![]() |
ZenWINX Architecture - Reference Manual - Guides |
|
00001 /* 00002 * ZenWINX - WIndows Native eXtended library. 00003 * Copyright (c) 2007-2010 by Dmitri Arkhangelski (dmitriar@gmail.com). 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00027 #include "ntndk.h" 00028 #include "zenwinx.h" 00029 00030 NTSTATUS (__stdcall *func_RtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation); 00031 00038 void __stdcall winx_sleep(int msec) 00039 { 00040 LARGE_INTEGER Interval; 00041 00042 if(msec != INFINITE){ 00043 /* System time units are 100 nanoseconds. */ 00044 Interval.QuadPart = -((signed long)msec * 10000); 00045 } else { 00046 /* Approximately 292000 years hence */ 00047 Interval.QuadPart = MAX_WAIT_INTERVAL; 00048 } 00049 /* 00050 * The next call is undocumented, therefore 00051 * we are not checking its result. 00052 */ 00053 (void)NtDelayExecution(0/*FALSE*/,&Interval); 00054 } 00055 00071 int __stdcall winx_get_os_version(void) 00072 { 00073 OSVERSIONINFOW ver; 00074 00075 ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); 00076 00077 if(winx_get_proc_address(L"ntdll.dll","RtlGetVersion", 00078 (void *)&func_RtlGetVersion) < 0) return 40; 00079 func_RtlGetVersion(&ver); 00080 return (ver.dwMajorVersion * 10 + ver.dwMinorVersion); 00081 } 00082 00092 int __stdcall winx_get_windows_directory(char *buffer, int length) 00093 { 00094 short buf[MAX_PATH + 1]; 00095 00096 DbgCheck2(buffer,(length > 0),"winx_get_windows_directory",-1); 00097 00098 if(winx_query_env_variable(L"SystemRoot",buf,MAX_PATH) < 0) return (-1); 00099 (void)_snprintf(buffer,length - 1,"\\??\\%ws",buf); 00100 buffer[length - 1] = 0; 00101 return 0; 00102 } 00103 00117 int __stdcall winx_query_symbolic_link(short *name, short *buffer, int length) 00118 { 00119 OBJECT_ATTRIBUTES oa; 00120 UNICODE_STRING uStr; 00121 NTSTATUS Status; 00122 HANDLE hLink; 00123 ULONG size; 00124 00125 DbgCheck3(name,buffer,(length > 0),"winx_query_symbolic_link",-1); 00126 00127 RtlInitUnicodeString(&uStr,name); 00128 InitializeObjectAttributes(&oa,&uStr,OBJ_CASE_INSENSITIVE,NULL,NULL); 00129 Status = NtOpenSymbolicLinkObject(&hLink,SYMBOLIC_LINK_QUERY,&oa); 00130 if(!NT_SUCCESS(Status)){ 00131 DebugPrintEx(Status,"Cannot open symbolic link %ls",name); 00132 return (-1); 00133 } 00134 uStr.Buffer = buffer; 00135 uStr.Length = 0; 00136 uStr.MaximumLength = length * sizeof(short); 00137 size = 0; 00138 Status = NtQuerySymbolicLinkObject(hLink,&uStr,&size); 00139 (void)NtClose(hLink); 00140 if(!NT_SUCCESS(Status)){ 00141 DebugPrintEx(Status,"Cannot query symbolic link %ls",name); 00142 return (-1); 00143 } 00144 buffer[length - 1] = 0; 00145 return 0; 00146 } 00147 00167 int __stdcall winx_set_system_error_mode(unsigned int mode) 00168 { 00169 NTSTATUS Status; 00170 00171 Status = NtSetInformationProcess(NtCurrentProcess(), 00172 ProcessDefaultHardErrorMode, 00173 (PVOID)&mode, 00174 sizeof(int)); 00175 if(!NT_SUCCESS(Status)){ 00176 DebugPrintEx(Status,"Cannot set system error mode %u",mode); 00177 return (-1); 00178 } 00179 return 0; 00180 } 00181 00190 int __stdcall winx_load_driver(short *driver_name) 00191 { 00192 UNICODE_STRING us; 00193 short driver_key[128]; /* enough for any driver registry path */ 00194 NTSTATUS Status; 00195 00196 DbgCheck1(driver_name,"winx_load_driver",-1); 00197 00198 (void)_snwprintf(driver_key,127,L"%ls%ls", 00199 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",driver_name); 00200 driver_key[127] = 0; 00201 RtlInitUnicodeString(&us,driver_key); 00202 Status = NtLoadDriver(&us); 00203 if(!NT_SUCCESS(Status) && Status != STATUS_IMAGE_ALREADY_LOADED){ 00204 DebugPrintEx(Status,"Cannot load %ws driver",driver_name); 00205 return (-1); 00206 } 00207 return 0; 00208 } 00209 00216 int __stdcall winx_unload_driver(short *driver_name) 00217 { 00218 UNICODE_STRING us; 00219 short driver_key[128]; /* enough for any driver registry path */ 00220 NTSTATUS Status; 00221 00222 DbgCheck1(driver_name,"winx_unload_driver",-1); 00223 00224 (void)_snwprintf(driver_key,127,L"%ls%ls", 00225 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",driver_name); 00226 driver_key[127] = 0; 00227 RtlInitUnicodeString(&us,driver_key); 00228 Status = NtUnloadDriver(&us); 00229 if(!NT_SUCCESS(Status)){ 00230 DebugPrintEx(Status,"Cannot unload %ws driver",driver_name); 00231 return (-1); 00232 } 00233 return 0; 00234 } 00235 00243 short * __stdcall winx_get_windows_boot_options(void) 00244 { 00245 UNICODE_STRING us; 00246 OBJECT_ATTRIBUTES oa; 00247 NTSTATUS status; 00248 HANDLE hKey; 00249 KEY_VALUE_PARTIAL_INFORMATION *data; 00250 short *data_buffer = NULL; 00251 DWORD data_size = 0; 00252 DWORD data_size2 = 0; 00253 DWORD data_length; 00254 BOOLEAN empty_value = FALSE; 00255 short *boot_options; 00256 int buffer_size; 00257 00258 /* 1. open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control registry key */ 00259 RtlInitUnicodeString(&us,L"\\Registry\\Machine\\SYSTEM\\" 00260 L"CurrentControlSet\\Control"); 00261 InitializeObjectAttributes(&oa,&us,OBJ_CASE_INSENSITIVE,NULL,NULL); 00262 status = NtOpenKey(&hKey,KEY_QUERY_VALUE,&oa); 00263 if(status != STATUS_SUCCESS){ 00264 DebugPrintEx(status,"Cannot open %ws",us.Buffer); 00265 winx_printf("Cannot open %ls: %x!\n\n",us.Buffer,(UINT)status); 00266 return NULL; 00267 } 00268 00269 /* 2. read SystemStartOptions value */ 00270 RtlInitUnicodeString(&us,L"SystemStartOptions"); 00271 status = NtQueryValueKey(hKey,&us,KeyValuePartialInformation, 00272 NULL,0,&data_size); 00273 if(status != STATUS_BUFFER_TOO_SMALL){ 00274 DebugPrintEx(status,"Cannot query SystemStartOptions value size"); 00275 winx_printf("Cannot query SystemStartOptions value size: %x!\n\n",(UINT)status); 00276 return NULL; 00277 } 00278 data_size += sizeof(short); 00279 data = winx_heap_alloc(data_size); 00280 if(data == NULL){ 00281 DebugPrint("Cannot allocate %u bytes of memory for winx_get_windows_boot_options()!", 00282 data_size); 00283 winx_printf("Cannot allocate %u bytes of memory for winx_get_windows_boot_options()!\n\n", 00284 data_size); 00285 return NULL; 00286 } 00287 00288 RtlZeroMemory(data,data_size); 00289 status = NtQueryValueKey(hKey,&us,KeyValuePartialInformation, 00290 data,data_size,&data_size2); 00291 if(status != STATUS_SUCCESS){ 00292 DebugPrintEx(status,"Cannot query SystemStartOptions value"); 00293 winx_printf("Cannot query SystemStartOptions value: %x!\n\n",(UINT)status); 00294 winx_heap_free(data); 00295 return NULL; 00296 } 00297 data_buffer = (short *)(data->Data); 00298 data_length = data->DataLength >> 1; 00299 if(data_length == 0) empty_value = TRUE; 00300 00301 if(!empty_value){ 00302 data_buffer[data_length - 1] = 0; 00303 buffer_size = data_length * sizeof(short); 00304 } else { 00305 buffer_size = 1 * sizeof(short); 00306 } 00307 00308 boot_options = winx_heap_alloc(buffer_size); 00309 if(!boot_options){ 00310 DebugPrint("Cannot allocate %u bytes of memory for winx_get_windows_boot_options()!", 00311 buffer_size); 00312 winx_printf("Cannot allocate %u bytes of memory for winx_get_windows_boot_options()!\n\n", 00313 buffer_size); 00314 winx_heap_free(data); 00315 return NULL; 00316 } 00317 00318 if(!empty_value){ 00319 memcpy((void *)boot_options,(void *)data_buffer,buffer_size); 00320 DebugPrint("%ls - %u\n\n",data_buffer,data_size); 00321 //winx_printf("%ls - %u\n\n",data_buffer,data_size); 00322 } else { 00323 boot_options[0] = 0; 00324 } 00325 00326 winx_heap_free(data); 00327 return boot_options; 00328 } 00329 00336 int __stdcall winx_windows_in_safe_mode(void) 00337 { 00338 short *boot_options; 00339 int safe_boot = 0; 00340 00341 boot_options = winx_get_windows_boot_options(); 00342 if(!boot_options) return (-1); 00343 00344 /* search for SAFEBOOT */ 00345 _wcsupr(boot_options); 00346 if(wcsstr(boot_options,L"SAFEBOOT")) safe_boot = 1; 00347 winx_heap_free(boot_options); 00348 00349 return safe_boot; 00350 }