static HMODULE load_desktop_driver( HWND hwnd ) { static const WCHAR display_device_guid_propW[] = { '_','_','w','i','n','e','_','d','i','s','p','l','a','y','_', 'd','e','v','i','c','e','_','g','u','i','d',0 }; static const WCHAR key_pathW[] = { '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','\\', 'V','i','d','e','o','\\','{',0}; static const WCHAR displayW[] = {'}','\\','0','0','0','0',0}; static const WCHAR driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0}; HMODULE ret = 0; HKEY hkey; DWORD size; WCHAR path[MAX_PATH]; WCHAR key[(sizeof(key_pathW) + sizeof(displayW)) / sizeof(WCHAR) + 40]; UINT guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW )); USER_CheckNotLock(); strcpy( driver_load_error, "The explorer process failed to start." ); /* default error */ if (!guid_atom) { SendMessageW( hwnd, WM_NULL, 0, 0 ); /* wait for the desktop process to be ready */ guid_atom = HandleToULong( GetPropW( hwnd, display_device_guid_propW )); } memcpy( key, key_pathW, sizeof(key_pathW) ); if (!GlobalGetAtomNameW( guid_atom, key + strlenW(key), 40 )) return 0; strcatW( key, displayW ); if (RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey )) return 0; size = sizeof(path); if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size )) { if (!(ret = LoadLibraryW( path ))) ERR( "failed to load %s\n", debugstr_w(path) ); TRACE( "%s %p\n", debugstr_w(path), ret ); } else { size = sizeof(driver_load_error); RegQueryValueExA( hkey, "DriverError", NULL, NULL, (BYTE *)driver_load_error, &size ); } RegCloseKey( hkey ); return ret; }
/*********************************************************************** * NtOpenThread (NTDLL.@) * ZwOpenThread (NTDLL.@) */ NTSTATUS WINAPI NtOpenThread( HANDLE *handle, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, const CLIENT_ID *id ) { NTSTATUS ret; SERVER_START_REQ( open_thread ) { req->tid = HandleToULong(id->UniqueThread); req->access = access; req->attributes = attr ? attr->Attributes : 0; ret = wine_server_call( req ); *handle = wine_server_ptr_handle( reply->handle ); } SERVER_END_REQ; return ret; }
/****************************************************************** * fetch_process_info * * reads system wide process information, and gather from it the threads information * for process of id 'pid' */ static BOOL fetch_process_info(struct dump_context* dc) { ULONG buf_size = 0x1000; NTSTATUS nts; void* pcs_buffer = NULL; if (!(pcs_buffer = HeapAlloc(GetProcessHeap(), 0, buf_size))) return FALSE; for (;;) { nts = NtQuerySystemInformation(SystemProcessInformation, pcs_buffer, buf_size, NULL); if (nts != STATUS_INFO_LENGTH_MISMATCH) break; pcs_buffer = HeapReAlloc(GetProcessHeap(), 0, pcs_buffer, buf_size *= 2); if (!pcs_buffer) return FALSE; } if (nts == STATUS_SUCCESS) { SYSTEM_PROCESS_INFORMATION* spi = pcs_buffer; unsigned i; for (;;) { if (HandleToUlong(spi->UniqueProcessId) == dc->pid) { dc->num_threads = spi->dwThreadCount; dc->threads = HeapAlloc(GetProcessHeap(), 0, dc->num_threads * sizeof(dc->threads[0])); if (!dc->threads) goto failed; for (i = 0; i < dc->num_threads; i++) { dc->threads[i].tid = HandleToULong(spi->ti[i].ClientId.UniqueThread); dc->threads[i].prio_class = spi->ti[i].dwBasePriority; /* FIXME */ dc->threads[i].curr_prio = spi->ti[i].dwCurrentPriority; } HeapFree(GetProcessHeap(), 0, pcs_buffer); return TRUE; } if (!spi->NextEntryOffset) break; spi = (SYSTEM_PROCESS_INFORMATION*)((char*)spi + spi->NextEntryOffset); } } failed: HeapFree(GetProcessHeap(), 0, pcs_buffer); return FALSE; }
/********************************************************************** * GetThreadId [KERNEL32.@] * * Retrieve the identifier of a thread. * * PARAMS * Thread [I] The thread to retrieve the identifier of. * * RETURNS * Success: Identifier of the target thread. * Failure: 0 */ DWORD WINAPI GetThreadId(HANDLE Thread) { THREAD_BASIC_INFORMATION tbi; NTSTATUS status; TRACE("(%p)\n", Thread); status = NtQueryInformationThread(Thread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL); if (status) { SetLastError( RtlNtStatusToDosError(status) ); return 0; } return HandleToULong(tbi.ClientId.UniqueThread); }
static BOOL get_display_device_reg_key(char *key, unsigned len) { static const char display_device_guid_prop[] = "__wine_display_device_guid"; static const char video_path[] = "System\\CurrentControlSet\\Control\\Video\\{"; static const char display0[] = "}\\0000"; ATOM guid_atom; assert(len >= sizeof(video_path) + sizeof(display0) + 40); guid_atom = HandleToULong(GetPropA(GetDesktopWindow(), display_device_guid_prop)); if (!guid_atom) return FALSE; memcpy(key, video_path, sizeof(video_path)); if (!GlobalGetAtomNameA(guid_atom, key + strlen(key), 40)) return FALSE; strcat(key, display0); TRACE("display device key %s\n", wine_dbgstr_a(key)); return TRUE; }
/*************************************************************************** * CreateRemoteThread (KERNEL32.@) * * Creates a thread that runs in the address space of another process * * PARAMS * * RETURNS * Success: Handle to the new thread. * Failure: NULL. Use GetLastError() to find the error cause. * * BUGS * Improper memory allocation: there's no ability to free new_thread_info * in other process. * Bad start address for RtlCreateUserThread because the library * may be loaded at different address in other process. */ HANDLE WINAPI CreateRemoteThread( HANDLE hProcess, SECURITY_ATTRIBUTES *sa, SIZE_T stack, LPTHREAD_START_ROUTINE start, LPVOID param, DWORD flags, LPDWORD id ) { HANDLE handle; CLIENT_ID client_id; NTSTATUS status; SIZE_T stack_reserve = 0, stack_commit = 0; if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack; else stack_commit = stack; status = RtlCreateUserThread( hProcess, NULL, TRUE, NULL, stack_reserve, stack_commit, (PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id ); if (status == STATUS_SUCCESS) { if (id) *id = HandleToULong(client_id.UniqueThread); if (sa && (sa->nLength >= sizeof(*sa)) && sa->bInheritHandle) SetHandleInformation( handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT ); if (!(flags & CREATE_SUSPENDED)) { ULONG ret; if (NtResumeThread( handle, &ret )) { NtClose( handle ); SetLastError( ERROR_NOT_ENOUGH_MEMORY ); handle = 0; } } } else { SetLastError( RtlNtStatusToDosError(status) ); handle = 0; } return handle; }
/*********************************************************************** * GetCurrentThreadId (KERNEL32.@) * * Get the current thread identifier. * * RETURNS * current thread identifier */ DWORD WINAPI GetCurrentThreadId(void) { return HandleToULong(NtCurrentTeb()->ClientId.UniqueThread); }
/*********************************************************************** * GetCurrentProcessId (KERNEL32.@) * * Get the current process identifier. * * RETURNS * current process identifier */ DWORD WINAPI GetCurrentProcessId(void) { return HandleToULong(NtCurrentTeb()->ClientId.UniqueProcess); }
static HANDLE modify_handle(HANDLE handle, DWORD modify) { DWORD tmp = HandleToULong(handle); tmp |= modify; return ULongToHandle(tmp); }
/*********************************************************************** * GetProcessDword (KERNEL.485) * 'Of course you cannot directly access Windows internal structures' */ DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset ) { DWORD x, y; STARTUPINFOW siw; TRACE("(%d, %d)\n", dwProcessID, offset ); if (dwProcessID && dwProcessID != GetCurrentProcessId()) { ERR("%d: process %x not accessible\n", offset, dwProcessID); return 0; } switch ( offset ) { case GPD_APP_COMPAT_FLAGS: return GetAppCompatFlags16(0); case GPD_LOAD_DONE_EVENT: return 0; case GPD_HINSTANCE16: return GetTaskDS16(); case GPD_WINDOWS_VERSION: return GetExeVersion16(); case GPD_THDB: return (DWORD_PTR)NtCurrentTeb() - 0x10 /* FIXME */; case GPD_PDB: return (DWORD_PTR)NtCurrentTeb()->Peb; /* FIXME: truncating a pointer */ case GPD_STARTF_SHELLDATA: /* return stdoutput handle from startupinfo ??? */ GetStartupInfoW(&siw); return HandleToULong(siw.hStdOutput); case GPD_STARTF_HOTKEY: /* return stdinput handle from startupinfo ??? */ GetStartupInfoW(&siw); return HandleToULong(siw.hStdInput); case GPD_STARTF_SHOWWINDOW: GetStartupInfoW(&siw); return siw.wShowWindow; case GPD_STARTF_SIZE: GetStartupInfoW(&siw); x = siw.dwXSize; if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16; y = siw.dwYSize; if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16; return MAKELONG( x, y ); case GPD_STARTF_POSITION: GetStartupInfoW(&siw); x = siw.dwX; if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16; y = siw.dwY; if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16; return MAKELONG( x, y ); case GPD_STARTF_FLAGS: GetStartupInfoW(&siw); return siw.dwFlags; case GPD_PARENT: return 0; case GPD_FLAGS: return GetProcessFlags(0); case GPD_USERDATA: return process_dword; default: ERR("Unknown offset %d\n", offset ); return 0; } }