Feature #12653 » 0001-Use-wide-WinAPI-for-rb_w32_getcwd.patch
| win32/win32.c | ||
|---|---|---|
| 
     rb_w32_getcwd(char *buffer, int size) 
   | 
||
| 
     { 
   | 
||
| 
         char *p = buffer; 
   | 
||
| 
         int len; 
   | 
||
| 
         WCHAR *wbuffer; 
   | 
||
| 
         int len, r; 
   | 
||
| 
         VALUE rp; 
   | 
||
| 
         len = GetCurrentDirectory(0, NULL); 
   | 
||
| 
         len = GetCurrentDirectoryW(0, NULL); 
   | 
||
| 
         if (!len) { 
   | 
||
| 
     	errno = map_errno(GetLastError()); 
   | 
||
| 
     	return NULL; 
   | 
||
| 
         } 
   | 
||
| 
         if (p) { 
   | 
||
| 
     	if (size < len) { 
   | 
||
| 
     	    errno = ERANGE; 
   | 
||
| 
     	    return NULL; 
   | 
||
| 
     	} 
   | 
||
| 
         if (buffer && size < len) { 
   | 
||
| 
             errno = ERANGE; 
   | 
||
| 
             return NULL; 
   | 
||
| 
         } 
   | 
||
| 
         else { 
   | 
||
| 
     	p = malloc(len); 
   | 
||
| 
     	size = len; 
   | 
||
| 
     	if (!p) { 
   | 
||
| 
     	    errno = ENOMEM; 
   | 
||
| 
     	    return NULL; 
   | 
||
| 
     	} 
   | 
||
| 
         wbuffer = malloc(len * sizeof(WCHAR)); 
   | 
||
| 
         if (!wbuffer) { 
   | 
||
| 
             errno = ENOMEM; 
   | 
||
| 
             return NULL; 
   | 
||
| 
         } 
   | 
||
| 
         if (!GetCurrentDirectory(size, p)) { 
   | 
||
| 
         if (!GetCurrentDirectoryW(len, wbuffer)) { 
   | 
||
| 
     	errno = map_errno(GetLastError()); 
   | 
||
| 
     	if (!buffer) 
   | 
||
| 
     	    free(p); 
   | 
||
| 
             free(wbuffer); 
   | 
||
| 
             return NULL; 
   | 
||
| 
         } 
   | 
||
| 
         if (!p) { 
   | 
||
| 
             size = WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, NULL, 0, NULL, NULL); 
   | 
||
| 
             p = malloc(size); 
   | 
||
| 
             if (!p) { 
   | 
||
| 
                 errno = ENOMEM; 
   | 
||
| 
                 return NULL; 
   | 
||
| 
             } 
   | 
||
| 
         } 
   | 
||
| 
         r = WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, p, size, NULL, NULL); 
   | 
||
| 
         free(wbuffer); 
   | 
||
| 
         if (r == 0) { 
   | 
||
| 
             DWORD lastError = GetLastError(); 
   | 
||
| 
             if (!buffer) { 
   | 
||
| 
                 free(p); 
   | 
||
| 
             } 
   | 
||
| 
             if (lastError == ERROR_INSUFFICIENT_BUFFER) { 
   | 
||
| 
                 errno = ERANGE; 
   | 
||
| 
                 return NULL; 
   | 
||
| 
             } 
   | 
||
| 
             errno = map_errno(lastError); 
   | 
||
| 
             return NULL; 
   | 
||
| 
         } 
   | 
||
| 
         translate_char(p, '\\', '/', filecp()); 
   | 
||
| 
         translate_char(p, '\\', '/', CP_UTF8); 
   | 
||
| 
         rp = rb_str_conv_enc_opts(rb_utf8_str_new_cstr(p), NULL, rb_filesystem_encoding(), ECONV_UNDEF_REPLACE, Qnil); 
   | 
||
| 
         if (!buffer) { 
   | 
||
| 
           free(p); 
   | 
||
| 
           p = strdup(RSTRING_PTR(rp)); 
   | 
||
| 
         } else { 
   | 
||
| 
           if (RSTRING_LEN(rp) >= size) { 
   | 
||
| 
             errno = ERANGE; 
   | 
||
| 
             return NULL; 
   | 
||
| 
           } 
   | 
||
| 
           strncpy(p, RSTRING_PTR(rp), size - 1); 
   | 
||
| 
           p[size - 1] = '\0'; 
   | 
||
| 
         } 
   | 
||
| 
         return p; 
   | 
||
| 
     } 
   | 
||