size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst, size_t dst_size) { size_t in_len; size_t out_len; if (!str) return 0; in_len = (len != 0) ? len : wcslen(str); out_len = dst ? (dst_size - 1) : wchar_to_utf8(str, in_len, NULL, 0, 0); if (dst) { if (!dst_size) return 0; if (out_len) out_len = wchar_to_utf8(str, in_len, dst, out_len + 1, 0); dst[out_len] = 0; } return out_len; }
void dstr_from_wcs(struct dstr *dst, const wchar_t *wstr) { size_t len = wchar_to_utf8(wstr, 0, NULL, 0, 0); if (len) { dstr_resize(dst, len); wchar_to_utf8(wstr, 0, dst->array, len+1, 0); } else { dstr_free(dst); } }
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst) { size_t in_len = (len != 0) ? len : wcslen(str); size_t out_len = dst ? len : wchar_to_utf8(str, in_len, NULL, 0, 0); if (out_len && dst) { wchar_to_utf8(str, in_len, dst, out_len+1, 0); dst[out_len] = 0; } return out_len; }
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char **pstr) { size_t in_len = (len != 0) ? len : wcslen(str); size_t out_len = wchar_to_utf8(str, in_len, NULL, 0, 0); char *dst = NULL; if (out_len) { dst = bmalloc(out_len+1); wchar_to_utf8(str, in_len, dst, out_len+1, 0); dst[out_len] = 0; } *pstr = dst; return out_len; }
void hpdf_doc::text_out_cjk(HPDF_REAL& f_xpos, HPDF_REAL& f_ypos, wstring out_string, HPDF_REAL& f_advance, HPDF_REAL f_width, HPDF_REAL f_gap, HPDF_REAL f_space) { char line[4]; memset(line, 0, 4); int n_TX = (et_cp.TX > 0) ? et_cp.TX : et_cp.T, n_TY = (et_cp.TY > 0) ? et_cp.TY : et_cp.T; HPDF_REAL font_height = MMTEXT2PTX((et_cp.Z * n_TY)); HPDF_REAL font_width = MMTEXT2PTX((et_cp.W * n_TX / 2) + (et_cp.X / 2)); HPDF_REAL ygap = MMTEXT2PTX(et_cp.L); HPDF_REAL xpos = f_xpos, ypos = f_ypos; int len = out_string.length(); if (et_cp.VorH == 'V') { xpos += (f_width + f_gap) * 2; ypos -= font_width; } for (int i = 0; i < len; i++) { wchar_t out_wchar = out_string[i]; size_t size = wchar_to_utf8(&out_wchar, 1, line, 4, NULL); if (size == 0) break; HPDF_Page_TextOut(h_current_page, xpos + f_advance, ypos - f_linespace, line); f_advance += (et_cp.VorH == 'V') ? (font_height) : (f_width + f_gap) * 2; //f_advance += (f_width + f_gap) * 2; } }
// eng: Finds the next ptc-file in emitters folder // rus: Поиск следующего ptc-файла в папке с эмиттерами const char* MP_Platform_WIN_POSIX::GetNextFile() { #ifdef _WINDOWS if (FindNextFileW(hFindFile,&fd)) { file=wchar_to_utf8(fd.cFileName); return file.c_str(); } FindClose(hFindFile); #else dirent* result=readdir(dir); while(result) { int len=strlen(result->d_name); if (len>4) { const char* ext=&(result->d_name[len-4]); if (strcmp(ext, ".ptc")==0) { return result->d_name; } } result=readdir(dir); } closedir(dir); dir=NULL; #endif return NULL; }
// eng: Finds the first ptc-file in emitters folder // rus: Поиск первого ptc-файла в папке с эмиттерами const char* MP_Platform_WIN_POSIX::GetFirstFile() { std::string ptc_path=GetPathToPTC(); #ifdef _WINDOWS ptc_path+="*.ptc"; const wchar_t* mask=utf8_to_wchar(ptc_path.c_str()); hFindFile=FindFirstFileW(mask,&fd); if (hFindFile!=INVALID_HANDLE_VALUE) { file=wchar_to_utf8(fd.cFileName); return file.c_str(); } FindClose(hFindFile); #else dir=opendir(ptc_path.c_str()); if (dir) return GetNextFile(); #endif return NULL; }
DWORD request_ui_get_keys_utf8(Remote *remote, Packet *request) { Packet *response = packet_create_response(request); DWORD result = ERROR_SUCCESS; char *utf8_keyscan_buf = NULL; if (tKeyScan) { utf8_keyscan_buf = wchar_to_utf8(g_keyscan_buf); packet_add_tlv_raw(response, TLV_TYPE_KEYS_DUMP, (LPVOID)utf8_keyscan_buf, (DWORD)strlen(utf8_keyscan_buf) + 1); memset(g_keyscan_buf, 0, KEYBUFSIZE); // reset index and zero active window string so the current one // is logged again g_idx = 0; RtlZeroMemory(g_prev_active_image, MAX_PATH); } else { result = 1; } // Transmit the response packet_transmit_response(result, remote, response); free(utf8_keyscan_buf); return ERROR_SUCCESS; }
std::string wchar_to_utf8_cstr(const wchar_t *str) { char *utf=wchar_to_utf8(str); std::string res(utf); free(utf); return res; }
/* The okay button has been clicked or the enter enter key in the text field. */ static void ok_button_clicked (HWND dlg, pinentry_t pe) { char *s_utf8; wchar_t *w_buffer; size_t w_buffer_size = 255; unsigned int nchar; pe->locale_err = 1; w_buffer = secmem_malloc ((w_buffer_size + 1) * sizeof *w_buffer); if (!w_buffer) return; nchar = GetDlgItemTextW (dlg, IDC_PINENT_TEXT, w_buffer, w_buffer_size); s_utf8 = wchar_to_utf8 (w_buffer, nchar, 1); secmem_free (w_buffer); if (s_utf8) { passphrase_ok = 1; pinentry_setbufferlen (pe, strlen (s_utf8) + 1); if (pe->pin) strcpy (pe->pin, s_utf8); secmem_free (s_utf8); pe->locale_err = 0; pe->result = pe->pin? strlen (pe->pin) : 0; } }
BOOL XFile::WriteAsUTF8(CTSTR lpBuffer, DWORD dwElements) { DWORD retVal = 0; if(!lpBuffer) return false; if (!hFile) return false; if (!lpBuffer[0]) return true; if(!dwElements) dwElements = slen(lpBuffer); #ifdef UNICODE DWORD dwBytes = (DWORD)wchar_to_utf8_len(lpBuffer, dwElements, 0); LPSTR lpDest = (LPSTR)Allocate(dwBytes+1); if (wchar_to_utf8(lpBuffer, dwElements, lpDest, dwBytes, 0)) retVal = (Write(lpDest, dwBytes) == dwBytes); else Log(TEXT("XFile::WriteAsUTF8: wchar_to_utf8 failed: %d"), GetLastError()); Free(lpDest); #else DWORD retVal = (Write(lpBuffer, dwElements) == dwBytes); #endif return retVal; }
/* * Converts a name + ext UTF-8 pair to a valid MS filename. * Returned string is allocated and needs to be freed manually */ char* to_valid_filename(char* name, char* ext) { size_t i, j, k; BOOL found; char* ret; wchar_t unauthorized[] = L"\x0001\x0002\x0003\x0004\x0005\x0006\x0007\x0008\x000a" L"\x000b\x000c\x000d\x000e\x000f\x0010\x0011\x0012\x0013\x0014\x0015\x0016\x0017" L"\x0018\x0019\x001a\x001b\x001c\x001d\x001e\x001f\x007f\"*/:<>?\\|,"; wchar_t to_underscore[] = L" \t"; wchar_t *wname, *wext, *wret; if ((name == NULL) || (ext == NULL)) { return NULL; } if (strlen(name) > WDI_MAX_STRLEN) return NULL; // Convert to UTF-16 wname = utf8_to_wchar(name); wext = utf8_to_wchar(ext); if ((wname == NULL) || (wext == NULL)) { safe_free(wname); safe_free(wext); return NULL; } // The returned UTF-8 string will never be larger than the sum of its parts wret = (wchar_t*)calloc(2*(wcslen(wname) + wcslen(wext) + 2), 1); if (wret == NULL) { safe_free(wname); safe_free(wext); return NULL; } wcscpy(wret, wname); safe_free(wname); wcscat(wret, wext); safe_free(wext); for (i=0, k=0; i<wcslen(wret); i++) { found = FALSE; for (j=0; j<wcslen(unauthorized); j++) { if (wret[i] == unauthorized[j]) { found = TRUE; break; } } if (found) continue; found = FALSE; for (j=0; j<wcslen(to_underscore); j++) { if (wret[i] == to_underscore[j]) { wret[k++] = '_'; found = TRUE; break; } } if (found) continue; wret[k++] = wret[i]; } wret[k] = 0; ret = wchar_to_utf8(wret); safe_free(wret); return ret; }
std::string hresult_error_string(HRESULT error) { LocalPtr<WCHAR> message; DWORD result = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&message.ptr, 0, NULL); if (!result) return "Unknown error"; return wchar_to_utf8(message.ptr); }
DWORD GetTempPathA (DWORD nBufferLength, LPSTR lpBuffer) { wchar_t dummy[1]; DWORD len; len = GetTempPathW (0, dummy); if (len == 0) return 0; assert (len <= MAX_PATH); /* Better be safe than sorry. MSDN doesn't say if len is with or without terminating 0. */ len++; { wchar_t *buffer_w; DWORD len_w; char *buffer_c; DWORD len_c; buffer_w = malloc (sizeof (wchar_t) * len); if (! buffer_w) return 0; len_w = GetTempPathW (len, buffer_w); /* Give up if we still can't get at it. */ if (len_w == 0 || len_w >= len) { free (buffer_w); return 0; } /* Better be really safe. */ buffer_w[len_w] = '\0'; buffer_c = wchar_to_utf8 (buffer_w); free (buffer_w); if (! buffer_c) return 0; /* strlen is correct (not _mbstrlen), because we want storage and not string length. */ len_c = strlen (buffer_c) + 1; if (len_c > nBufferLength) return len_c; strcpy (lpBuffer, buffer_c); free (buffer_c); return len_c - 1; } }
size_t os_wcs_to_utf8(const wchar_t *str, size_t len, char *dst, size_t dst_size) { size_t in_len = (len != 0) ? len : wcslen(str); size_t out_len = dst ? len : wchar_to_utf8(str, in_len, NULL, 0, 0); if (out_len && dst) { if (!dst_size) return 0; if (out_len) { if ((out_len + 1) > dst_size) out_len = dst_size - 1; wchar_to_utf8(str, in_len, dst, out_len + 1, 0); } dst[out_len] = 0; } return out_len; }
BOOL XFile::WriteStr(CWSTR lpBuffer) { assert(lpBuffer); if(!hFile) return XFILE_ERROR; DWORD dwElements = (DWORD)wcslen(lpBuffer); char lpDest[4096]; DWORD dwBytes = (DWORD)wchar_to_utf8(lpBuffer, dwElements, lpDest, 4095, 0); DWORD retVal = (Write(lpDest, dwBytes) == dwBytes); return retVal; }
/* * Parse a buffer (ANSI or UTF-8) and return the data for the 'n'th occurrence of 'token' * The returned string is UTF-8 and MUST be freed by the caller */ char* get_token_data_buffer(const char* token, unsigned int n, const char* buffer, size_t buffer_size) { unsigned int j, curly_count; wchar_t *wtoken = NULL, *wdata = NULL, *wbuffer = NULL, *wline = NULL; size_t i; BOOL done = FALSE; char* ret = NULL; // We're handling remote data => better safe than sorry if ((token == NULL) || (buffer == NULL) || (buffer_size <= 4) || (buffer_size > 65536)) goto out; // Ensure that our buffer is NUL terminated if (buffer[buffer_size-1] != 0) goto out; wbuffer = utf8_to_wchar(buffer); wtoken = utf8_to_wchar(token); if ((wbuffer == NULL) || (wtoken == NULL)) goto out; // Process individual lines (or multiple lines when between {}, for RTF) for (i=0,j=0,done=FALSE; (j!=n)&&(!done); ) { wline = &wbuffer[i]; for(curly_count=0;((curly_count>0)||((wbuffer[i]!=L'\n')&&(wbuffer[i]!=L'\r')))&&(wbuffer[i]!=0);i++) { if (wbuffer[i] == L'{') curly_count++; if (wbuffer[i] == L'}') curly_count--; } if (wbuffer[i]==0) { done = TRUE; } else { wbuffer[i++] = 0; } wdata = get_token_data_line(wtoken, wline); if (wdata != NULL) { j++; } } out: if (wdata != NULL) ret = wchar_to_utf8(wdata); safe_free(wbuffer); safe_free(wtoken); return ret; }
DWORD XFile::WriteStr(WSTR lpBuffer) { traceInFast(XFile::WriteStr); assert(lpBuffer); if(!hFile) return XFILE_ERROR; DWORD dwElements = slen(lpBuffer); char lpDest[4096]; DWORD dwBytes = (DWORD)wchar_to_utf8(lpBuffer, dwElements, lpDest, 4095, 0); DWORD retVal = Write(lpDest, dwBytes); return retVal; traceOutFast; }
// eng: Returns path to folder which could be used by wrapper to store temporary files. If NULL is returned the temporary files are saved in RAM. // rus: Возвращает путь к временной папке. Если вернуть NULL, то временные файлы будут сохраняться в ОЗУ. const char* MP_Platform_WIN_POSIX::GetPathToTemp() { #ifdef _WINDOWS if (temp_path.empty()) { wchar_t path[MAX_PATH]; GetTempPathW(MAX_PATH, path); temp_path=wchar_to_utf8(path); } return temp_path.c_str(); #else return NULL; #endif }
int fs_getwd(char **dir) { int rc = ERROR_SUCCESS; wchar_t dir_w[FS_MAX_PATH]; if (GetCurrentDirectoryW(FS_MAX_PATH, dir_w) == 0) { rc = GetLastError(); goto out; } *dir = wchar_to_utf8(dir_w); if (*dir == NULL) { rc = GetLastError(); } out: return rc; }
void tagUpdateCachedEntryWithRequest(sqlite3_stmt * request, TAG_VERBOSE * newData, uint nbData) { for(uint i = 0; i < nbData; i++) { //We get a UTF8 version of the name size_t length = wstrlen((charType *) newData[i].name); char utf8[4 * length + 1]; length = wchar_to_utf8((charType *) newData[i].name, length, utf8, 4 * length + 1, 0); //We submit the data to the request, then run and clean it sqlite3_bind_int(request, 1, (int32_t) newData[i].ID); sqlite3_bind_text(request, 2, utf8, (int32_t) length, SQLITE_STATIC); sqlite3_step(request); sqlite3_reset(request); } destroyRequest(request); }
char * fs_expand_path(const char *regular) { wchar_t expanded_path[FS_MAX_PATH]; wchar_t *regular_w; regular_w = utf8_to_wchar(regular); if (regular_w == NULL) { return NULL; } if (ExpandEnvironmentStringsW(regular_w, expanded_path, FS_MAX_PATH) == 0) { free(regular_w); return NULL; } free(regular_w); return wchar_to_utf8(expanded_path); }
/* * Parse a file (ANSI or UTF-8 or UTF-16) and return the data for the first occurrence of 'token' * The returned string is UTF-8 and MUST be freed by the caller */ char* get_token_data_file(const char* token, const char* filename) { wchar_t *wtoken = NULL, *wdata= NULL, *wfilename = NULL; wchar_t buf[1024]; FILE* fd = NULL; char *ret = NULL; if ((filename == NULL) || (token == NULL)) return NULL; if ((filename[0] == 0) || (token[0] == 0)) return NULL; wfilename = utf8_to_wchar(filename); if (wfilename == NULL) { uprintf(conversion_error, filename); goto out; } wtoken = utf8_to_wchar(token); if (wfilename == NULL) { uprintf(conversion_error, token); goto out; } fd = _wfopen(wfilename, L"r, ccs=UNICODE"); if (fd == NULL) goto out; // Process individual lines. NUL is always appended. // Ideally, we'd check that our buffer fits the line while (fgetws(buf, ARRAYSIZE(buf), fd) != NULL) { wdata = get_token_data_line(wtoken, buf); if (wdata != NULL) { ret = wchar_to_utf8(wdata); break; } } out: if (fd != NULL) fclose(fd); safe_free(wfilename); safe_free(wtoken); return ret; }
static void test_wchar2utf8(const wchar_t *src, size_t slen, const char *dst, size_t dlen, int flags, size_t res, const char *descr) { size_t size; char *mem; mem = NULL; if (dst != NULL) { mem = (char *)malloc(dlen); if (mem == NULL) { fprintf(stderr, "w2u: %s: MALLOC FAILED\n", descr); return; } } do { size = wchar_to_utf8(src, slen, mem, dlen, flags); if (res != size) { retval = 1; fprintf(stderr, "w2u: %s: FAILED (rv: %u, must be %u)\n", descr, size, res); break; } if (mem == NULL) break; /* OK */ if (memcmp(mem, dst, size) != 0) { retval = 1; fprintf(stderr, "w2u: %s: BROKEN\n", descr); break; } } while (0); if (mem != NULL); free(mem); }
DWORD XFile::WriteAsUTF8(CTSTR lpBuffer, DWORD dwElements) { traceInFast(XFile::WriteAsUTF8); if(!lpBuffer) return 0; if(!hFile) return XFILE_ERROR; if(!dwElements) dwElements = slen(lpBuffer); DWORD dwBytes = (DWORD)wchar_to_utf8_len(lpBuffer, dwElements, 0); LPSTR lpDest = (LPSTR)Allocate(dwBytes+1); wchar_to_utf8(lpBuffer, dwElements, lpDest, dwBytes, 0); DWORD retVal = Write(lpDest, dwBytes); Free(lpDest); return retVal; traceOutFast; }
// eng: Returns path to folder with emitters // rus: Возвращает путь к папке с ptc-файлами const char* MP_Platform_WIN_POSIX::GetPathToPTC() { if (ptc_path.empty()) { #ifdef _WINDOWS wchar_t path[MAX_PATH]; #if 0//ndef TEST GetModuleFileNameW(NULL, path, MAX_PATH); int len=wcslen(path); for (int i=len-1;i>=0;i--) { if (path[i]=='\\') { path[i]=0; break; } } #else GetCurrentDirectoryW(MAX_PATH, path); #endif ptc_path=wchar_to_utf8(path); ptc_path+='\\'; #else char path[MAX_PATH]; getcwd(path, MAX_PATH); ptc_path=path; ptc_path+='/'; #endif } return ptc_path.c_str(); }
BOOL SHGetSpecialFolderPathA (HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate) { wchar_t path[MAX_PATH]; char *path_c; BOOL result; path[0] = (wchar_t) 0; result = SHGetSpecialFolderPath (hwndOwner, path, nFolder, fCreate); /* Note: May return false even if succeeds. */ path[MAX_PATH - 1] = (wchar_t) 0; path_c = wchar_to_utf8 (path); if (! path_c) return 0; strncpy (lpszPath, path_c, MAX_PATH); free (path_c); lpszPath[MAX_PATH - 1] = '\0'; return result; }
String::String(CWSTR str) { #ifdef UNICODE if(!str) { curLength = 0; lpString = NULL; return; } curLength = slen(str); if(curLength) { lpString = (TSTR)Allocate((curLength+1)*sizeof(TCHAR)); scpy(lpString, str); } else lpString = NULL; #else if(!str) { curLength = 0; lpString = NULL; return; } size_t wideLen = wcslen(str); curLength = (UINT)wchar_to_utf8_len(str, wideLen, 0); if(curLength) { lpString = (TSTR)Allocate(curLength+1); wchar_to_utf8(str, wideLen+1, lpString, curLength+1, 0); } else lpString = NULL; #endif }
json_t* json_string_wchar(CTSTR str) { if(!str) { return NULL; } size_t wcharLen = slen(str); size_t curLength = (UINT)wchar_to_utf8_len(str, wcharLen, 0); if(curLength) { char *out = (char *) malloc((curLength+1)); wchar_to_utf8(str,wcharLen, out, curLength + 1, 0); out[curLength] = 0; json_t* ret = json_string(out); free(out); return ret; } else { return NULL; } }
// TODO: allow commandline options (v2) // TODO: remove existing infs for similar devices (v2) int __cdecl main(int argc_ansi, char** argv_ansi) { DWORD r; BOOL b; int i, ret, argc = argc_ansi, si=0; char** argv = argv_ansi; wchar_t **wenv, **wargv; char* hardware_id = NULL; char* device_id = NULL; char* user_sid = NULL; char* inf_name = NULL; char path[MAX_PATH_LENGTH]; char destname[MAX_PATH_LENGTH]; uintptr_t syslog_reader_thid = -1L; // Connect to the messaging pipe pipe_handle = CreateFileA(INSTALLER_PIPE_NAME, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, NULL); if (pipe_handle == INVALID_HANDLE_VALUE) { // If we can't connect to the pipe, someone is probably trying to run us standalone printf("This application can not be run from the command line.\n"); printf("Please use your initial installer application if you want to install the driver.\n"); return WDI_ERROR_NOT_SUPPORTED; } if (init_dlls()) { plog("could not init DLLs"); ret = WDI_ERROR_RESOURCE; goto out; } // Initialize COM for Restore Point disabling CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // libwdi provides the arguments as UTF-16 => read them and convert to UTF-8 if (__wgetmainargs != NULL) { __wgetmainargs(&argc, &wargv, &wenv, 1, &si); argv = calloc(argc, sizeof(char*)); for (i=0; i<argc; i++) { argv[i] = wchar_to_utf8(wargv[i]); } } else { plog("unable to access UTF-16 args - trying ANSI"); } if (argc < 2) { printf("usage: %s <inf_name>\n", argv[0]); plog("missing inf_name parameter"); } inf_name = argv[1]; plog("got parameter %s", argv[1]); r = GetFullPathNameU(".", MAX_PATH_LENGTH, path, NULL); if ((r == 0) || (r > MAX_PATH_LENGTH)) { plog("could not retrieve absolute path of working directory"); ret = WDI_ERROR_ACCESS; goto out; } safe_strcat(path, MAX_PATH_LENGTH, "\\"); safe_strcat(path, MAX_PATH_LENGTH, inf_name); device_id = req_id(IC_GET_DEVICE_ID); hardware_id = req_id(IC_GET_HARDWARE_ID); // Will be used if we ever need to create a file, as the original user, from this app user_sid = req_id(IC_GET_USER_SID); ConvertStringSidToSidA(user_sid, &user_psid); // Setup the syslog reader thread syslog_ready_event = CreateEvent(NULL, TRUE, FALSE, NULL); syslog_terminate_event = CreateEvent(NULL, TRUE, FALSE, NULL); syslog_reader_thid = _beginthread(syslog_reader_thread, 0, 0); if ( (syslog_reader_thid == -1L) || (WaitForSingleObject(syslog_ready_event, 2000) != WAIT_OBJECT_0) ) { plog("Unable to create syslog reader thread"); SetEvent(syslog_terminate_event); // NB: if you try to close the syslog reader thread handle, you get a // "more recent driver was found" error from UpdateForPnP. Weird... } // Disable the creation of a restore point disable_system_restore(true); // Find if the device is plugged in send_status(IC_SET_TIMEOUT_INFINITE); if (hardware_id != NULL) { plog("Installing driver for %s - please wait...", hardware_id); b = UpdateDriverForPlugAndPlayDevicesU(NULL, hardware_id, path, INSTALLFLAG_FORCE, NULL); send_status(IC_SET_TIMEOUT_DEFAULT); if (b == true) { // Success plog("driver update completed"); enumerate_device(device_id); ret = WDI_SUCCESS; goto out; } ret = process_error(GetLastError(), path); if (ret != WDI_SUCCESS) { goto out; } } // TODO: try URL for OEMSourceMediaLocation (v2) plog("Copying inf file (for the next time device is plugged) - please wait..."); send_status(IC_SET_TIMEOUT_INFINITE); b = SetupCopyOEMInfU(path, NULL, SPOST_PATH, 0, destname, MAX_PATH_LENGTH, NULL, NULL); send_status(IC_SET_TIMEOUT_DEFAULT); if (b) { plog("copied inf to %s", destname); ret = WDI_SUCCESS; enumerate_device(device_id); goto out; } ret = process_error(GetLastError(), path); if (ret != WDI_SUCCESS) { goto out; } // If needed, flag removed devices for reinstallation. see: // http://msdn.microsoft.com/en-us/library/aa906206.aspx check_removed(hardware_id); out: // Report any error status code and wait for target app to read it send_status(IC_INSTALLER_COMPLETED); pstat(ret); // Restore the system restore point creation original settings disable_system_restore(false); // TODO: have libwi send an ACK? Sleep(1000); SetEvent(syslog_terminate_event); if (argv != argv_ansi) { for (i=0; i<argc; i++) { safe_free(argv[i]); } safe_free(argv); } CloseHandle(syslog_ready_event); CloseHandle(syslog_terminate_event); CloseHandle((HANDLE)syslog_reader_thid); CloseHandle(pipe_handle); return ret; }