Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendosdev.c
Go to the documentation of this file.
00001 /* $Id: dosdev.c 54326 2011-11-07 00:18:13Z ion $ 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS system libraries 00005 * FILE: lib/kernel32/file/dosdev.c 00006 * PURPOSE: Dos device functions 00007 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) 00008 * UPDATE HISTORY: 00009 * Created 01/11/98 00010 */ 00011 00012 /* INCLUDES ******************************************************************/ 00013 00014 #include <k32.h> 00015 #define NDEBUG 00016 #include <debug.h> 00017 #include <dbt.h> 00018 DEBUG_CHANNEL(kernel32file); 00019 00020 /* FUNCTIONS *****************************************************************/ 00021 00022 /* 00023 * @implemented 00024 */ 00025 BOOL 00026 WINAPI 00027 DefineDosDeviceA( 00028 DWORD dwFlags, 00029 LPCSTR lpDeviceName, 00030 LPCSTR lpTargetPath 00031 ) 00032 { 00033 UNICODE_STRING DeviceNameU = {0}; 00034 UNICODE_STRING TargetPathU = {0}; 00035 BOOL Result; 00036 00037 if (lpDeviceName && 00038 ! RtlCreateUnicodeStringFromAsciiz(&DeviceNameU, 00039 (LPSTR)lpDeviceName)) 00040 { 00041 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00042 return 0; 00043 } 00044 00045 if (lpTargetPath && 00046 ! RtlCreateUnicodeStringFromAsciiz(&TargetPathU, 00047 (LPSTR)lpTargetPath)) 00048 { 00049 if (DeviceNameU.Buffer) 00050 { 00051 RtlFreeHeap(RtlGetProcessHeap (), 00052 0, 00053 DeviceNameU.Buffer); 00054 } 00055 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00056 return 0; 00057 } 00058 00059 Result = DefineDosDeviceW(dwFlags, 00060 DeviceNameU.Buffer, 00061 TargetPathU.Buffer); 00062 00063 if (TargetPathU.Buffer) 00064 { 00065 RtlFreeHeap(RtlGetProcessHeap (), 00066 0, 00067 TargetPathU.Buffer); 00068 } 00069 00070 if (DeviceNameU.Buffer) 00071 { 00072 RtlFreeHeap(RtlGetProcessHeap (), 00073 0, 00074 DeviceNameU.Buffer); 00075 } 00076 return Result; 00077 } 00078 00079 00080 /* 00081 * @implemented 00082 */ 00083 BOOL 00084 WINAPI 00085 DefineDosDeviceW( 00086 DWORD dwFlags, 00087 LPCWSTR lpDeviceName, 00088 LPCWSTR lpTargetPath 00089 ) 00090 { 00091 ULONG ArgumentCount; 00092 ULONG BufferSize; 00093 PCSR_CAPTURE_BUFFER CaptureBuffer; 00094 CSR_API_MESSAGE Request; 00095 NTSTATUS Status; 00096 UNICODE_STRING NtTargetPathU; 00097 UNICODE_STRING DeviceNameU; 00098 UNICODE_STRING DeviceUpcaseNameU; 00099 HANDLE hUser32; 00100 DEV_BROADCAST_VOLUME dbcv; 00101 BOOL Result = TRUE; 00102 DWORD dwRecipients; 00103 typedef long (WINAPI *BSM_type)(DWORD,LPDWORD,UINT,WPARAM,LPARAM); 00104 BSM_type BSM_ptr; 00105 00106 if ( (dwFlags & 0xFFFFFFF0) || 00107 ((dwFlags & DDD_EXACT_MATCH_ON_REMOVE) && 00108 ! (dwFlags & DDD_REMOVE_DEFINITION)) ) 00109 { 00110 SetLastError(ERROR_INVALID_PARAMETER); 00111 return FALSE; 00112 } 00113 00114 ArgumentCount = 1; 00115 BufferSize = 0; 00116 if (! lpTargetPath) 00117 { 00118 RtlInitUnicodeString(&NtTargetPathU, 00119 NULL); 00120 } 00121 else 00122 { 00123 if (dwFlags & DDD_RAW_TARGET_PATH) 00124 { 00125 RtlInitUnicodeString(&NtTargetPathU, 00126 lpTargetPath); 00127 } 00128 else 00129 { 00130 if (! RtlDosPathNameToNtPathName_U(lpTargetPath, 00131 &NtTargetPathU, 00132 0, 00133 0)) 00134 { 00135 WARN("RtlDosPathNameToNtPathName_U() failed\n"); 00136 BaseSetLastNTError(STATUS_OBJECT_NAME_INVALID); 00137 return FALSE; 00138 } 00139 } 00140 ArgumentCount = 2; 00141 BufferSize += NtTargetPathU.Length; 00142 } 00143 00144 RtlInitUnicodeString(&DeviceNameU, 00145 lpDeviceName); 00146 RtlUpcaseUnicodeString(&DeviceUpcaseNameU, 00147 &DeviceNameU, 00148 TRUE); 00149 BufferSize += DeviceUpcaseNameU.Length; 00150 00151 CaptureBuffer = CsrAllocateCaptureBuffer(ArgumentCount, 00152 BufferSize); 00153 if (! CaptureBuffer) 00154 { 00155 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00156 Result = FALSE; 00157 } 00158 else 00159 { 00160 Request.Data.DefineDosDeviceRequest.dwFlags = dwFlags; 00161 00162 CsrCaptureMessageBuffer(CaptureBuffer, 00163 (PVOID)DeviceUpcaseNameU.Buffer, 00164 DeviceUpcaseNameU.Length, 00165 (PVOID*)&Request.Data.DefineDosDeviceRequest.DeviceName.Buffer); 00166 00167 Request.Data.DefineDosDeviceRequest.DeviceName.Length = 00168 DeviceUpcaseNameU.Length; 00169 Request.Data.DefineDosDeviceRequest.DeviceName.MaximumLength = 00170 DeviceUpcaseNameU.Length; 00171 00172 if (NtTargetPathU.Buffer) 00173 { 00174 CsrCaptureMessageBuffer(CaptureBuffer, 00175 (PVOID)NtTargetPathU.Buffer, 00176 NtTargetPathU.Length, 00177 (PVOID*)&Request.Data.DefineDosDeviceRequest.TargetName.Buffer); 00178 } 00179 Request.Data.DefineDosDeviceRequest.TargetName.Length = 00180 NtTargetPathU.Length; 00181 Request.Data.DefineDosDeviceRequest.TargetName.MaximumLength = 00182 NtTargetPathU.Length; 00183 00184 Status = CsrClientCallServer(&Request, 00185 CaptureBuffer, 00186 MAKE_CSR_API(DEFINE_DOS_DEVICE, CSR_CONSOLE), 00187 sizeof(CSR_API_MESSAGE)); 00188 CsrFreeCaptureBuffer(CaptureBuffer); 00189 00190 if (! NT_SUCCESS(Status) || 00191 ! NT_SUCCESS(Status = Request.Status)) 00192 { 00193 WARN("CsrClientCallServer() failed (Status %lx)\n", 00194 Status); 00195 BaseSetLastNTError(Status); 00196 Result = FALSE; 00197 } 00198 else 00199 { 00200 if (! (dwFlags & DDD_NO_BROADCAST_SYSTEM) && 00201 DeviceUpcaseNameU.Length == 2 * sizeof(WCHAR) && 00202 DeviceUpcaseNameU.Buffer[1] == L':' && 00203 ( (DeviceUpcaseNameU.Buffer[0] - L'A') < 26 )) 00204 { 00205 hUser32 = LoadLibraryA("user32.dll"); 00206 if (hUser32) 00207 { 00208 BSM_ptr = (BSM_type) 00209 GetProcAddress(hUser32, "BroadcastSystemMessageW"); 00210 if (BSM_ptr) 00211 { 00212 dwRecipients = BSM_APPLICATIONS; 00213 dbcv.dbcv_size = sizeof(DEV_BROADCAST_VOLUME); 00214 dbcv.dbcv_devicetype = DBT_DEVTYP_VOLUME; 00215 dbcv.dbcv_reserved = 0; 00216 dbcv.dbcv_unitmask |= 00217 (1 << (DeviceUpcaseNameU.Buffer[0] - L'A')); 00218 dbcv.dbcv_flags = DBTF_NET; 00219 (void) BSM_ptr(BSF_SENDNOTIFYMESSAGE | BSF_FLUSHDISK, 00220 &dwRecipients, 00221 WM_DEVICECHANGE, 00222 (WPARAM)DBT_DEVICEARRIVAL, 00223 (LPARAM)&dbcv); 00224 } 00225 FreeLibrary(hUser32); 00226 } 00227 } 00228 } 00229 } 00230 00231 if (NtTargetPathU.Buffer) 00232 { 00233 RtlFreeHeap(RtlGetProcessHeap(), 00234 0, 00235 NtTargetPathU.Buffer); 00236 } 00237 RtlFreeUnicodeString(&DeviceUpcaseNameU); 00238 return Result; 00239 } 00240 00241 00242 /* 00243 * @implemented 00244 */ 00245 DWORD 00246 WINAPI 00247 QueryDosDeviceA( 00248 LPCSTR lpDeviceName, 00249 LPSTR lpTargetPath, 00250 DWORD ucchMax 00251 ) 00252 { 00253 UNICODE_STRING DeviceNameU; 00254 UNICODE_STRING TargetPathU; 00255 ANSI_STRING TargetPathA; 00256 DWORD Length; 00257 DWORD CurrentLength; 00258 PWCHAR Buffer; 00259 00260 if (lpDeviceName) 00261 { 00262 if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU, 00263 (LPSTR)lpDeviceName)) 00264 { 00265 SetLastError (ERROR_NOT_ENOUGH_MEMORY); 00266 return 0; 00267 } 00268 } 00269 Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 00270 0, 00271 ucchMax * sizeof(WCHAR)); 00272 if (Buffer == NULL) 00273 { 00274 if (lpDeviceName) 00275 { 00276 RtlFreeHeap (RtlGetProcessHeap (), 00277 0, 00278 DeviceNameU.Buffer); 00279 } 00280 SetLastError (ERROR_NOT_ENOUGH_MEMORY); 00281 return 0; 00282 } 00283 00284 Length = QueryDosDeviceW (lpDeviceName ? DeviceNameU.Buffer : NULL, 00285 Buffer, 00286 ucchMax); 00287 if (Length != 0) 00288 { 00289 TargetPathA.Buffer = lpTargetPath; 00290 TargetPathU.Buffer = Buffer; 00291 ucchMax = Length; 00292 00293 while (ucchMax) 00294 { 00295 CurrentLength = min (ucchMax, MAXUSHORT / 2); 00296 TargetPathU.MaximumLength = TargetPathU.Length = (USHORT)CurrentLength * sizeof(WCHAR); 00297 00298 TargetPathA.Length = 0; 00299 TargetPathA.MaximumLength = (USHORT)CurrentLength; 00300 00301 RtlUnicodeStringToAnsiString (&TargetPathA, 00302 &TargetPathU, 00303 FALSE); 00304 ucchMax -= CurrentLength; 00305 TargetPathA.Buffer += TargetPathA.Length; 00306 TargetPathU.Buffer += TargetPathU.Length / sizeof(WCHAR); 00307 } 00308 } 00309 00310 RtlFreeHeap (RtlGetProcessHeap (), 00311 0, 00312 Buffer); 00313 if (lpDeviceName) 00314 { 00315 RtlFreeHeap (RtlGetProcessHeap (), 00316 0, 00317 DeviceNameU.Buffer); 00318 } 00319 return Length; 00320 } 00321 00322 00323 /* 00324 * @implemented 00325 */ 00326 DWORD 00327 WINAPI 00328 QueryDosDeviceW( 00329 LPCWSTR lpDeviceName, 00330 LPWSTR lpTargetPath, 00331 DWORD ucchMax 00332 ) 00333 { 00334 POBJECT_DIRECTORY_INFORMATION DirInfo; 00335 OBJECT_ATTRIBUTES ObjectAttributes; 00336 UNICODE_STRING UnicodeString; 00337 HANDLE DirectoryHandle; 00338 HANDLE DeviceHandle; 00339 ULONG ReturnLength; 00340 ULONG NameLength; 00341 ULONG Length; 00342 ULONG Context; 00343 BOOLEAN RestartScan; 00344 NTSTATUS Status; 00345 UCHAR Buffer[512]; 00346 PWSTR Ptr; 00347 00348 /* Open the '\??' directory */ 00349 RtlInitUnicodeString (&UnicodeString, 00350 L"\\??"); 00351 InitializeObjectAttributes (&ObjectAttributes, 00352 &UnicodeString, 00353 OBJ_CASE_INSENSITIVE, 00354 NULL, 00355 NULL); 00356 Status = NtOpenDirectoryObject (&DirectoryHandle, 00357 DIRECTORY_QUERY, 00358 &ObjectAttributes); 00359 if (!NT_SUCCESS (Status)) 00360 { 00361 WARN ("NtOpenDirectoryObject() failed (Status %lx)\n", Status); 00362 BaseSetLastNTError (Status); 00363 return 0; 00364 } 00365 00366 Length = 0; 00367 00368 if (lpDeviceName != NULL) 00369 { 00370 /* Open the lpDeviceName link object */ 00371 RtlInitUnicodeString (&UnicodeString, 00372 (PWSTR)lpDeviceName); 00373 InitializeObjectAttributes (&ObjectAttributes, 00374 &UnicodeString, 00375 OBJ_CASE_INSENSITIVE, 00376 DirectoryHandle, 00377 NULL); 00378 Status = NtOpenSymbolicLinkObject (&DeviceHandle, 00379 SYMBOLIC_LINK_QUERY, 00380 &ObjectAttributes); 00381 if (!NT_SUCCESS (Status)) 00382 { 00383 WARN ("NtOpenSymbolicLinkObject() failed (Status %lx)\n", Status); 00384 NtClose (DirectoryHandle); 00385 BaseSetLastNTError (Status); 00386 return 0; 00387 } 00388 00389 /* Query link target */ 00390 UnicodeString.Length = 0; 00391 UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR); 00392 UnicodeString.Buffer = lpTargetPath; 00393 00394 ReturnLength = 0; 00395 Status = NtQuerySymbolicLinkObject (DeviceHandle, 00396 &UnicodeString, 00397 &ReturnLength); 00398 NtClose (DeviceHandle); 00399 NtClose (DirectoryHandle); 00400 if (!NT_SUCCESS (Status)) 00401 { 00402 WARN ("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status); 00403 BaseSetLastNTError (Status); 00404 return 0; 00405 } 00406 00407 TRACE ("ReturnLength: %lu\n", ReturnLength); 00408 TRACE ("TargetLength: %hu\n", UnicodeString.Length); 00409 TRACE ("Target: '%wZ'\n", &UnicodeString); 00410 00411 Length = UnicodeString.Length / sizeof(WCHAR); 00412 if (Length < ucchMax) 00413 { 00414 /* Append null-charcter */ 00415 lpTargetPath[Length] = UNICODE_NULL; 00416 Length++; 00417 } 00418 else 00419 { 00420 TRACE ("Buffer is too small\n"); 00421 BaseSetLastNTError (STATUS_BUFFER_TOO_SMALL); 00422 return 0; 00423 } 00424 } 00425 else 00426 { 00427 RestartScan = TRUE; 00428 Context = 0; 00429 Ptr = lpTargetPath; 00430 DirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer; 00431 00432 while (TRUE) 00433 { 00434 Status = NtQueryDirectoryObject (DirectoryHandle, 00435 Buffer, 00436 sizeof (Buffer), 00437 TRUE, 00438 RestartScan, 00439 &Context, 00440 &ReturnLength); 00441 if (!NT_SUCCESS(Status)) 00442 { 00443 if (Status == STATUS_NO_MORE_ENTRIES) 00444 { 00445 /* Terminate the buffer */ 00446 *Ptr = UNICODE_NULL; 00447 Length++; 00448 00449 Status = STATUS_SUCCESS; 00450 } 00451 else 00452 { 00453 Length = 0; 00454 } 00455 BaseSetLastNTError (Status); 00456 break; 00457 } 00458 00459 if (!wcscmp (DirInfo->TypeName.Buffer, L"SymbolicLink")) 00460 { 00461 TRACE ("Name: '%wZ'\n", &DirInfo->Name); 00462 00463 NameLength = DirInfo->Name.Length / sizeof(WCHAR); 00464 if (Length + NameLength + 1 >= ucchMax) 00465 { 00466 Length = 0; 00467 BaseSetLastNTError (STATUS_BUFFER_TOO_SMALL); 00468 break; 00469 } 00470 00471 memcpy (Ptr, 00472 DirInfo->Name.Buffer, 00473 DirInfo->Name.Length); 00474 Ptr += NameLength; 00475 Length += NameLength; 00476 *Ptr = UNICODE_NULL; 00477 Ptr++; 00478 Length++; 00479 } 00480 00481 RestartScan = FALSE; 00482 } 00483 00484 NtClose (DirectoryHandle); 00485 } 00486 00487 return Length; 00488 } 00489 00490 /* EOF */ Generated on Sat May 26 2012 04:22:56 for ReactOS by
1.7.6.1
|