ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dosdev.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.