/* Fill in service table entry for a specified service */ static BOOL AddServiceElem(LPWSTR service_name, SERVICE_TABLE_ENTRYW *service_table_entry) { LONG ret; HKEY service_hkey = NULL; LPWSTR service_param_key = NULL; LPWSTR dll_name_short = NULL; LPWSTR dll_name_long = NULL; LPSTR dll_service_main = NULL; HMODULE library = NULL; LPSERVICE_MAIN_FUNCTIONW service_main_func = NULL; BOOL success = FALSE; DWORD reg_size; DWORD size; WINE_TRACE("Adding element for %s\n", wine_dbgstr_w(service_name)); /* Construct registry path to the service's parameters key */ size = (lstrlenW(service_reg_path) + lstrlenW(reg_separator) + lstrlenW(service_name) + lstrlenW(reg_separator) + lstrlenW(parameters) + 1); service_param_key = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); lstrcpyW(service_param_key, service_reg_path); lstrcatW(service_param_key, reg_separator); lstrcatW(service_param_key, service_name); lstrcatW(service_param_key, reg_separator); lstrcatW(service_param_key, parameters); service_param_key[size - 1] = '\0'; ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, service_param_key, 0, KEY_READ, &service_hkey); if (ret != ERROR_SUCCESS) { WINE_ERR("cannot open key %s, err=%d\n", wine_dbgstr_w(service_param_key), ret); goto cleanup; } /* Find DLL associate with service from key */ dll_name_short = GetRegValue(service_hkey, service_dll); if (!dll_name_short) { WINE_ERR("cannot find registry value %s for service %s\n", wine_dbgstr_w(service_dll), wine_dbgstr_w(service_name)); RegCloseKey(service_hkey); goto cleanup; } /* Expand environment variables in ServiceDll name*/ dll_name_long = ExpandEnv(dll_name_short); if (!dll_name_long) { WINE_ERR("failed to expand string %s\n", wine_dbgstr_w(dll_name_short)); RegCloseKey(service_hkey); goto cleanup; } /* Look for alternate to default ServiceMain entry point */ ret = RegQueryValueExA(service_hkey, service_main, NULL, NULL, NULL, ®_size); if (ret == ERROR_SUCCESS) { /* Add space for potentially missing NULL terminator, allocate, and * fill with the registry value */ size = reg_size + 1; dll_service_main = HeapAlloc(GetProcessHeap(), 0, size); ret = RegQueryValueExA(service_hkey, service_main, NULL, NULL, (LPBYTE)dll_service_main, ®_size); if (ret != ERROR_SUCCESS) { RegCloseKey(service_hkey); goto cleanup; } dll_service_main[size - 1] = '\0'; } RegCloseKey(service_hkey); /* Load the DLL and obtain a pointer to ServiceMain entry point */ library = LoadLibraryW(dll_name_long); if (!library) { WINE_ERR("failed to load library %s, err=%u\n", wine_dbgstr_w(dll_name_long), GetLastError()); goto cleanup; } if (dll_service_main) { service_main_func = (LPSERVICE_MAIN_FUNCTIONW) GetProcAddress(library, dll_service_main); } else { service_main_func = (LPSERVICE_MAIN_FUNCTIONW) GetProcAddress(library, service_main); } if (!service_main_func) { WINE_ERR("cannot locate ServiceMain procedure in DLL for %s\n", wine_dbgstr_w(service_name)); FreeLibrary(library); goto cleanup; } if (GetProcAddress(library, "SvchostPushServiceGlobals")) { WINE_FIXME("library %s expects undocumented SvchostPushServiceGlobals function to be called\n", wine_dbgstr_w(dll_name_long)); } /* Fill in the service table entry */ service_table_entry->lpServiceName = service_name; service_table_entry->lpServiceProc = service_main_func; success = TRUE; cleanup: HeapFree(GetProcessHeap(), 0, service_param_key); HeapFree(GetProcessHeap(), 0, dll_name_short); HeapFree(GetProcessHeap(), 0, dll_name_long); HeapFree(GetProcessHeap(), 0, dll_service_main); return success; }
/****************************************************************** * types_extract_as_longlong * * Given a lvalue, try to get an integral (or pointer/address) value * out of it */ LONGLONG types_extract_as_longlong(const struct dbg_lvalue* lvalue, unsigned* psize, BOOL *issigned) { LONGLONG rtn; DWORD tag, bt; DWORD64 size; struct dbg_type type = lvalue->type; BOOL s = FALSE; if (!types_get_real_type(&type, &tag)) RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL); if (type.id == dbg_itype_segptr) { return (LONG_PTR)memory_to_linear_addr(&lvalue->addr); } if (psize) *psize = 0; if (issigned) *issigned = FALSE; switch (tag) { case SymTagBaseType: if (!types_get_info(&type, TI_GET_LENGTH, &size) || !types_get_info(&type, TI_GET_BASETYPE, &bt)) { WINE_ERR("Couldn't get information\n"); RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); } if (size > sizeof(rtn)) { WINE_ERR("Size too large (%s)\n", wine_dbgstr_longlong(size)); RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL); } switch (bt) { case btChar: case btInt: if (!be_cpu->fetch_integer(lvalue, (unsigned)size, s = TRUE, &rtn)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break; case btUInt: if (!be_cpu->fetch_integer(lvalue, (unsigned)size, s = FALSE, &rtn)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break; case btFloat: RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL); } if (psize) *psize = (unsigned)size; if (issigned) *issigned = s; break; case SymTagPointerType: if (!be_cpu->fetch_integer(lvalue, sizeof(void*), s = FALSE, &rtn)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break; case SymTagArrayType: case SymTagUDT: if (!be_cpu->fetch_integer(lvalue, sizeof(unsigned), s = FALSE, &rtn)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break; case SymTagEnum: /* FIXME: we don't handle enum size */ if (!be_cpu->fetch_integer(lvalue, sizeof(unsigned), s = FALSE, &rtn)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break; case SymTagFunctionType: rtn = (ULONG_PTR)memory_to_linear_addr(&lvalue->addr); break; default: WINE_FIXME("Unsupported tag %u\n", tag); RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL); break; } return rtn; }
static DWORD WINAPI NPMainWorkThread(LPVOID ignored) { BOOL connected; HANDLE hthread, master_mutex = RPCSS_GetMasterMutex(); DWORD threadid, wait_result; WINE_TRACE("\n"); while (server_live) { connected = ConnectNamedPipe(np_server_end, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (connected) { /* is "work" the act of connecting pipes, or the act of serving requests successfully? for now I will make it the former. */ if (!SetEvent(np_server_work_event)) WINE_WARN("failed to signal np_server_work_event.\n"); /* Create a thread for this client. */ InterlockedIncrement(&srv_thread_count); hthread = CreateThread( NULL, /* no security attribute */ 0, /* default stack size */ HandlerThread, (LPVOID) np_server_end, /* thread parameter */ 0, /* not suspended */ &threadid /* returns thread ID (not used) */ ); if (hthread) { WINE_TRACE("Spawned handler thread: %p\n", hthread); CloseHandle(hthread); /* for safety's sake, hold the mutex while we switch the pipe */ wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT); switch (wait_result) { case WAIT_ABANDONED: /* ? */ case WAIT_OBJECT_0: /* we have ownership */ break; case WAIT_FAILED: case WAIT_TIMEOUT: default: /* huh? */ wait_result = WAIT_FAILED; } if (wait_result == WAIT_FAILED) { WINE_ERR("Couldn't enter master mutex. Expect problems.\n"); } else { /* now create a new named pipe instance to listen on */ np_server_end = CreateNamedPipe( NAME_RPCSS_NAMED_PIPE, /* pipe name */ PIPE_ACCESS_DUPLEX, /* pipe open mode */ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, /* pipe-specific modes */ PIPE_UNLIMITED_INSTANCES, /* maximum instances */ sizeof(RPCSS_NP_REPLY), /* output buffer size */ sizeof(RPCSS_NP_MESSAGE), /* input buffer size */ 2000, /* time-out interval */ NULL /* SD */ ); if (np_server_end == INVALID_HANDLE_VALUE) { WINE_ERR("Failed to recreate named pipe!\n"); /* not sure what to do? */ assert(FALSE); } if (!ReleaseMutex(master_mutex)) WINE_ERR("Uh oh. Couldn't leave master mutex. Expect deadlock.\n"); } } else { WINE_ERR("Failed to spawn handler thread!\n"); DisconnectNamedPipe(np_server_end); InterlockedDecrement(&srv_thread_count); } } } WINE_TRACE("Server thread shutdown.\n"); return 0; }
/* main desktop management function */ void manage_desktop( WCHAR *arg ) { static const WCHAR messageW[] = {'M','e','s','s','a','g','e',0}; HDESK desktop = 0; GUID guid; MSG msg; HWND hwnd; HMODULE graphics_driver; unsigned int width, height; WCHAR *cmdline = NULL, *driver = NULL; WCHAR *p = arg; const WCHAR *name = NULL; BOOL enable_shell = FALSE; /* get the rest of the command line (if any) */ while (*p && !isspace(*p)) p++; if (*p) { *p++ = 0; while (*p && isspace(*p)) p++; if (*p) cmdline = p; } /* parse the desktop option */ /* the option is of the form /desktop=name[,widthxheight[,driver]] */ if (*arg == '=' || *arg == ',') { arg++; name = arg; if ((p = strchrW( arg, ',' ))) { *p++ = 0; if ((driver = strchrW( p, ',' ))) *driver++ = 0; } if (!p || !parse_size( p, &width, &height )) get_default_desktop_size( name, &width, &height ); } else if ((name = get_default_desktop_name())) { if (!get_default_desktop_size( name, &width, &height )) width = height = 0; } if (name) enable_shell = get_default_enable_shell( name ); if (name && width && height) { if (!(desktop = CreateDesktopW( name, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ))) { WINE_ERR( "failed to create desktop %s error %d\n", wine_dbgstr_w(name), GetLastError() ); ExitProcess( 1 ); } SetThreadDesktop( desktop ); } UuidCreate( &guid ); TRACE( "display guid %s\n", debugstr_guid(&guid) ); graphics_driver = load_graphics_driver( driver, &guid ); /* create the desktop window */ hwnd = CreateWindowExW( 0, DESKTOP_CLASS_ATOM, NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, &guid ); if (hwnd) { /* create the HWND_MESSAGE parent */ CreateWindowExW( 0, messageW, NULL, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, 100, 100, 0, 0, 0, NULL ); using_root = !desktop || !create_desktop( graphics_driver, name, width, height ); SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)desktop_wnd_proc ); SendMessageW( hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIconW( 0, MAKEINTRESOURCEW(OIC_WINLOGO))); if (name) set_desktop_window_title( hwnd, name ); SetWindowPos( hwnd, 0, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN), GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), SWP_SHOWWINDOW ); SystemParametersInfoW( SPI_SETDESKWALLPAPER, 0, NULL, FALSE ); ClipCursor( NULL ); initialize_display_settings(); initialize_appbar(); if (graphics_driver) { HMODULE shell32; void (WINAPI *pShellDDEInit)( BOOL ); if (using_root) enable_shell = FALSE; initialize_systray( graphics_driver, using_root, enable_shell ); if (!using_root) initialize_launchers( hwnd ); if ((shell32 = LoadLibraryA( "shell32.dll" )) && (pShellDDEInit = (void *)GetProcAddress( shell32, (LPCSTR)188))) { pShellDDEInit( TRUE ); } } } /* if we have a command line, execute it */ if (cmdline) { STARTUPINFOW si; PROCESS_INFORMATION pi; memset( &si, 0, sizeof(si) ); si.cb = sizeof(si); WINE_TRACE( "starting %s\n", wine_dbgstr_w(cmdline) ); if (CreateProcessW( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) { CloseHandle( pi.hThread ); CloseHandle( pi.hProcess ); } } /* run the desktop message loop */ if (hwnd) { WINE_TRACE( "desktop message loop starting on hwnd %p\n", hwnd ); while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg ); WINE_TRACE( "desktop message loop exiting for hwnd %p\n", hwnd ); } ExitProcess( 0 ); }
static void extract(LPCWSTR cabfile, LPWSTR destdir) { if (!SetupIterateCabinetW(cabfile, 0, ExtCabCallback, destdir)) WINE_ERR("Could not extract cab file %s\n", wine_dbgstr_w(cabfile)); }
DWORD service_start(struct service_entry *service, DWORD service_argc, LPCWSTR *service_argv) { DWORD err; LPWSTR name; HANDLE process_handle = NULL; err = scmdatabase_lock_startup(service->db); if (err != ERROR_SUCCESS) return err; if (service->control_pipe != INVALID_HANDLE_VALUE) { scmdatabase_unlock_startup(service->db); return ERROR_SERVICE_ALREADY_RUNNING; } service->control_mutex = CreateMutexW(NULL, TRUE, NULL); if (!service->status_changed_event) service->status_changed_event = CreateEventW(NULL, FALSE, FALSE, NULL); if (!service->overlapped_event) service->overlapped_event = CreateEventW(NULL, TRUE, FALSE, NULL); name = service_get_pipe_name(); service->control_pipe = CreateNamedPipeW(name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE|PIPE_WAIT, 1, 256, 256, 10000, NULL ); HeapFree(GetProcessHeap(), 0, name); if (service->control_pipe==INVALID_HANDLE_VALUE) { WINE_ERR("failed to create pipe for %s, error = %d\n", wine_dbgstr_w(service->name), GetLastError()); err = GetLastError(); } else { err = service_start_process(service, &process_handle); if (err == ERROR_SUCCESS) { if (!service_send_start_message(service, process_handle, service_argv, service_argc)) err = ERROR_SERVICE_REQUEST_TIMEOUT; } if (err == ERROR_SUCCESS) err = service_wait_for_startup(service, process_handle); } if (err == ERROR_SUCCESS) ReleaseMutex(service->control_mutex); else { CloseHandle(service->overlapped_event); service->overlapped_event = NULL; CloseHandle(service->status_changed_event); service->status_changed_event = NULL; CloseHandle(service->control_mutex); service->control_mutex = NULL; if (service->control_pipe != INVALID_HANDLE_VALUE) CloseHandle(service->control_pipe); service->control_pipe = INVALID_HANDLE_VALUE; service->status.dwProcessId = 0; service_lock_exclusive(service); service->status.dwCurrentState = SERVICE_STOPPED; service_unlock(service); } scmdatabase_unlock_startup(service->db); WINE_TRACE("returning %d\n", err); return err; }
static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int level) { WCHAR string[1024], datestring[32], timestring[32]; WCHAR real_path[MAX_PATH]; WIN32_FIND_DATAW *fd; FILETIME ft; SYSTEMTIME st; HANDLE hff; int dir_count, file_count, entry_count, i, widest, cur_width, tmp_width; int numCols, numRows; int rows, cols; ULARGE_INTEGER byte_count, file_size; DIRECTORY_STACK *parms; int concurrentDirs = 0; BOOL done_header = FALSE; static const WCHAR fmtDir[] = {'%','1','0','s',' ',' ','%','8','s',' ',' ', '<','D','I','R','>',' ',' ',' ',' ',' ',' ',' ',' ',' ','\0'}; static const WCHAR fmtFile[] = {'%','1','0','s',' ',' ','%','8','s',' ',' ', ' ',' ','%','1','0','s',' ',' ','\0'}; static const WCHAR fmt2[] = {'%','-','1','3','s','\0'}; static const WCHAR fmt3[] = {'%','-','2','3','s','\0'}; static const WCHAR fmt4[] = {'%','s','\0'}; static const WCHAR fmt5[] = {'%','s','%','s','\0'}; dir_count = 0; file_count = 0; entry_count = 0; byte_count.QuadPart = 0; widest = 0; cur_width = 0; /* Loop merging all the files from consecutive parms which relate to the same directory. Note issuing a directory header with no contents mirrors what windows does */ parms = inputparms; fd = HeapAlloc(GetProcessHeap(),0,sizeof(WIN32_FIND_DATAW)); while (parms && strcmpW(inputparms->dirName, parms->dirName) == 0) { concurrentDirs++; /* Work out the full path + filename */ strcpyW(real_path, parms->dirName); strcatW(real_path, parms->fileName); /* Load all files into an in memory structure */ WINE_TRACE("Looking for matches to '%s'\n", wine_dbgstr_w(real_path)); hff = FindFirstFileW(real_path, (fd+entry_count)); if (hff != INVALID_HANDLE_VALUE) { do { /* Skip any which are filtered out by attribute */ if (((fd+entry_count)->dwFileAttributes & attrsbits) != showattrs) continue; entry_count++; /* Keep running track of longest filename for wide output */ if (wide || orderByCol) { int tmpLen = strlenW((fd+(entry_count-1))->cFileName) + 3; if ((fd+(entry_count-1))->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) tmpLen = tmpLen + 2; if (tmpLen > widest) widest = tmpLen; } fd = HeapReAlloc(GetProcessHeap(),0,fd,(entry_count+1)*sizeof(WIN32_FIND_DATAW)); if (fd == NULL) { FindClose (hff); WINE_ERR("Out of memory\n"); errorlevel = 1; return parms->next; } } while (FindNextFileW(hff, (fd+entry_count)) != 0); FindClose (hff); } /* Work out the actual current directory name without a trailing \ */ strcpyW(real_path, parms->dirName); real_path[strlenW(parms->dirName)-1] = 0x00; /* Output the results */ if (!bare) { if (level != 0 && (entry_count > 0)) WCMD_output (newline); if (!recurse || ((entry_count > 0) && done_header==FALSE)) { static const WCHAR headerW[] = {'D','i','r','e','c','t','o','r','y',' ','o','f', ' ','%','s','\n','\n','\0'}; WCMD_output (headerW, real_path); done_header = TRUE; } } /* Move to next parm */ parms = parms->next; } /* Handle case where everything is filtered out */ if (entry_count > 0) { /* Sort the list of files */ qsort (fd, entry_count, sizeof(WIN32_FIND_DATAW), WCMD_dir_sort); /* Work out the number of columns */ WINE_TRACE("%d entries, maxwidth=%d, widest=%d\n", entry_count, max_width, widest); if (wide || orderByCol) { numCols = max(1, (int)max_width / widest); numRows = entry_count / numCols; if (entry_count % numCols) numRows++; } else { numCols = 1; numRows = entry_count; } WINE_TRACE("cols=%d, rows=%d\n", numCols, numRows); for (rows=0; rows<numRows; rows++) { BOOL addNewLine = TRUE; for (cols=0; cols<numCols; cols++) { WCHAR username[24]; /* Work out the index of the entry being pointed to */ if (orderByCol) { i = (cols * numRows) + rows; if (i >= entry_count) continue; } else { i = (rows * numCols) + cols; if (i >= entry_count) continue; } /* /L convers all names to lower case */ if (lower) { WCHAR *p = (fd+i)->cFileName; while ( (*p = tolower(*p)) ) ++p; } /* /Q gets file ownership information */ if (usernames) { strcpyW (string, inputparms->dirName); strcatW (string, (fd+i)->cFileName); WCMD_getfileowner(string, username, sizeof(username)/sizeof(WCHAR)); } if (dirTime == Written) { FileTimeToLocalFileTime (&(fd+i)->ftLastWriteTime, &ft); } else if (dirTime == Access) { FileTimeToLocalFileTime (&(fd+i)->ftLastAccessTime, &ft); } else { FileTimeToLocalFileTime (&(fd+i)->ftCreationTime, &ft); } FileTimeToSystemTime (&ft, &st); GetDateFormatW(0, DATE_SHORTDATE, &st, NULL, datestring, sizeof(datestring)/sizeof(WCHAR)); GetTimeFormatW(0, TIME_NOSECONDS, &st, NULL, timestring, sizeof(timestring)/sizeof(WCHAR)); if (wide) { tmp_width = cur_width; if ((fd+i)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { static const WCHAR fmt[] = {'[','%','s',']','\0'}; WCMD_output (fmt, (fd+i)->cFileName); dir_count++; tmp_width = tmp_width + strlenW((fd+i)->cFileName) + 2; } else { static const WCHAR fmt[] = {'%','s','\0'}; WCMD_output (fmt, (fd+i)->cFileName); tmp_width = tmp_width + strlenW((fd+i)->cFileName) ; file_count++; file_size.u.LowPart = (fd+i)->nFileSizeLow; file_size.u.HighPart = (fd+i)->nFileSizeHigh; byte_count.QuadPart += file_size.QuadPart; } cur_width = cur_width + widest; if ((cur_width + widest) > max_width) { cur_width = 0; } else { int padding = cur_width - tmp_width; int toWrite = 0; WCHAR temp[101]; /* Note: WCMD_output uses wvsprintf which does not allow %* so manually pad with spaces to appropriate width */ strcpyW(temp, nullW); while (padding > 0) { strcatW(&temp[toWrite], space); toWrite++; if (toWrite > 99) { WCMD_output(temp); toWrite = 0; strcpyW(temp, nullW); } padding--; } WCMD_output(temp); } } else if ((fd+i)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { dir_count++; if (!bare) { WCMD_output (fmtDir, datestring, timestring); if (shortname) WCMD_output (fmt2, (fd+i)->cAlternateFileName); if (usernames) WCMD_output (fmt3, username); WCMD_output(fmt4,(fd+i)->cFileName); } else { if (!((strcmpW((fd+i)->cFileName, dotW) == 0) || (strcmpW((fd+i)->cFileName, dotdotW) == 0))) { WCMD_output (fmt5, recurse?inputparms->dirName:nullW, (fd+i)->cFileName); } else { addNewLine = FALSE; } } } else { file_count++; file_size.u.LowPart = (fd+i)->nFileSizeLow; file_size.u.HighPart = (fd+i)->nFileSizeHigh; byte_count.QuadPart += file_size.QuadPart; if (!bare) { WCMD_output (fmtFile, datestring, timestring, WCMD_filesize64(file_size.QuadPart)); if (shortname) WCMD_output (fmt2, (fd+i)->cAlternateFileName); if (usernames) WCMD_output (fmt3, username); WCMD_output(fmt4,(fd+i)->cFileName); } else { WCMD_output (fmt5, recurse?inputparms->dirName:nullW, (fd+i)->cFileName); } } } if (addNewLine) WCMD_output (newline); cur_width = 0; } if (!bare) { if (file_count == 1) { static const WCHAR fmt[] = {' ',' ',' ',' ',' ',' ',' ','1',' ','f','i','l','e',' ', '%','2','5','s',' ','b','y','t','e','s','\n','\0'}; WCMD_output (fmt, WCMD_filesize64 (byte_count.QuadPart)); } else { static const WCHAR fmt[] = {'%','8','d',' ','f','i','l','e','s',' ','%','2','4','s', ' ','b','y','t','e','s','\n','\0'}; WCMD_output (fmt, file_count, WCMD_filesize64 (byte_count.QuadPart)); } } byte_total = byte_total + byte_count.QuadPart; file_total = file_total + file_count; dir_total = dir_total + dir_count; if (!bare && !recurse) { if (dir_count == 1) { static const WCHAR fmt[] = {'%','8','d',' ','d','i','r','e','c','t','o','r','y', ' ',' ',' ',' ',' ',' ',' ',' ',' ','\0'}; WCMD_output (fmt, 1); } else { static const WCHAR fmt[] = {'%','8','d',' ','d','i','r','e','c','t','o','r','i', 'e','s','\0'}; WCMD_output (fmt, dir_count); } } } HeapFree(GetProcessHeap(),0,fd); /* When recursing, look in all subdirectories for matches */ if (recurse) { DIRECTORY_STACK *dirStack = NULL; DIRECTORY_STACK *lastEntry = NULL; WIN32_FIND_DATAW finddata; /* Build path to search */ strcpyW(string, inputparms->dirName); strcatW(string, starW); WINE_TRACE("Recursive, looking for '%s'\n", wine_dbgstr_w(string)); hff = FindFirstFileW(string, &finddata); if (hff != INVALID_HANDLE_VALUE) { do { if ((finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (strcmpW(finddata.cFileName, dotdotW) != 0) && (strcmpW(finddata.cFileName, dotW) != 0)) { DIRECTORY_STACK *thisDir; int dirsToCopy = concurrentDirs; /* Loop creating list of subdirs for all concurrent entries */ parms = inputparms; while (dirsToCopy > 0) { dirsToCopy--; /* Work out search parameter in sub dir */ strcpyW (string, inputparms->dirName); strcatW (string, finddata.cFileName); strcatW (string, slashW); WINE_TRACE("Recursive, Adding to search list '%s'\n", wine_dbgstr_w(string)); /* Allocate memory, add to list */ thisDir = HeapAlloc(GetProcessHeap(),0,sizeof(DIRECTORY_STACK)); if (dirStack == NULL) dirStack = thisDir; if (lastEntry != NULL) lastEntry->next = thisDir; lastEntry = thisDir; thisDir->next = NULL; thisDir->dirName = HeapAlloc(GetProcessHeap(),0, sizeof(WCHAR) * (strlenW(string)+1)); strcpyW(thisDir->dirName, string); thisDir->fileName = HeapAlloc(GetProcessHeap(),0, sizeof(WCHAR) * (strlenW(parms->fileName)+1)); strcpyW(thisDir->fileName, parms->fileName); parms = parms->next; } } } while (FindNextFileW(hff, &finddata) != 0); FindClose (hff); while (dirStack != NULL) { DIRECTORY_STACK *thisDir = dirStack; dirStack = WCMD_list_directory (thisDir, 1); while (thisDir != dirStack) { DIRECTORY_STACK *tempDir = thisDir->next; HeapFree(GetProcessHeap(),0,thisDir->dirName); HeapFree(GetProcessHeap(),0,thisDir->fileName); HeapFree(GetProcessHeap(),0,thisDir); thisDir = tempDir; } } } } /* Handle case where everything is filtered out */ if ((file_total + dir_total == 0) && (level == 0)) { SetLastError (ERROR_FILE_NOT_FOUND); WCMD_print_error (); errorlevel = 1; } return parms; }
/* Process items in the StartUp group of the user's Programs under the Start Menu. Some installers put * shell links here to restart themselves after boot. */ static BOOL ProcessStartupItems(void) { BOOL ret = FALSE; HRESULT hr; IMalloc *ppM = NULL; IShellFolder *psfDesktop = NULL, *psfStartup = NULL; LPITEMIDLIST pidlStartup = NULL, pidlItem; ULONG NumPIDLs; IEnumIDList *iEnumList = NULL; STRRET strret; WCHAR wszCommand[MAX_PATH]; WINE_TRACE("Processing items in the StartUp folder.\n"); hr = SHGetMalloc(&ppM); if (FAILED(hr)) { WINE_ERR("Couldn't get IMalloc object.\n"); goto done; } hr = SHGetDesktopFolder(&psfDesktop); if (FAILED(hr)) { WINE_ERR("Couldn't get desktop folder.\n"); goto done; } hr = SHGetSpecialFolderLocation(NULL, CSIDL_STARTUP, &pidlStartup); if (FAILED(hr)) { WINE_TRACE("Couldn't get StartUp folder location.\n"); goto done; } hr = IShellFolder_BindToObject(psfDesktop, pidlStartup, NULL, &IID_IShellFolder, (LPVOID*)&psfStartup); if (FAILED(hr)) { WINE_TRACE("Couldn't bind IShellFolder to StartUp folder.\n"); goto done; } hr = IShellFolder_EnumObjects(psfStartup, NULL, SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &iEnumList); if (FAILED(hr)) { WINE_TRACE("Unable to enumerate StartUp objects.\n"); goto done; } while (IEnumIDList_Next(iEnumList, 1, &pidlItem, &NumPIDLs) == S_OK && (NumPIDLs) == 1) { hr = IShellFolder_GetDisplayNameOf(psfStartup, pidlItem, SHGDN_FORPARSING, &strret); if (FAILED(hr)) WINE_TRACE("Unable to get display name of enumeration item.\n"); else { hr = StrRetToBufW(&strret, pidlItem, wszCommand, MAX_PATH); if (FAILED(hr)) WINE_TRACE("Unable to parse display name.\n"); else { HINSTANCE hinst; hinst = ShellExecuteW(NULL, NULL, wszCommand, NULL, NULL, SW_SHOWNORMAL); if (PtrToUlong(hinst) <= 32) WINE_WARN("Error %p executing command %s.\n", hinst, wine_dbgstr_w(wszCommand)); } } IMalloc_Free(ppM, pidlItem); } /* Return success */ ret = TRUE; done: if (iEnumList) IEnumIDList_Release(iEnumList); if (psfStartup) IShellFolder_Release(psfStartup); if (pidlStartup) IMalloc_Free(ppM, pidlStartup); return ret; }
int main( int argc, char *argv[] ) { extern HANDLE CDECL __wine_make_process_system(void); static const WCHAR RunW[] = {'R','u','n',0}; static const WCHAR RunOnceW[] = {'R','u','n','O','n','c','e',0}; static const WCHAR RunServicesW[] = {'R','u','n','S','e','r','v','i','c','e','s',0}; static const WCHAR RunServicesOnceW[] = {'R','u','n','S','e','r','v','i','c','e','s','O','n','c','e',0}; static const WCHAR wineboot_eventW[] = {'_','_','w','i','n','e','b','o','o','t','_','e','v','e','n','t',0}; /* First, set the current directory to SystemRoot */ int optc; int end_session = 0, force = 0, init = 0, kill = 0, restart = 0, shutdown = 0, update = 0; HANDLE event; SECURITY_ATTRIBUTES sa; BOOL is_wow64; GetWindowsDirectoryW( windowsdir, MAX_PATH ); if( !SetCurrentDirectoryW( windowsdir ) ) WINE_ERR("Cannot set the dir to %s (%d)\n", wine_dbgstr_w(windowsdir), GetLastError() ); if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64) { STARTUPINFOW si; PROCESS_INFORMATION pi; WCHAR filename[MAX_PATH]; void *redir; DWORD exit_code; memset( &si, 0, sizeof(si) ); si.cb = sizeof(si); GetModuleFileNameW( 0, filename, MAX_PATH ); Wow64DisableWow64FsRedirection( &redir ); if (CreateProcessW( filename, GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi )) { WINE_TRACE( "restarting %s\n", wine_dbgstr_w(filename) ); WaitForSingleObject( pi.hProcess, INFINITE ); GetExitCodeProcess( pi.hProcess, &exit_code ); ExitProcess( exit_code ); } else WINE_ERR( "failed to restart 64-bit %s, err %d\n", wine_dbgstr_w(filename), GetLastError() ); Wow64RevertWow64FsRedirection( redir ); } while ((optc = getopt_long(argc, argv, short_options, long_options, NULL )) != -1) { switch(optc) { case 'e': end_session = 1; break; case 'f': force = 1; break; case 'i': init = 1; break; case 'k': kill = 1; break; case 'r': restart = 1; break; case 's': shutdown = 1; break; case 'u': update = 1; break; case 'h': usage(); return 0; case '?': usage(); return 1; } } if (end_session) { if (kill) { if (!shutdown_all_desktops( force )) return 1; } else if (!shutdown_close_windows( force )) return 1; } if (kill) kill_processes( shutdown ); if (shutdown) return 0; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* so that services.exe inherits it */ event = CreateEventW( &sa, TRUE, FALSE, wineboot_eventW ); ResetEvent( event ); /* in case this is a restart */ create_hardware_registry_keys(); create_dynamic_registry_keys(); create_environment_registry_keys(); wininit(); pendingRename(); ProcessWindowsFileProtection(); ProcessRunKeys( HKEY_LOCAL_MACHINE, RunServicesOnceW, TRUE, FALSE ); if (init || (kill && !restart)) { ProcessRunKeys( HKEY_LOCAL_MACHINE, RunServicesW, FALSE, FALSE ); start_services_process(); } if (init || update) update_wineprefix( update ); create_volatile_environment_registry_key(); ProcessRunKeys( HKEY_LOCAL_MACHINE, RunOnceW, TRUE, TRUE ); if (!init && !restart) { ProcessRunKeys( HKEY_LOCAL_MACHINE, RunW, FALSE, FALSE ); ProcessRunKeys( HKEY_CURRENT_USER, RunW, FALSE, FALSE ); ProcessStartupItems(); } WINE_TRACE("Operation done\n"); SetEvent( event ); return 0; }
static void make_explorer_window(IShellFolder* startFolder) { RECT explorerRect; HWND rebar,nav_toolbar; FOLDERSETTINGS fs; IExplorerBrowserEvents *events; explorer_info *info; HRESULT hres; WCHAR explorer_title[100]; WCHAR pathbox_label[50]; TBADDBITMAP bitmap_info; TBBUTTON nav_buttons[3]; int hist_offset,view_offset; REBARBANDINFOW band_info; memset(nav_buttons,0,sizeof(nav_buttons)); LoadStringW(explorer_hInstance,IDS_EXPLORER_TITLE,explorer_title, sizeof(explorer_title)/sizeof(WCHAR)); LoadStringW(explorer_hInstance,IDS_PATHBOX_LABEL,pathbox_label, sizeof(pathbox_label)/sizeof(WCHAR)); info = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(explorer_info)); if(!info) { WINE_ERR("Could not allocate a explorer_info struct\n"); return; } hres = CoCreateInstance(&CLSID_ExplorerBrowser,NULL,CLSCTX_INPROC_SERVER, &IID_IExplorerBrowser,(LPVOID*)&info->browser); if(FAILED(hres)) { WINE_ERR("Could not obtain an instance of IExplorerBrowser\n"); HeapFree(GetProcessHeap(),0,info); return; } info->rebar_height=0; info->main_window = CreateWindowW(EXPLORER_CLASS,explorer_title,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,DEFAULT_WIDTH, DEFAULT_HEIGHT,NULL,NULL,explorer_hInstance,NULL); fs.ViewMode = FVM_DETAILS; fs.fFlags = FWF_AUTOARRANGE; explorerRect.left = 0; explorerRect.top = 0; explorerRect.right = DEFAULT_WIDTH; explorerRect.bottom = DEFAULT_HEIGHT; IExplorerBrowser_Initialize(info->browser,info->main_window,&explorerRect,&fs); IExplorerBrowser_SetOptions(info->browser,EBO_SHOWFRAMES); SetWindowLongPtrW(info->main_window,EXPLORER_INFO_INDEX,(LONG_PTR)info); /*setup navbar*/ rebar = CreateWindowExW(WS_EX_TOOLWINDOW,REBARCLASSNAMEW,NULL, WS_CHILD|WS_VISIBLE|RBS_VARHEIGHT|CCS_TOP|CCS_NODIVIDER, 0,0,0,0,info->main_window,NULL,explorer_hInstance,NULL); nav_toolbar = CreateWindowExW(TBSTYLE_EX_MIXEDBUTTONS,TOOLBARCLASSNAMEW,NULL, WS_CHILD|WS_VISIBLE|TBSTYLE_FLAT,0,0,0,0,rebar,NULL, explorer_hInstance,NULL); bitmap_info.hInst = HINST_COMMCTRL; bitmap_info.nID = IDB_HIST_LARGE_COLOR; hist_offset= SendMessageW(nav_toolbar,TB_ADDBITMAP,0,(LPARAM)&bitmap_info); bitmap_info.nID = IDB_VIEW_LARGE_COLOR; view_offset= SendMessageW(nav_toolbar,TB_ADDBITMAP,0,(LPARAM)&bitmap_info); nav_buttons[0].iBitmap=hist_offset+HIST_BACK; nav_buttons[0].idCommand=BACK_BUTTON; nav_buttons[0].fsState=TBSTATE_ENABLED; nav_buttons[0].fsStyle=BTNS_BUTTON|BTNS_AUTOSIZE; nav_buttons[1].iBitmap=hist_offset+HIST_FORWARD; nav_buttons[1].idCommand=FORWARD_BUTTON; nav_buttons[1].fsState=TBSTATE_ENABLED; nav_buttons[1].fsStyle=BTNS_BUTTON|BTNS_AUTOSIZE; nav_buttons[2].iBitmap=view_offset+VIEW_PARENTFOLDER; nav_buttons[2].idCommand=UP_BUTTON; nav_buttons[2].fsState=TBSTATE_ENABLED; nav_buttons[2].fsStyle=BTNS_BUTTON|BTNS_AUTOSIZE; SendMessageW(nav_toolbar,TB_BUTTONSTRUCTSIZE,sizeof(TBBUTTON),0); SendMessageW(nav_toolbar,TB_ADDBUTTONSW,sizeof(nav_buttons)/sizeof(TBBUTTON),(LPARAM)nav_buttons); band_info.cbSize = sizeof(band_info); band_info.fMask = RBBIM_STYLE|RBBIM_CHILD|RBBIM_CHILDSIZE|RBBIM_SIZE; band_info.hwndChild = nav_toolbar; band_info.fStyle=RBBS_GRIPPERALWAYS|RBBS_CHILDEDGE; band_info.cyChild=NAV_TOOLBAR_HEIGHT; band_info.cx=0; band_info.cyMinChild=NAV_TOOLBAR_HEIGHT; band_info.cxMinChild=0; SendMessageW(rebar,RB_INSERTBANDW,-1,(LPARAM)&band_info); info->path_box = CreateWindowW(WC_COMBOBOXEXW,PATH_BOX_NAME, WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, 0,0,DEFAULT_WIDTH,PATHBOX_HEIGHT,rebar,NULL, explorer_hInstance,NULL); band_info.cyChild=PATHBOX_HEIGHT; band_info.cx=0; band_info.cyMinChild=PATHBOX_HEIGHT; band_info.cxMinChild=0; band_info.fMask|=RBBIM_TEXT; band_info.lpText=pathbox_label; band_info.fStyle|=RBBS_BREAK; band_info.hwndChild=info->path_box; SendMessageW(rebar,RB_INSERTBANDW,-1,(LPARAM)&band_info); events = make_explorer_events(info); IExplorerBrowser_Advise(info->browser,events,&info->advise_cookie); IExplorerBrowser_BrowseToObject(info->browser,(IUnknown*)startFolder, SBSP_ABSOLUTE); ShowWindow(info->main_window,SW_SHOWDEFAULT); UpdateWindow(info->main_window); IExplorerBrowserEvents_Release(events); }
/* load the .sys module for a device driver */ static BOOL load_driver(void) { static const WCHAR driversW[] = {'\\','d','r','i','v','e','r','s','\\',0}; static const WCHAR postfixW[] = {'.','s','y','s',0}; static const WCHAR ntprefixW[] = {'\\','?','?','\\',0}; static const WCHAR ImagePathW[] = {'I','m','a','g','e','P','a','t','h',0}; static const WCHAR servicesW[] = {'\\','R','e','g','i','s','t','r','y', '\\','M','a','c','h','i','n','e', '\\','S','y','s','t','e','m', '\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t', '\\','S','e','r','v','i','c','e','s','\\',0}; UNICODE_STRING keypath; HMODULE module; LPWSTR path = NULL, str; DWORD type, size; str = HeapAlloc( GetProcessHeap(), 0, sizeof(servicesW) + strlenW(driver_name)*sizeof(WCHAR) ); lstrcpyW( str, servicesW ); lstrcatW( str, driver_name ); if (RegOpenKeyW( HKEY_LOCAL_MACHINE, str + 18 /* skip \registry\machine */, &driver_hkey )) { WINE_ERR( "cannot open key %s, err=%u\n", wine_dbgstr_w(str), GetLastError() ); HeapFree( GetProcessHeap(), 0, str); return FALSE; } RtlInitUnicodeString( &keypath, str ); /* read the executable path from memory */ size = 0; if (!RegQueryValueExW( driver_hkey, ImagePathW, NULL, &type, NULL, &size )) { str = HeapAlloc( GetProcessHeap(), 0, size ); if (!RegQueryValueExW( driver_hkey, ImagePathW, NULL, &type, (LPBYTE)str, &size )) { size = ExpandEnvironmentStringsW(str,NULL,0); path = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR)); ExpandEnvironmentStringsW(str,path,size); } HeapFree( GetProcessHeap(), 0, str ); if (!path) return FALSE; } else { /* default is to use the driver name + ".sys" */ WCHAR buffer[MAX_PATH]; GetSystemDirectoryW(buffer, MAX_PATH); path = HeapAlloc(GetProcessHeap(),0, (strlenW(buffer) + strlenW(driversW) + strlenW(driver_name) + strlenW(postfixW) + 1) *sizeof(WCHAR)); lstrcpyW(path, buffer); lstrcatW(path, driversW); lstrcatW(path, driver_name); lstrcatW(path, postfixW); } /* GameGuard uses an NT-style path name */ str = path; if (!strncmpW( path, ntprefixW, 4 )) str += 4; WINE_TRACE( "loading driver %s\n", wine_dbgstr_w(str) ); module = load_driver_module( str ); HeapFree( GetProcessHeap(), 0, path ); if (!module) return FALSE; init_driver( module, &keypath ); return TRUE; }
/*********************************************************************** * pif_cmd * * execute a pif file. */ static VOID pif_cmd( char *filename, char *cmdline) { HANDLE hFile; char progpath[MAX_PATH]; char buf[128]; char progname[64]; char title[31]; char optparams[64]; char startdir[64]; char *p; int closeonexit; int textmode; if( (hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE) { WINE_ERR("open file %s failed\n", wine_dbgstr_a(filename)); return; } if( !read_pif_file( hFile, progname, title, optparams, startdir, &closeonexit, &textmode)) { WINE_ERR( "failed to read %s\n", wine_dbgstr_a(filename)); CloseHandle( hFile); sprintf( buf, "%s\nInvalid file format. Check your pif file.", filename); MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONWARNING); SetLastError( ERROR_BAD_FORMAT); return; } CloseHandle( hFile); if( (p = strrchr( progname, '.')) && !strcasecmp( p, ".bat")) WINE_FIXME(".bat programs in pif files are not supported.\n"); /* first change dir, so the search below can start from there */ if( startdir[0] && !SetCurrentDirectory( startdir)) { WINE_ERR("Cannot change directory %s\n", wine_dbgstr_a( startdir)); sprintf( buf, "%s\nInvalid startup directory. Check your pif file.", filename); MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONWARNING); } /* search for the program */ if( !SearchPathA( NULL, progname, NULL, MAX_PATH, progpath, NULL )) { sprintf( buf, "%s\nInvalid program file name. Check your pif file.", filename); MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONERROR); SetLastError( ERROR_FILE_NOT_FOUND); return; } if( textmode) if( AllocConsole()) SetConsoleTitleA( title) ; /* if no arguments on the commandline, use them from the pif file */ if( !cmdline[0] && optparams[0]) cmdline = optparams; /* FIXME: do something with: * - close on exit * - graphic modes * - hot key's * - etc. */ wine_load_dos_exe( progpath, cmdline ); return; }
cudaError_t WINAPI wine_cudaLaunch(const char *entry) { WINE_TRACE("%p\n", entry); if (QUEUE_MAX == numQueued) { cudaError_t evtErr; if (WINE_TRACE_ON(cuda)) { /* print out if event was recorded or not */ WINE_TRACE("check event recorded %s\n", debug_cudaError(cudaEventQuery(event))); } /* wait for event */ unsigned int sleepCount = 0; char * SLTIME = getenv("SLEEPTIME"); if ( SLTIME == NULL ) { sleep = 300000; } else { sleep = atoi ( SLTIME ); } while (cudaEventQuery(event) != cudaSuccess) { nanosleep(sleep, NULL); sleepCount++; } WINE_TRACE("slept %u times\n", sleepCount); WINE_TRACE("event recorded, continuing\n"); /* record a new event and subtract HALF_QUEUE_MAX from numQueued */ numQueued = HALF_QUEUE_MAX; evtErr = cudaEventRecord(event, 0); if (evtErr) { WINE_ERR("cudaEventRecord: %s\n", debug_cudaError(evtErr)); } } cudaError_t err = cudaLaunch(entry); if (!eventInitialized) { /* Create an event on the first cudaLaunch call. This is done here so the calling program * has a chance to select the GPU device with cudaSetDevice if desired. */ cudaError_t evtErr = cudaEventCreate(&event); if (evtErr) { WINE_ERR("cudaEventCreate: %s\n", debug_cudaError(evtErr)); } /* cudaEventCreate can WINE_TRACE("\n"); return errors from previous asynchronous calls, so an error here does * not necessarily mean the event wasn't created. Assume it was created for now. */ eventInitialized = TRUE; WINE_TRACE("created event %d\n", event); } /* record an event at HALF_QUEUE_MAX */ if (HALF_QUEUE_MAX == ++numQueued) { cudaError_t evtErr = cudaEventRecord(event, 0); /* Assuming everything using stream 0 */ if (evtErr) { WINE_ERR("cudaEventRecord: %s\n", debug_cudaError(evtErr)); } } if (err) { WINE_TRACE("return %s\n", debug_cudaError(err)); } return err; }
int wmain( int argc, WCHAR *argv[] ) { static const WCHAR noneW[] = {'n','o','n','e',0}; static const WCHAR mszipW[] = {'m','s','z','i','p',0}; WCHAR *p, *command; char buffer[MAX_PATH]; char filename[MAX_PATH]; char *cab_file, *file_part; int i; while (argv[1] && argv[1][0] == '-') { switch (argv[1][1]) { case 'd': argv++; argc--; opt_cabinet_size = atoiW( argv[1] ); if (opt_cabinet_size < 50000) { WINE_MESSAGE( "cabarc: Cabinet size must be at least 50000\n" ); return 1; } break; case 'h': usage(); return 0; case 'i': argv++; argc--; opt_cabinet_id = atoiW( argv[1] ); break; case 'm': argv++; argc--; if (!strcmpiW( argv[1], noneW )) opt_compression = tcompTYPE_NONE; else if (!strcmpiW( argv[1], mszipW )) opt_compression = tcompTYPE_MSZIP; else { WINE_MESSAGE( "cabarc: Unknown compression type '%s'\n", optarg ); return 1; } break; case 'p': opt_preserve_paths = 1; break; case 'r': opt_recurse = 1; break; case 's': argv++; argc--; opt_reserve_space = atoiW( argv[1] ); break; case 'v': opt_verbose++; break; default: usage(); return 1; } argv++; argc--; } command = argv[1]; if (argc < 3 || !command[0] || command[1]) { usage(); return 1; } cab_file = strdupWtoA( CP_ACP, argv[2] ); argv += 2; argc -= 2; if (!GetFullPathNameA( cab_file, MAX_PATH, buffer, &file_part ) || !file_part) { WINE_ERR( "cannot get full name for %s\n", wine_dbgstr_a( cab_file )); return 1; } strcpy(filename, file_part); file_part[0] = 0; /* map slash to backslash in all file arguments */ for (i = 1; i < argc; i++) for (p = argv[i]; *p; p++) if (*p == '/') *p = '\\'; opt_files = argv + 1; opt_cab_file = filename; switch (*command) { case 'l': case 'L': return list_cabinet( buffer ); case 'n': case 'N': return new_cabinet( buffer ); case 'x': case 'X': if (argc > 1) /* check for destination dir as last argument */ { WCHAR *last = argv[argc - 1]; if (last[0] && last[strlenW(last) - 1] == '\\') { opt_dest_dir = last; argv[--argc] = NULL; } } WINE_TRACE("Extracting file(s) from cabinet %s\n", wine_dbgstr_a(cab_file)); return extract_cabinet( buffer ); default: usage(); return 1; } }
static DWORD service_start_process(struct service_entry *service_entry, HANDLE *process) { PROCESS_INFORMATION pi; STARTUPINFOW si; LPWSTR path = NULL; DWORD size; BOOL r; service_lock_exclusive(service_entry); if (!env) { HANDLE htok; if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &htok)) CreateEnvironmentBlock(&env, htok, FALSE); if (!env) WINE_ERR("failed to create services environment\n"); } size = ExpandEnvironmentStringsW(service_entry->config.lpBinaryPathName,NULL,0); path = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR)); if (!path) { service_unlock(service_entry); return ERROR_NOT_ENOUGH_SERVER_MEMORY; } ExpandEnvironmentStringsW(service_entry->config.lpBinaryPathName,path,size); if (service_entry->config.dwServiceType == SERVICE_KERNEL_DRIVER) { static const WCHAR winedeviceW[] = {'\\','w','i','n','e','d','e','v','i','c','e','.','e','x','e',' ',0}; WCHAR system_dir[MAX_PATH]; DWORD type, len; GetSystemDirectoryW( system_dir, MAX_PATH ); if (is_win64) { if (!GetBinaryTypeW( path, &type )) { HeapFree( GetProcessHeap(), 0, path ); service_unlock(service_entry); return GetLastError(); } if (type == SCS_32BIT_BINARY) GetSystemWow64DirectoryW( system_dir, MAX_PATH ); } len = strlenW( system_dir ) + sizeof(winedeviceW)/sizeof(WCHAR) + strlenW(service_entry->name); HeapFree( GetProcessHeap(), 0, path ); if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) { service_unlock(service_entry); return ERROR_NOT_ENOUGH_SERVER_MEMORY; } lstrcpyW( path, system_dir ); lstrcatW( path, winedeviceW ); lstrcatW( path, service_entry->name ); } ZeroMemory(&si, sizeof(STARTUPINFOW)); si.cb = sizeof(STARTUPINFOW); if (!(service_entry->config.dwServiceType & SERVICE_INTERACTIVE_PROCESS)) { static WCHAR desktopW[] = {'_','_','w','i','n','e','s','e','r','v','i','c','e','_','w','i','n','s','t','a','t','i','o','n','\\','D','e','f','a','u','l','t',0}; si.lpDesktop = desktopW; } service_entry->status.dwCurrentState = SERVICE_START_PENDING; service_unlock(service_entry); r = CreateProcessW(NULL, path, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, env, NULL, &si, &pi); HeapFree(GetProcessHeap(),0,path); if (!r) { service_lock_exclusive(service_entry); service_entry->status.dwCurrentState = SERVICE_STOPPED; service_unlock(service_entry); return GetLastError(); } service_entry->status.dwProcessId = pi.dwProcessId; service_entry->process = pi.hProcess; *process = pi.hProcess; CloseHandle( pi.hThread ); return ERROR_SUCCESS; }
static BOOL pendingRename(void) { static const WCHAR ValueName[] = {'P','e','n','d','i','n','g', 'F','i','l','e','R','e','n','a','m','e', 'O','p','e','r','a','t','i','o','n','s',0}; static const WCHAR SessionW[] = { 'S','y','s','t','e','m','\\', 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', 'C','o','n','t','r','o','l','\\', 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r',0}; WCHAR *buffer=NULL; const WCHAR *src=NULL, *dst=NULL; DWORD dataLength=0; HKEY hSession=NULL; DWORD res; WINE_TRACE("Entered\n"); if( (res=RegOpenKeyExW( HKEY_LOCAL_MACHINE, SessionW, 0, KEY_ALL_ACCESS, &hSession )) !=ERROR_SUCCESS ) { WINE_TRACE("The key was not found - skipping\n"); return TRUE; } res=RegQueryValueExW( hSession, ValueName, NULL, NULL /* The value type does not really interest us, as it is not truly a REG_MULTI_SZ anyways */, NULL, &dataLength ); if( res==ERROR_FILE_NOT_FOUND ) { /* No value - nothing to do. Great! */ WINE_TRACE("Value not present - nothing to rename\n"); res=TRUE; goto end; } if( res!=ERROR_SUCCESS ) { WINE_ERR("Couldn't query value's length (%d)\n", res ); res=FALSE; goto end; } buffer=HeapAlloc( GetProcessHeap(),0,dataLength ); if( buffer==NULL ) { WINE_ERR("Couldn't allocate %u bytes for the value\n", dataLength ); res=FALSE; goto end; } res=RegQueryValueExW( hSession, ValueName, NULL, NULL, (LPBYTE)buffer, &dataLength ); if( res!=ERROR_SUCCESS ) { WINE_ERR("Couldn't query value after successfully querying before (%u),\n" "please report to [email protected]\n", res); res=FALSE; goto end; } /* Make sure that the data is long enough and ends with two NULLs. This * simplifies the code later on. */ if( dataLength<2*sizeof(buffer[0]) || buffer[dataLength/sizeof(buffer[0])-1]!='\0' || buffer[dataLength/sizeof(buffer[0])-2]!='\0' ) { WINE_ERR("Improper value format - doesn't end with NULL\n"); res=FALSE; goto end; } for( src=buffer; (src-buffer)*sizeof(src[0])<dataLength && *src!='\0'; src=dst+lstrlenW(dst)+1 ) { DWORD dwFlags=0; WINE_TRACE("processing next command\n"); dst=src+lstrlenW(src)+1; /* We need to skip the \??\ header */ if( src[0]=='\\' && src[1]=='?' && src[2]=='?' && src[3]=='\\' ) src+=4; if( dst[0]=='!' ) { dwFlags|=MOVEFILE_REPLACE_EXISTING; dst++; } if( dst[0]=='\\' && dst[1]=='?' && dst[2]=='?' && dst[3]=='\\' ) dst+=4; if( *dst!='\0' ) { /* Rename the file */ MoveFileExW( src, dst, dwFlags ); } else { /* Delete the file or directory */ if (!RemoveDirectoryW( src ) && GetLastError() == ERROR_DIRECTORY) DeleteFileW( src ); } } if((res=RegDeleteValueW(hSession, ValueName))!=ERROR_SUCCESS ) { WINE_ERR("Error deleting the value (%u)\n", GetLastError() ); res=FALSE; } else res=TRUE; end: HeapFree(GetProcessHeap(), 0, buffer); if( hSession!=NULL ) RegCloseKey( hSession ); return res; }
/****************************************************************************** * service_send_start_message */ static BOOL service_send_start_message(struct service_entry *service, HANDLE process_handle, LPCWSTR *argv, DWORD argc) { OVERLAPPED overlapped; DWORD i, len, result; service_start_info *ssi; LPWSTR p; BOOL r; WINE_TRACE("%s %p %d\n", wine_dbgstr_w(service->name), argv, argc); overlapped.hEvent = service->overlapped_event; if (!ConnectNamedPipe(service->control_pipe, &overlapped)) { if (GetLastError() == ERROR_IO_PENDING) { HANDLE handles[2]; handles[0] = service->overlapped_event; handles[1] = process_handle; if (WaitForMultipleObjects( 2, handles, FALSE, service_pipe_timeout ) != WAIT_OBJECT_0) CancelIo( service->control_pipe ); if (!HasOverlappedCompleted( &overlapped )) { WINE_ERR( "service %s failed to start\n", wine_dbgstr_w( service->name )); return FALSE; } } else if (GetLastError() != ERROR_PIPE_CONNECTED) { WINE_ERR("pipe connect failed\n"); return FALSE; } } /* calculate how much space do we need to send the startup info */ len = strlenW(service->name) + 1; for (i=0; i<argc; i++) len += strlenW(argv[i])+1; len++; ssi = HeapAlloc(GetProcessHeap(),0,FIELD_OFFSET(service_start_info, data[len])); ssi->cmd = WINESERV_STARTINFO; ssi->control = 0; ssi->total_size = FIELD_OFFSET(service_start_info, data[len]); ssi->name_size = strlenW(service->name) + 1; strcpyW( ssi->data, service->name ); /* copy service args into a single buffer*/ p = &ssi->data[ssi->name_size]; for (i=0; i<argc; i++) { strcpyW(p, argv[i]); p += strlenW(p) + 1; } *p=0; r = service_send_command( service, service->control_pipe, ssi, ssi->total_size, &result ); if (r && result) { SetLastError(result); r = FALSE; } HeapFree(GetProcessHeap(),0,ssi); return r; }
/* * Process a "Run" type registry key. * hkRoot is the HKEY from which "Software\Microsoft\Windows\CurrentVersion" is * opened. * szKeyName is the key holding the actual entries. * bDelete tells whether we should delete each value right before executing it. * bSynchronous tells whether we should wait for the prog to complete before * going on to the next prog. */ static BOOL ProcessRunKeys( HKEY hkRoot, LPCWSTR szKeyName, BOOL bDelete, BOOL bSynchronous ) { static const WCHAR WINKEY_NAME[]={'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0}; HKEY hkWin, hkRun; DWORD res, dispos; DWORD i, nMaxCmdLine=0, nMaxValue=0; WCHAR *szCmdLine=NULL; WCHAR *szValue=NULL; if (hkRoot==HKEY_LOCAL_MACHINE) WINE_TRACE("processing %s entries under HKLM\n",wine_dbgstr_w(szKeyName) ); else WINE_TRACE("processing %s entries under HKCU\n",wine_dbgstr_w(szKeyName) ); if (RegCreateKeyExW( hkRoot, WINKEY_NAME, 0, NULL, 0, KEY_READ, NULL, &hkWin, NULL ) != ERROR_SUCCESS) return TRUE; if ((res = RegCreateKeyExW( hkWin, szKeyName, 0, NULL, 0, bDelete ? KEY_ALL_ACCESS : KEY_READ, NULL, &hkRun, &dispos ) != ERROR_SUCCESS)) { RegCloseKey( hkWin ); return TRUE; } RegCloseKey( hkWin ); if (dispos == REG_CREATED_NEW_KEY) goto end; if( (res=RegQueryInfoKeyW( hkRun, NULL, NULL, NULL, NULL, NULL, NULL, &i, &nMaxValue, &nMaxCmdLine, NULL, NULL ))!=ERROR_SUCCESS ) goto end; if( i==0 ) { WINE_TRACE("No commands to execute.\n"); res=ERROR_SUCCESS; goto end; } if( (szCmdLine=HeapAlloc(GetProcessHeap(),0,nMaxCmdLine))==NULL ) { WINE_ERR("Couldn't allocate memory for the commands to be executed\n"); res=ERROR_NOT_ENOUGH_MEMORY; goto end; } if( (szValue=HeapAlloc(GetProcessHeap(),0,(++nMaxValue)*sizeof(*szValue)))==NULL ) { WINE_ERR("Couldn't allocate memory for the value names\n"); res=ERROR_NOT_ENOUGH_MEMORY; goto end; } while( i>0 ) { DWORD nValLength=nMaxValue, nDataLength=nMaxCmdLine; DWORD type; --i; if( (res=RegEnumValueW( hkRun, i, szValue, &nValLength, 0, &type, (LPBYTE)szCmdLine, &nDataLength ))!=ERROR_SUCCESS ) { WINE_ERR("Couldn't read in value %d - %d\n", i, res ); continue; } if( bDelete && (res=RegDeleteValueW( hkRun, szValue ))!=ERROR_SUCCESS ) { WINE_ERR("Couldn't delete value - %d, %d. Running command anyways.\n", i, res ); } if( type!=REG_SZ ) { WINE_ERR("Incorrect type of value #%d (%d)\n", i, type ); continue; } if( (res=runCmd(szCmdLine, NULL, bSynchronous, FALSE ))==INVALID_RUNCMD_RETURN ) { WINE_ERR("Error running cmd %s (%d)\n", wine_dbgstr_w(szCmdLine), GetLastError() ); } WINE_TRACE("Done processing cmd #%d\n", i); } res=ERROR_SUCCESS; end: HeapFree( GetProcessHeap(), 0, szValue ); HeapFree( GetProcessHeap(), 0, szCmdLine ); if( hkRun!=NULL ) RegCloseKey( hkRun ); WINE_TRACE("done\n"); return res==ERROR_SUCCESS; }
static void initAudioDlg (HWND hDlg) { int i, j, found; char* buf = NULL; WINE_TRACE("\n"); /* make a list of all drivers that can be loaded */ findAudioDrivers(); /* get current registry setting if available */ buf = get_reg_key(config_key, "Drivers", "Audio", NULL); /* check for first time install and set a default driver * select first available driver, and if that fails: none */ if (buf == NULL) { /* select first available driver */ if (*loadedAudioDrv->szDriver) selectDriver(hDlg, loadedAudioDrv->szDriver); } else /* make a local copy of the current registry setting */ strcpy(curAudioDriver, buf); WINE_TRACE("curAudioDriver = %s\n", curAudioDriver); /* check for drivers that can't be loaded */ checkRegistrySetting(hDlg); initAudioDeviceTree(hDlg); SendDlgItemMessage(hDlg, IDC_DSOUND_HW_ACCEL, CB_RESETCONTENT, 0, 0); buf = get_reg_key(config_key, keypath("DirectSound"), "HardwareAcceleration", "Full"); j = found = 0; for (i = 0; 0 != DSound_HW_Accels[i].displayID; ++i) { WCHAR accelStr[64]; int match; match = (strcmp(buf, DSound_HW_Accels[i].settingStr) == 0); if (match) { DSound_HW_Accels[i].visible = 1; found = 1; } if (DSound_HW_Accels[i].visible) { LoadStringW (GetModuleHandle (NULL), DSound_HW_Accels[i].displayID, accelStr, sizeof(accelStr)/sizeof(accelStr[0])); SendDlgItemMessageW (hDlg, IDC_DSOUND_HW_ACCEL, CB_ADDSTRING, 0, (LPARAM)accelStr); if (match) SendDlgItemMessage(hDlg, IDC_DSOUND_HW_ACCEL, CB_SETCURSEL, j, 0); j++; } } if (!found) { WINE_ERR("Invalid Direct Sound HW Accel read from registry (%s)\n", buf); } HeapFree(GetProcessHeap(), 0, buf); SendDlgItemMessage(hDlg, IDC_DSOUND_RATES, CB_RESETCONTENT, 0, 0); for (i = 0; NULL != DSound_Rates[i]; ++i) { SendDlgItemMessage(hDlg, IDC_DSOUND_RATES, CB_ADDSTRING, 0, (LPARAM) DSound_Rates[i]); } buf = get_reg_key(config_key, keypath("DirectSound"), "DefaultSampleRate", "44100"); for (i = 0; NULL != DSound_Rates[i]; ++i) { if (strcmp(buf, DSound_Rates[i]) == 0) { SendDlgItemMessage(hDlg, IDC_DSOUND_RATES, CB_SETCURSEL, i, 0); break ; } } SendDlgItemMessage(hDlg, IDC_DSOUND_BITS, CB_RESETCONTENT, 0, 0); for (i = 0; NULL != DSound_Bits[i]; ++i) { SendDlgItemMessage(hDlg, IDC_DSOUND_BITS, CB_ADDSTRING, 0, (LPARAM) DSound_Bits[i]); } buf = get_reg_key(config_key, keypath("DirectSound"), "DefaultBitsPerSample", "16"); for (i = 0; NULL != DSound_Bits[i]; ++i) { if (strcmp(buf, DSound_Bits[i]) == 0) { SendDlgItemMessage(hDlg, IDC_DSOUND_BITS, CB_SETCURSEL, i, 0); break ; } } HeapFree(GetProcessHeap(), 0, buf); }
int wmain (int argc, WCHAR *argv[]) { SHELLEXECUTEINFOW sei; WCHAR *args = NULL; int i; int unix_mode = 0; int progid_open = 0; WCHAR *dos_filename = NULL; WCHAR *parent_directory = NULL; DWORD binary_type; static const WCHAR openW[] = { 'o', 'p', 'e', 'n', 0 }; static const WCHAR unixW[] = { 'u', 'n', 'i', 'x', 0 }; static const WCHAR progIDOpenW[] = { 'p', 'r', 'o', 'g', 'I', 'D', 'O', 'p', 'e', 'n', 0}; memset(&sei, 0, sizeof(sei)); sei.cbSize = sizeof(sei); sei.lpVerb = openW; sei.nShow = SW_SHOWNORMAL; /* Dunno what these mean, but it looks like winMe's start uses them */ sei.fMask = SEE_MASK_FLAG_DDEWAIT| SEE_MASK_FLAG_NO_UI| SEE_MASK_NO_CONSOLE; /* Canonical Microsoft commandline flag processing: * flags start with /, are case insensitive, * and may be run together in same word. */ for (i=1; i<argc; i++) { int ci; if (argv[i][0] != '/') break; /* Unix paths can start with / so we have to assume anything following /U is not a flag */ if (unix_mode || progid_open) break; /* Handle all options in this word */ for (ci=0; argv[i][ci]; ) { /* Skip slash */ ci++; switch(argv[i][ci]) { case 'b': case 'B': break; /* FIXME: should stop new window from being created */ case 'i': case 'I': break; /* FIXME: should ignore any changes to current environment */ case 'l': case 'L': license(); break; /* notreached */ case 'm': case 'M': if (argv[i][ci+1] == 'a' || argv[i][ci+1] == 'A') sei.nShow = SW_SHOWMAXIMIZED; else sei.nShow = SW_SHOWMINIMIZED; break; case 'r': case 'R': /* sei.nShow = SW_SHOWNORMAL; */ break; case 'u': case 'U': if (strncmpiW(&argv[i][ci], unixW, 4) == 0) unix_mode = 1; else { WINE_ERR("Option '%s' not recognized\n", wine_dbgstr_w( argv[i]+ci-1)); usage(); } break; case 'p': case 'P': if (strncmpiW(&argv[i][ci], progIDOpenW, 17) == 0) progid_open = 1; else { WINE_ERR("Option '%s' not recognized\n", wine_dbgstr_w( argv[i]+ci-1)); usage(); } break; case 'w': case 'W': sei.fMask |= SEE_MASK_NOCLOSEPROCESS; break; default: WINE_ERR("Option '%s' not recognized\n", wine_dbgstr_w( argv[i]+ci-1)); usage(); } /* Skip to next slash */ while (argv[i][ci] && (argv[i][ci] != '/')) ci++; } } if (i == argc) usage(); if (progid_open) { sei.lpClass = argv[i++]; sei.fMask |= SEE_MASK_CLASSNAME; } sei.lpFile = argv[i++]; args = build_args( argc - i, &argv[i] ); sei.lpParameters = args; if (unix_mode || progid_open) { LPWSTR (*CDECL wine_get_dos_file_name_ptr)(LPCSTR); char* multibyte_unixpath; int multibyte_unixpath_len; wine_get_dos_file_name_ptr = (void*)GetProcAddress(GetModuleHandleA("KERNEL32"), "wine_get_dos_file_name"); if (!wine_get_dos_file_name_ptr) fatal_string(STRING_UNIXFAIL); multibyte_unixpath_len = WideCharToMultiByte(CP_UNIXCP, 0, sei.lpFile, -1, NULL, 0, NULL, NULL); multibyte_unixpath = HeapAlloc(GetProcessHeap(), 0, multibyte_unixpath_len); WideCharToMultiByte(CP_UNIXCP, 0, sei.lpFile, -1, multibyte_unixpath, multibyte_unixpath_len, NULL, NULL); dos_filename = wine_get_dos_file_name_ptr(multibyte_unixpath); HeapFree(GetProcessHeap(), 0, multibyte_unixpath); if (!dos_filename) fatal_string(STRING_UNIXFAIL); sei.lpFile = dos_filename; sei.lpDirectory = parent_directory = get_parent_dir(dos_filename); sei.fMask &= ~SEE_MASK_FLAG_NO_UI; if (GetBinaryTypeW(sei.lpFile, &binary_type)) { WCHAR *commandline; STARTUPINFOW startup_info; PROCESS_INFORMATION process_information; static WCHAR commandlineformat[] = {'"','%','s','"','%','s',0}; /* explorer on windows always quotes the filename when running a binary on windows (see bug 5224) so we have to use CreateProcessW in this case */ commandline = HeapAlloc(GetProcessHeap(), 0, (strlenW(sei.lpFile)+3+strlenW(sei.lpParameters))*sizeof(WCHAR)); sprintfW(commandline, commandlineformat, sei.lpFile, sei.lpParameters); ZeroMemory(&startup_info, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); if (!CreateProcessW( NULL, /* lpApplicationName */ commandline, /* lpCommandLine */ NULL, /* lpProcessAttributes */ NULL, /* lpThreadAttributes */ FALSE, /* bInheritHandles */ CREATE_NEW_CONSOLE, /* dwCreationFlags */ NULL, /* lpEnvironment */ sei.lpDirectory, /* lpCurrentDirectory */ &startup_info, /* lpStartupInfo */ &process_information /* lpProcessInformation */ )) { fatal_string_error(STRING_EXECFAIL, GetLastError(), sei.lpFile); } sei.hProcess = process_information.hProcess; goto done; } } if (!ShellExecuteExW(&sei)) fatal_string_error(STRING_EXECFAIL, GetLastError(), sei.lpFile); done: HeapFree( GetProcessHeap(), 0, args ); HeapFree( GetProcessHeap(), 0, dos_filename ); HeapFree( GetProcessHeap(), 0, parent_directory ); if (sei.fMask & SEE_MASK_NOCLOSEPROCESS) { DWORD exitcode; WaitForSingleObject(sei.hProcess, INFINITE); GetExitCodeProcess(sei.hProcess, &exitcode); ExitProcess(exitcode); } ExitProcess(0); }
static WCHAR *get_url_from_dde(void) { static const WCHAR szApplication[] = {'I','E','x','p','l','o','r','e',0}; static const WCHAR szTopic[] = {'W','W','W','_','O','p','e','n','U','R','L',0}; static const WCHAR szReturn[] = {'R','e','t','u','r','n',0}; HSZ hszApplication = 0; UINT_PTR timer = 0; int rc; WCHAR *ret = NULL; rc = DdeInitializeW(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0); if (rc != DMLERR_NO_ERROR) { WINE_ERR("Unable to initialize DDE, DdeInitialize returned %d\n", rc); goto done; } hszApplication = DdeCreateStringHandleW(ddeInst, szApplication, CP_WINUNICODE); if (!hszApplication) { WINE_ERR("Unable to initialize DDE, DdeCreateStringHandle failed\n"); goto done; } hszTopic = DdeCreateStringHandleW(ddeInst, szTopic, CP_WINUNICODE); if (!hszTopic) { WINE_ERR("Unable to initialize DDE, DdeCreateStringHandle failed\n"); goto done; } hszReturn = DdeCreateStringHandleW(ddeInst, szReturn, CP_WINUNICODE); if (!hszReturn) { WINE_ERR("Unable to initialize DDE, DdeCreateStringHandle failed\n"); goto done; } if (!DdeNameService(ddeInst, hszApplication, 0, DNS_REGISTER)) { WINE_ERR("Unable to initialize DDE, DdeNameService failed\n"); goto done; } timer = SetTimer(NULL, 0, 5000, NULL); if (!timer) { WINE_ERR("SetTimer failed to create timer\n"); goto done; } while (!ddeString) { MSG msg; if (!GetMessageW(&msg, NULL, 0, 0)) break; if (msg.message == WM_TIMER) break; DispatchMessageW(&msg); } if (ddeString) { if (*ddeString == '"') { WCHAR *endquote = strchrW(ddeString + 1, '"'); if (!endquote) { WINE_ERR("Unable to retrieve URL from string %s\n", wine_dbgstr_w(ddeString)); goto done; } *endquote = 0; ret = ddeString+1; } else ret = ddeString; } done: if (timer) KillTimer(NULL, timer); if (ddeInst) { if (hszTopic && hszApplication) DdeNameService(ddeInst, hszApplication, 0, DNS_UNREGISTER); if (hszReturn) DdeFreeStringHandle(ddeInst, hszReturn); if (hszTopic) DdeFreeStringHandle(ddeInst, hszTopic); if (hszApplication) DdeFreeStringHandle(ddeInst, hszApplication); DdeUninitialize(ddeInst); } return ret; }
void WINECON_Fatal(const char* msg) { WINE_ERR("%s\n", msg); ExitProcess(0); }
int PASCAL wWinMain(HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int show) { LPWSTR *argv; int argc; int i; WCHAR check, cmd = 0; WCHAR path[MAX_PATH]; LPCWSTR cabfile = NULL; path[0] = 0; /* Do not use CommandLineToArgvW() or __wgetmainargs() to parse * command line for this program. It should treat each quote as argument * delimiter. This doesn't match with behavior of mentioned functions. * Do not use args provided by wmain() for the same reason. */ argv = get_extrac_args(cmdline, &argc); if(!argv) { WINE_ERR("Command line parsing failed\n"); return 0; } /* Parse arguments */ for(i = 0; i < argc; i++) { /* Get cabfile */ if (argv[i][0] != '/' && argv[i][0] != '-') { if (!cabfile) { cabfile = argv[i]; continue; } else break; } /* Get parameters for commands */ check = toupperW( argv[i][1] ); switch(check) { case 'A': WINE_FIXME("/A not implemented\n"); break; case 'Y': force_mode = TRUE; break; case 'L': if ((i + 1) >= argc) return 0; if (!GetFullPathNameW(argv[++i], MAX_PATH, path, NULL)) return 0; break; case 'C': case 'E': case 'D': if (cmd) return 0; cmd = check; break; default: return 0; } } if (!cabfile) return 0; if (cmd == 'C') { if ((i + 1) != argc) return 0; if (!GetFullPathNameW(argv[i], MAX_PATH, path, NULL)) return 0; } else if (!cmd) /* Use extraction by default if names of required files presents */ cmd = i < argc ? 'E' : 'D'; if (cmd == 'E' && !path[0]) GetCurrentDirectoryW(MAX_PATH, path); PathAddBackslashW(path); /* Execute the specified command */ switch(cmd) { case 'C': /* Copy file */ copy_file(cabfile, path); break; case 'D': /* Display CAB archive */ show_content = TRUE; /* Fall through */ case 'E': /* Extract CAB archive */ extract(cabfile, path); break; } return 0; }
/*********************************************************************** * read_pif_file *pif386rec_tu * Read a pif file and return the header and possibly the 286 (real mode) * record or 386 (enhanced mode) record. Returns FALSE if the file is * invalid otherwise TRUE. */ static BOOL read_pif_file( HANDLE hFile, char *progname, char *title, char *optparams, char *startdir, int *closeonexit, int *textmode) { DWORD nread; LARGE_INTEGER filesize; recordhead_t rhead; BOOL found386rec = FALSE; pif386rec_t pif386rec; pifhead_t pifheader; if( !GetFileSizeEx( hFile, &filesize) || filesize.QuadPart < (sizeof(pifhead_t) + sizeof(recordhead_t))) { WINE_ERR("Invalid pif file: size error %d\n", (int)filesize.QuadPart); return FALSE; } SetFilePointer( hFile, 0, NULL, FILE_BEGIN); if( !ReadFile( hFile, &pifheader, sizeof(pifhead_t), &nread, NULL)) return FALSE; WINE_TRACE("header: program %s title %s startdir %s params %s\n", wine_dbgstr_a(pifheader.program), wine_dbgstr_an(pifheader.windowtitle, sizeof(pifheader.windowtitle)), wine_dbgstr_a(pifheader.startdir), wine_dbgstr_a(pifheader.optparams)); WINE_TRACE("header: memory req'd %d desr'd %d drive %d videomode %d\n", pifheader.memmin, pifheader.memmax, pifheader.startdrive, pifheader.videomode); WINE_TRACE("header: flags 0x%x 0x%x 0x%x\n", pifheader.hdrflags1, pifheader.hdrflags2, pifheader.hdrflags3); ReadFile( hFile, &rhead, sizeof(recordhead_t), &nread, NULL); if( strncmp( rhead.recordname, "MICROSOFT PIFEX", 15)) { WINE_ERR("Invalid pif file: magic string not found\n"); return FALSE; } /* now process the following records */ while( 1) { WORD nextrecord = rhead.posofnextrecord; if( (nextrecord & 0x8000) || filesize.QuadPart <( nextrecord + sizeof(recordhead_t))) break; if( !SetFilePointer( hFile, nextrecord, NULL, FILE_BEGIN) || !ReadFile( hFile, &rhead, sizeof(recordhead_t), &nread, NULL)) return FALSE; if( !rhead.recordname[0]) continue; /* deleted record */ WINE_TRACE("reading record %s size %d next 0x%x\n", wine_dbgstr_a(rhead.recordname), rhead.sizeofdata, rhead.posofnextrecord ); if( !strncmp( rhead.recordname, "WINDOWS 386", 11)) { found386rec = TRUE; ReadFile( hFile, &pif386rec, sizeof(pif386rec_t), &nread, NULL); WINE_TRACE("386rec: memory req'd %d des'd %d EMS req'd %d des'd %d XMS req'd %d des'd %d\n", pif386rec.memmin, pif386rec.memmax, pif386rec.emsmin, pif386rec.emsmax, pif386rec.xmsmin, pif386rec.xmsmax); WINE_TRACE("386rec: option 0x%x memory 0x%x video 0x%x\n", pif386rec.optflags, pif386rec.memflags, pif386rec.videoflags); WINE_TRACE("386rec: optional parameters %s\n", wine_dbgstr_a(pif386rec.optparams)); } } /* prepare the return data */ lstrcpynA( progname, pifheader.program, sizeof(pifheader.program)+1); lstrcpynA( title, pifheader.windowtitle, sizeof(pifheader.windowtitle)+1); if( found386rec) lstrcpynA( optparams, pif386rec.optparams, sizeof( pif386rec.optparams)+1); else lstrcpynA( optparams, pifheader.optparams, sizeof(pifheader.optparams)+1); lstrcpynA( startdir, pifheader.startdir, sizeof(pifheader.startdir)+1); *closeonexit = pifheader.hdrflags1 & 0x10; *textmode = found386rec ? pif386rec.videoflags & 0x0010 : pifheader.hdrflags1 & 0x0002; return TRUE; }
static unsigned dbg_handle_debug_event(DEBUG_EVENT* de) { union { char bufferA[256]; WCHAR buffer[256]; } u; DWORD cont = DBG_CONTINUE; dbg_curr_pid = de->dwProcessId; dbg_curr_tid = de->dwThreadId; if ((dbg_curr_process = dbg_get_process(de->dwProcessId)) != NULL) dbg_curr_thread = dbg_get_thread(dbg_curr_process, de->dwThreadId); else dbg_curr_thread = NULL; switch (de->dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: if (!dbg_curr_thread) { WINE_ERR("%04x:%04x: not a registered process or thread (perhaps a 16 bit one ?)\n", de->dwProcessId, de->dwThreadId); break; } WINE_TRACE("%04x:%04x: exception code=%08x\n", de->dwProcessId, de->dwThreadId, de->u.Exception.ExceptionRecord.ExceptionCode); if (dbg_curr_process->continue_on_first_exception) { dbg_curr_process->continue_on_first_exception = FALSE; if (!DBG_IVAR(BreakOnAttach)) break; } if (dbg_fetch_context()) { cont = dbg_handle_exception(&de->u.Exception.ExceptionRecord, de->u.Exception.dwFirstChance); if (cont && dbg_curr_thread) { SetThreadContext(dbg_curr_thread->handle, &dbg_context); } } break; case CREATE_PROCESS_DEBUG_EVENT: dbg_curr_process = dbg_add_process(&be_process_active_io, de->dwProcessId, de->u.CreateProcessInfo.hProcess); if (dbg_curr_process == NULL) { WINE_ERR("Couldn't create process\n"); break; } fetch_module_name(de->u.CreateProcessInfo.lpImageName, de->u.CreateProcessInfo.fUnicode, de->u.CreateProcessInfo.lpBaseOfImage, u.buffer, sizeof(u.buffer) / sizeof(WCHAR), TRUE); WINE_TRACE("%04x:%04x: create process '%s'/%p @%p (%u<%u>)\n", de->dwProcessId, de->dwThreadId, wine_dbgstr_w(u.buffer), de->u.CreateProcessInfo.lpImageName, de->u.CreateProcessInfo.lpStartAddress, de->u.CreateProcessInfo.dwDebugInfoFileOffset, de->u.CreateProcessInfo.nDebugInfoSize); dbg_set_process_name(dbg_curr_process, u.buffer); if (!dbg_init(dbg_curr_process->handle, u.buffer, FALSE)) dbg_printf("Couldn't initiate DbgHelp\n"); if (!dbg_load_module(dbg_curr_process->handle, de->u.CreateProcessInfo.hFile, u.buffer, (DWORD_PTR)de->u.CreateProcessInfo.lpBaseOfImage, 0)) dbg_printf("couldn't load main module (%u)\n", GetLastError()); WINE_TRACE("%04x:%04x: create thread I @%p\n", de->dwProcessId, de->dwThreadId, de->u.CreateProcessInfo.lpStartAddress); dbg_curr_thread = dbg_add_thread(dbg_curr_process, de->dwThreadId, de->u.CreateProcessInfo.hThread, de->u.CreateProcessInfo.lpThreadLocalBase); if (!dbg_curr_thread) { WINE_ERR("Couldn't create thread\n"); break; } dbg_init_current_process(); dbg_init_current_thread(de->u.CreateProcessInfo.lpStartAddress); break; case EXIT_PROCESS_DEBUG_EVENT: WINE_TRACE("%04x:%04x: exit process (%d)\n", de->dwProcessId, de->dwThreadId, de->u.ExitProcess.dwExitCode); if (dbg_curr_process == NULL) { WINE_ERR("Unknown process\n"); break; } tgt_process_active_close_process(dbg_curr_process, FALSE); dbg_printf("Process of pid=%04x has terminated\n", de->dwProcessId); break; case CREATE_THREAD_DEBUG_EVENT: WINE_TRACE("%04x:%04x: create thread D @%p\n", de->dwProcessId, de->dwThreadId, de->u.CreateThread.lpStartAddress); if (dbg_curr_process == NULL) { WINE_ERR("Unknown process\n"); break; } if (dbg_get_thread(dbg_curr_process, de->dwThreadId) != NULL) { WINE_TRACE("Thread already listed, skipping\n"); break; } dbg_curr_thread = dbg_add_thread(dbg_curr_process, de->dwThreadId, de->u.CreateThread.hThread, de->u.CreateThread.lpThreadLocalBase); if (!dbg_curr_thread) { WINE_ERR("Couldn't create thread\n"); break; } dbg_init_current_thread(de->u.CreateThread.lpStartAddress); break; case EXIT_THREAD_DEBUG_EVENT: WINE_TRACE("%04x:%04x: exit thread (%d)\n", de->dwProcessId, de->dwThreadId, de->u.ExitThread.dwExitCode); if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } /* FIXME: remove break point set on thread startup */ dbg_del_thread(dbg_curr_thread); break; case LOAD_DLL_DEBUG_EVENT: if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } fetch_module_name(de->u.LoadDll.lpImageName, de->u.LoadDll.fUnicode, de->u.LoadDll.lpBaseOfDll, u.buffer, sizeof(u.buffer) / sizeof(WCHAR), FALSE); WINE_TRACE("%04x:%04x: loads DLL %s @%p (%u<%u>)\n", de->dwProcessId, de->dwThreadId, wine_dbgstr_w(u.buffer), de->u.LoadDll.lpBaseOfDll, de->u.LoadDll.dwDebugInfoFileOffset, de->u.LoadDll.nDebugInfoSize); dbg_load_module(dbg_curr_process->handle, de->u.LoadDll.hFile, u.buffer, (DWORD_PTR)de->u.LoadDll.lpBaseOfDll, 0); break_set_xpoints(FALSE); break_check_delayed_bp(); break_set_xpoints(TRUE); if (DBG_IVAR(BreakOnDllLoad)) { dbg_printf("Stopping on DLL %s loading at 0x%08lx\n", dbg_W2A(u.buffer, -1), (unsigned long)de->u.LoadDll.lpBaseOfDll); if (dbg_fetch_context()) cont = 0; } break; case UNLOAD_DLL_DEBUG_EVENT: WINE_TRACE("%04x:%04x: unload DLL @%p\n", de->dwProcessId, de->dwThreadId, de->u.UnloadDll.lpBaseOfDll); break_delete_xpoints_from_module((unsigned long)de->u.UnloadDll.lpBaseOfDll); SymUnloadModule(dbg_curr_process->handle, (unsigned long)de->u.UnloadDll.lpBaseOfDll); break; case OUTPUT_DEBUG_STRING_EVENT: if (dbg_curr_thread == NULL) { WINE_ERR("Unknown thread\n"); break; } memory_get_string(dbg_curr_process, de->u.DebugString.lpDebugStringData, TRUE, de->u.DebugString.fUnicode, u.bufferA, sizeof(u.bufferA)); WINE_TRACE("%04x:%04x: output debug string (%s)\n", de->dwProcessId, de->dwThreadId, u.bufferA); break; case RIP_EVENT: WINE_TRACE("%04x:%04x: rip error=%u type=%u\n", de->dwProcessId, de->dwThreadId, de->u.RipInfo.dwError, de->u.RipInfo.dwType); break; default: WINE_TRACE("%04x:%04x: unknown event (%x)\n", de->dwProcessId, de->dwThreadId, de->dwDebugEventCode); } if (!cont) return TRUE; /* stop execution */ ContinueDebugEvent(de->dwProcessId, de->dwThreadId, cont); return FALSE; /* continue execution */ }
static void print_typed_basic(const struct dbg_lvalue* lvalue) { LONGLONG val_int; void* val_ptr; long double val_real; DWORD64 size64; DWORD tag, size, count, bt; struct dbg_type type = lvalue->type; struct dbg_type sub_type; if (!types_get_real_type(&type, &tag)) return; switch (tag) { case SymTagBaseType: if (!types_get_info(&type, TI_GET_LENGTH, &size64) || !types_get_info(&type, TI_GET_BASETYPE, &bt)) { WINE_ERR("Couldn't get information\n"); RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); } size = (DWORD)size64; switch (bt) { case btInt: if (!be_cpu->fetch_integer(lvalue, size, TRUE, &val_int)) return; dbg_printf("%lld", val_int); break; case btUInt: if (!be_cpu->fetch_integer(lvalue, size, FALSE, &val_int)) return; dbg_printf("%llu", val_int); break; case btFloat: if (!be_cpu->fetch_float(lvalue, size, &val_real)) return; dbg_printf("%Lf", val_real); break; case btChar: if (!be_cpu->fetch_integer(lvalue, size, TRUE, &val_int)) return; /* FIXME: should do the same for a Unicode character (size == 2) */ if (size == 1 && (val_int < 0x20 || val_int > 0x80)) dbg_printf("%d", (int)val_int); else dbg_printf("'%c'", (char)val_int); break; default: WINE_FIXME("Unsupported basetype %lu\n", bt); break; } break; case SymTagPointerType: if (!memory_read_value(lvalue, sizeof(void*), &val_ptr)) return; sub_type.module = lvalue->type.module; if (!types_get_info(&type, TI_GET_TYPE, &sub_type.id) || sub_type.id == dbg_itype_none) { dbg_printf("Internal symbol error: unable to access memory location %p", val_ptr); break; } if (!types_get_real_type(&sub_type, &tag)) return; if (types_get_info(&sub_type, TI_GET_SYMTAG, &tag) && tag == SymTagBaseType && types_get_info(&sub_type, TI_GET_BASETYPE, &bt) && bt == btChar && types_get_info(&sub_type, TI_GET_LENGTH, &size64)) { char buffer[1024]; if (!val_ptr) dbg_printf("0x0"); else if (memory_get_string(dbg_curr_process, val_ptr, lvalue->cookie == DLV_TARGET, size64 == 2, buffer, sizeof(buffer))) dbg_printf("\"%s\"", buffer); else dbg_printf("*** invalid address %p ***", val_ptr); } else dbg_printf("%p", val_ptr); break; case SymTagArrayType: case SymTagUDT: assert(lvalue->cookie == DLV_TARGET); if (!memory_read_value(lvalue, sizeof(val_ptr), &val_ptr)) return; dbg_printf("%p", val_ptr); break; case SymTagEnum: { BOOL ok = FALSE; assert(lvalue->cookie == DLV_TARGET); /* FIXME: it depends on underlying type for enums * (not supported yet in dbghelp) * Assuming 4 as for an int */ if (!be_cpu->fetch_integer(lvalue, 4, TRUE, &val_int)) return; if (types_get_info(&type, TI_GET_CHILDRENCOUNT, &count)) { char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)]; TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer; WCHAR* ptr; char tmp[256]; VARIANT variant; int i; fcp->Start = 0; while (count) { fcp->Count = min(count, 256); if (types_get_info(&type, TI_FINDCHILDREN, fcp)) { sub_type.module = type.module; for (i = 0; i < min(fcp->Count, count); i++) { sub_type.id = fcp->ChildId[i]; if (!types_get_info(&sub_type, TI_GET_VALUE, &variant)) continue; switch (variant.n1.n2.vt) { case VT_I4: ok = (val_int == variant.n1.n2.n3.lVal); break; default: WINE_FIXME("Unsupported variant type (%u)\n", variant.n1.n2.vt); } if (ok) { ptr = NULL; types_get_info(&sub_type, TI_GET_SYMNAME, &ptr); if (!ptr) continue; WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL); HeapFree(GetProcessHeap(), 0, ptr); dbg_printf("%s", tmp); count = 0; /* so that we'll get away from outter loop */ break; } } } } count -= min(count, 256); fcp->Start += 256; } if (!ok) dbg_printf("%lld", val_int); } break; default: WINE_FIXME("Unsupported tag %lu\n", tag); break; } }
/* each message gets its own thread. this is it. */ static DWORD WINAPI HandlerThread(LPVOID lpvPipeHandle) { RPCSS_NP_MESSAGE msg, vardata_payload_msg; char *c, *vardata = NULL; RPCSS_NP_REPLY reply; DWORD bytesread, written; BOOL success, had_payload = FALSE; HANDLE mypipe; mypipe = (HANDLE) lpvPipeHandle; WINE_TRACE("mypipe: %p\n", mypipe); success = ReadFile( mypipe, /* pipe handle */ (char *) &msg, /* message buffer */ sizeof(RPCSS_NP_MESSAGE), /* message buffer size */ &bytesread, /* receives number of bytes read */ NULL /* not overlapped */ ); if (msg.vardata_payload_size) { had_payload = TRUE; /* this fudge space allows us not to worry about exceeding the buffer space on the last read */ vardata = LocalAlloc(LPTR, (msg.vardata_payload_size) + VARDATA_PAYLOAD_BYTES); if (!vardata) { WINE_ERR("vardata memory allocation failure.\n"); success = FALSE; } else { for ( c = vardata; (c - vardata) < msg.vardata_payload_size; c += VARDATA_PAYLOAD_BYTES) { success = ReadFile( mypipe, (char *) &vardata_payload_msg, sizeof(RPCSS_NP_MESSAGE), &bytesread, NULL ); if ( (!success) || (bytesread != sizeof(RPCSS_NP_MESSAGE)) || (vardata_payload_msg.message_type != RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG) ) { WINE_ERR("vardata payload read failure! (s=%s,br=%d,mt=%u,mt_exp=%u\n", success ? "TRUE" : "FALSE", bytesread, vardata_payload_msg.message_type, RPCSS_NP_MESSAGE_TYPEID_VARDATAPAYLOADMSG); success = FALSE; break; } CopyMemory(c, vardata_payload_msg.message.vardatapayloadmsg.payload, VARDATA_PAYLOAD_BYTES); WINE_TRACE("payload read.\n"); } } } if (success && (bytesread == sizeof(RPCSS_NP_MESSAGE))) { WINE_TRACE("read success.\n"); /* process the message and send a reply, serializing requests. */ EnterCriticalSection(&np_server_cs); WINE_TRACE("processing message.\n"); RPCSS_ServerProcessMessage(&msg, &reply, vardata); LeaveCriticalSection(&np_server_cs); if (had_payload) LocalFree(vardata); WINE_TRACE("message processed, sending reply....\n"); success = WriteFile( mypipe, /* pipe handle */ (char *) &reply, /* reply buffer */ sizeof(RPCSS_NP_REPLY), /* reply buffer size */ &written, /* receives number of bytes written */ NULL /* not overlapped */ ); if ( (!success) || (written != sizeof(RPCSS_NP_REPLY)) ) WINE_WARN("Message reply failed. (success=%d, br=%d)\n", success, written); else WINE_TRACE("Reply sent successfully.\n"); } else WINE_WARN("Message receipt failed.\n"); FlushFileBuffers(mypipe); DisconnectNamedPipe(mypipe); CloseHandle(mypipe); InterlockedDecrement(&srv_thread_count); return 0; }
static DWORD scmdatabase_load_services(struct scmdatabase *db) { DWORD err; int i; for (i = 0; TRUE; i++) { WCHAR szName[MAX_SERVICE_NAME]; struct service_entry *entry; HKEY hServiceKey; err = RegEnumKeyW(db->root_key, i, szName, MAX_SERVICE_NAME); if (err == ERROR_NO_MORE_ITEMS) break; if (err != 0) { WINE_ERR("Error %d reading key %d name - skipping\n", err, i); continue; } err = service_create(szName, &entry); if (err != ERROR_SUCCESS) break; WINE_TRACE("Loading service %s\n", wine_dbgstr_w(szName)); err = RegOpenKeyExW(db->root_key, szName, 0, KEY_READ, &hServiceKey); if (err == ERROR_SUCCESS) { err = load_service_config(hServiceKey, entry); RegCloseKey(hServiceKey); } if (err != ERROR_SUCCESS) { WINE_ERR("Error %d reading registry key for service %s - skipping\n", err, wine_dbgstr_w(szName)); free_service_entry(entry); continue; } if (entry->config.dwServiceType == 0) { /* Maybe an application only wrote some configuration in the service key. Continue silently */ WINE_TRACE("Even the service type not set for service %s - skipping\n", wine_dbgstr_w(szName)); free_service_entry(entry); continue; } if (!validate_service_config(entry)) { WINE_ERR("Invalid configuration of service %s - skipping\n", wine_dbgstr_w(szName)); free_service_entry(entry); continue; } entry->status.dwServiceType = entry->config.dwServiceType; entry->db = db; list_add_tail(&db->services, &entry->entry); } return ERROR_SUCCESS; }
static HANDLE RPCSS_NPConnect(void) { HANDLE the_pipe; DWORD dwmode, wait_result; HANDLE master_mutex = RPCSS_GetMasterMutex(); WINE_TRACE("\n"); while (TRUE) { wait_result = WaitForSingleObject(master_mutex, MASTER_MUTEX_TIMEOUT); switch (wait_result) { case WAIT_ABANDONED: case WAIT_OBJECT_0: break; case WAIT_FAILED: case WAIT_TIMEOUT: default: WINE_ERR("This should never happen: couldn't enter mutex.\n"); return NULL; } /* try to open the client side of the named pipe. */ the_pipe = CreateFileA( NAME_RPCSS_NAMED_PIPE, /* pipe name */ GENERIC_READ | GENERIC_WRITE, /* r/w access */ 0, /* no sharing */ NULL, /* no security attributes */ OPEN_EXISTING, /* open an existing pipe */ 0, /* default attributes */ NULL /* no template file */ ); if (the_pipe != INVALID_HANDLE_VALUE) break; if (GetLastError() != ERROR_PIPE_BUSY) { WINE_WARN("Unable to open named pipe %s (assuming unavailable).\n", wine_dbgstr_a(NAME_RPCSS_NAMED_PIPE)); break; } WINE_WARN("Named pipe busy (will wait)\n"); if (!ReleaseMutex(master_mutex)) WINE_ERR("Failed to release master mutex. Expect deadlock.\n"); /* wait for the named pipe. We are only willing to wait only 5 seconds. It should be available /very/ soon. */ if (! WaitNamedPipeA(NAME_RPCSS_NAMED_PIPE, MASTER_MUTEX_WAITNAMEDPIPE_TIMEOUT)) { WINE_ERR("Named pipe unavailable after waiting. Something is probably wrong.\n"); return NULL; } } if (the_pipe != INVALID_HANDLE_VALUE) { dwmode = PIPE_READMODE_MESSAGE; /* SetNamedPipeHandleState not implemented ATM, but still seems to work somehow. */ if (! SetNamedPipeHandleState(the_pipe, &dwmode, NULL, NULL)) WINE_WARN("Failed to set pipe handle state\n"); } if (!ReleaseMutex(master_mutex)) WINE_ERR("Uh oh, failed to leave the RPC Master Mutex!\n"); return the_pipe; }
/****************************************************************** * types_extract_as_integer * * Given a lvalue, try to get an integral (or pointer/address) value * out of it */ long int types_extract_as_integer(const struct dbg_lvalue* lvalue) { long int rtn; LONGLONG val; DWORD tag, bt; DWORD64 size; struct dbg_type type = lvalue->type; if (!types_get_real_type(&type, &tag)) RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL); if (type.id == dbg_itype_segptr) { return (long int)memory_to_linear_addr(&lvalue->addr); } switch (tag) { case SymTagBaseType: if (!types_get_info(&type, TI_GET_LENGTH, &size) || !types_get_info(&type, TI_GET_BASETYPE, &bt)) { WINE_ERR("Couldn't get information\n"); RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); } if (size > sizeof(rtn)) { WINE_ERR("Size too large (%s)\n", wine_dbgstr_longlong(size)); RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL); } switch (bt) { case btChar: case btInt: if (!be_cpu->fetch_integer(lvalue, (unsigned)size, TRUE, &val)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); rtn = (long)val; break; case btUInt: if (!be_cpu->fetch_integer(lvalue, (unsigned)size, FALSE, &val)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); rtn = (DWORD)(DWORD64)val; break; case btFloat: RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL); } break; case SymTagPointerType: if (!memory_read_value(lvalue, sizeof(void*), &rtn)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break; case SymTagArrayType: case SymTagUDT: assert(lvalue->cookie == DLV_TARGET); if (!memory_read_value(lvalue, sizeof(rtn), &rtn)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break; case SymTagEnum: assert(lvalue->cookie == DLV_TARGET); if (!memory_read_value(lvalue, sizeof(rtn), &rtn)) RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL); break; case SymTagFunctionType: rtn = (unsigned)memory_to_linear_addr(&lvalue->addr); break; default: WINE_FIXME("Unsupported tag %lu\n", tag); RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL); break; } return rtn; }