Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

434 lines
11 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. object.c
  5. Abstract:
  6. Resource DLL for disks.
  7. Author:
  8. Rod Gamache (rodga) 18-Dec-1995
  9. Revision History:
  10. --*/
  11. #include "ntos.h"
  12. #include "zwapi.h"
  13. #include "windef.h"
  14. #include "stdio.h"
  15. #include "stdlib.h"
  16. #include "clusdskp.h"
  17. extern POBJECT_TYPE IoDeviceObjectType;
  18. #if 0
  19. #define ATTR_DIR 0x00000001
  20. #define ATTR_DEVICE 0x00000002
  21. #define ATTR_FILE 0x00000004
  22. #define ATTR_SYMLINK 0x00000008
  23. #define DIRECTORYTYPE L"Directory"
  24. #define DEVICETYPE L"Device"
  25. #define FILETYPE L"File"
  26. #define SYMLINKTYPE L"SymbolicLink"
  27. #endif
  28. #ifdef ALLOC_PRAGMA
  29. //#pragma alloc_text(INIT, GetSymbolicLink)
  30. #endif // ALLOC_PRAGMA
  31. /* Converts the type-name into an attribute value */
  32. #if 0
  33. LONG
  34. CalcAttributes(
  35. PUNICODE_STRING Type
  36. )
  37. {
  38. UNICODE_STRING TypeName;
  39. RtlInitUnicodeString(&TypeName, DIRECTORYTYPE);
  40. if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
  41. return ATTR_DIR;
  42. }
  43. RtlInitUnicodeString(&TypeName, DEVICETYPE);
  44. if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
  45. return ATTR_DEVICE;
  46. }
  47. RtlInitUnicodeString(&TypeName, FILETYPE);
  48. if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
  49. return ATTR_FILE;
  50. }
  51. RtlInitUnicodeString(&TypeName, SYMLINKTYPE);
  52. if (RtlEqualString((PSTRING)Type, (PSTRING)&TypeName, TRUE)) {
  53. return ATTR_SYMLINK;
  54. }
  55. return(0);
  56. } // CalcAttributes
  57. #endif
  58. VOID
  59. GetSymbolicLink(
  60. IN PWCHAR RootName,
  61. IN OUT PWCHAR ObjectName // Assume this points at a MAX_PATH len buffer
  62. )
  63. {
  64. NTSTATUS Status;
  65. OBJECT_ATTRIBUTES ObjectAttributes;
  66. HANDLE LinkHandle;
  67. WCHAR UnicodeBuffer[MAX_PATH];
  68. WCHAR Buffer[MAX_PATH];
  69. UNICODE_STRING UnicodeString;
  70. ULONG rootLen;
  71. ULONG objLen;
  72. rootLen = wcslen(RootName);
  73. objLen = wcslen(ObjectName);
  74. if ( (rootLen + objLen + 1) > ( sizeof(UnicodeBuffer)/sizeof(WCHAR) ) ) {
  75. *ObjectName = '\0';
  76. return;
  77. }
  78. RtlZeroMemory( Buffer, sizeof(Buffer) );
  79. wcsncpy( Buffer, RootName, rootLen );
  80. wcsncat( Buffer, ObjectName, objLen );
  81. //
  82. // Make the output buffer empty in case we fail.
  83. //
  84. *ObjectName = '\0';
  85. RtlInitUnicodeString(&UnicodeString, Buffer);
  86. InitializeObjectAttributes(&ObjectAttributes,
  87. &UnicodeString,
  88. OBJ_CASE_INSENSITIVE,
  89. NULL,
  90. NULL
  91. );
  92. // Open the given symbolic link object
  93. Status = ZwOpenSymbolicLinkObject(&LinkHandle,
  94. GENERIC_READ,
  95. &ObjectAttributes);
  96. if (!NT_SUCCESS(Status)) {
  97. ClusDiskPrint((1,
  98. "[ClusDisk] GetSymbolicLink: ZwOpenSymbolicLink "
  99. "failed, status = %08X., Name = [%ws]\n",
  100. Status, UnicodeString.Buffer));
  101. return;
  102. }
  103. // Go get the target of the symbolic link
  104. UnicodeString.Length = 0;
  105. UnicodeString.Buffer = ObjectName;
  106. UnicodeString.MaximumLength = (USHORT)(MAX_PATH);
  107. Status = ZwQuerySymbolicLinkObject(LinkHandle, &UnicodeString, NULL);
  108. ZwClose(LinkHandle);
  109. if (!NT_SUCCESS(Status)) {
  110. ClusDiskPrint((1,
  111. "[ClusDisk] GetSymbolicLink: ZwQuerySymbolicLink failed, status = %08X.\n",
  112. Status));
  113. return;
  114. }
  115. // Add NULL terminator
  116. UnicodeString.Buffer[UnicodeString.Length/sizeof(WCHAR)] = '\0';
  117. return;
  118. } // GetSymbolicLink
  119. static WCHAR wszDosDevices[] = L"\\DosDevices\\A:";
  120. NTSTATUS
  121. GetDriveLetterFromObjectDir(
  122. IN LPWSTR InputDeviceName,
  123. OUT PUCHAR Letter
  124. )
  125. {
  126. UNICODE_STRING LinkName;
  127. UNICODE_STRING DeviceName;
  128. UNICODE_STRING UniDeviceName;
  129. OBJECT_ATTRIBUTES Obja;
  130. HANDLE LinkHandle;
  131. NTSTATUS Status;
  132. ULONG i;
  133. PWCHAR p;
  134. WCHAR DeviceNameBuffer[MAXIMUM_FILENAME_LENGTH];
  135. RtlInitUnicodeString( &UniDeviceName, InputDeviceName );
  136. RtlInitUnicodeString(&LinkName,wszDosDevices);
  137. p = (PWCHAR)LinkName.Buffer;
  138. p = p+12;
  139. for ( i=0; i<26; i++ ) {
  140. *p = (WCHAR)'A' + (WCHAR)i;
  141. InitializeObjectAttributes(
  142. &Obja,
  143. &LinkName,
  144. OBJ_CASE_INSENSITIVE,
  145. NULL,
  146. NULL
  147. );
  148. Status = ZwOpenSymbolicLinkObject(
  149. &LinkHandle,
  150. SYMBOLIC_LINK_QUERY,
  151. &Obja
  152. );
  153. if (NT_SUCCESS( Status )) {
  154. //
  155. // Open succeeded, Now get the link value
  156. //
  157. DeviceName.Length = 0;
  158. DeviceName.MaximumLength = sizeof(DeviceNameBuffer);
  159. DeviceName.Buffer = DeviceNameBuffer;
  160. Status = ZwQuerySymbolicLinkObject(
  161. LinkHandle,
  162. &DeviceName,
  163. NULL
  164. );
  165. ZwClose(LinkHandle);
  166. if ( NT_SUCCESS(Status) ) {
  167. if ( RtlEqualUnicodeString(&UniDeviceName,&DeviceName,TRUE) ) {
  168. *Letter = (UCHAR)('A' + i);
  169. return(STATUS_SUCCESS);
  170. }
  171. }
  172. }
  173. }
  174. return(STATUS_NO_SUCH_FILE);
  175. } // GetDriveLetterFromObjectDir
  176. #if 0
  177. PDEVICE_OBJECT
  178. GetDeviceObject(
  179. IN LPWSTR lpwstrDirectory,
  180. IN LPWSTR lpwstrObject,
  181. IN LPWSTR lpwstrType
  182. )
  183. /*++
  184. Routine Description:
  185. Find the device object given the directory, name and type.
  186. Arguments:
  187. Directory - the directory name for the object.
  188. Object - the object name.
  189. Type - the object type.
  190. Return Value:
  191. non-zero pointer to the device object
  192. NULL on failure
  193. --*/
  194. {
  195. #define BUFFER_SIZE 2048
  196. NTSTATUS Status;
  197. HANDLE DirectoryHandle;
  198. HANDLE ObjectHandle = NULL;
  199. ULONG Context = 0;
  200. ULONG ReturnedLength;
  201. CHAR Buffer[BUFFER_SIZE];
  202. UNICODE_STRING ObjectName;
  203. UNICODE_STRING ObjectType;
  204. UNICODE_STRING DirectoryName;
  205. OBJECT_ATTRIBUTES Attributes;
  206. IO_STATUS_BLOCK IoStatusBlock;
  207. POBJECT_DIRECTORY_INFORMATION DirInfo;
  208. BOOL NotFound;
  209. UNICODE_STRING TypeName;
  210. //
  211. // Initialize strings
  212. //
  213. RtlInitUnicodeString( &ObjectType, lpwstrType );
  214. RtlInitUnicodeString( &ObjectName, lpwstrObject );
  215. RtlInitUnicodeString( &DirectoryName, lpwstrDirectory );
  216. InitializeObjectAttributes( &Attributes,
  217. &DirectoryName,
  218. OBJ_CASE_INSENSITIVE,
  219. NULL,
  220. NULL );
  221. if (!NT_SUCCESS( Status = ZwOpenDirectoryObject( &DirectoryHandle,
  222. STANDARD_RIGHTS_READ |
  223. DIRECTORY_QUERY |
  224. DIRECTORY_TRAVERSE,
  225. &Attributes ) )) {
  226. if (Status == STATUS_OBJECT_TYPE_MISMATCH) {
  227. ClusDiskPrint((
  228. 1,
  229. "ClusDisk: OpenObject, <%wZ> is not a valid Object Directory Object name\n",
  230. &DirectoryName ));
  231. } else {
  232. ClusDiskPrint((
  233. 1,
  234. "ClusDisk: OpenObject, failed to open directory, status = 0x%lx\n\r", Status ));
  235. }
  236. return NULL;
  237. }
  238. //
  239. // Query the entire directory in one sweep
  240. //
  241. NotFound = TRUE;
  242. for (Status = ZwQueryDirectoryObject( DirectoryHandle,
  243. Buffer,
  244. sizeof(Buffer),
  245. // LATER FALSE,
  246. TRUE, // one entry at a time for now
  247. TRUE,
  248. &Context,
  249. &ReturnedLength );
  250. NotFound;
  251. Status = ZwQueryDirectoryObject( DirectoryHandle,
  252. Buffer,
  253. sizeof(Buffer),
  254. // LATER FALSE,
  255. TRUE, // one entry at a time for now
  256. FALSE,
  257. &Context,
  258. &ReturnedLength ) ) {
  259. //
  260. // Check the status of the operation.
  261. //
  262. if ( !NT_SUCCESS(Status) ) {
  263. break;
  264. }
  265. //
  266. // For every record in the buffer get the symbolic link and
  267. // compare the name of the symbolic link with the one we're
  268. // looking for.
  269. //
  270. //
  271. // Point to the first record in the buffer, we are guaranteed to have
  272. // one otherwise Status would have been No More Files
  273. //
  274. DirInfo = (POBJECT_DIRECTORY_INFORMATION)Buffer;
  275. while ( DirInfo->Name.Length != 0 ) {
  276. ClusDiskPrint((
  277. 1,
  278. "ClusDisk: Found object <%wZ>, Type <%wZ>\n",
  279. &(DirInfo->Name),
  280. &(DirInfo->TypeName) ));
  281. if (RtlEqualUnicodeString(&ObjectName, &DirInfo->Name, TRUE) &&
  282. RtlEqualUnicodeString(&ObjectType, &DirInfo->TypeName, TRUE)) {
  283. NotFound = FALSE;
  284. break;
  285. }
  286. DirInfo++;
  287. } // while
  288. } // for
  289. ZwClose(DirectoryHandle);
  290. if ( NotFound ) {
  291. return(NULL);
  292. }
  293. InitializeObjectAttributes( &Attributes,
  294. &ObjectName,
  295. OBJ_CASE_INSENSITIVE,
  296. NULL,
  297. NULL );
  298. Status = ZwOpenSymbolicLinkObject( &ObjectHandle,
  299. SYMBOLIC_LINK_ALL_ACCESS,
  300. &Attributes );
  301. return(NULL);
  302. #if 0
  303. // We now have the type of the object in ObjectType
  304. // We still have the full object name in lpstrObject
  305. // Use the appropriate open routine to get a handle
  306. sprintf( Buffer, "\\\\.\\%s", AnsiString.Buffer );
  307. RtlInitAnsiString( &AnsiString, Buffer );
  308. Status = RtlAnsiStringToUnicodeString(&ObjectName, &AnsiString, FALSE);
  309. ASSERT(NT_SUCCESS(Status));
  310. InitializeObjectAttributes( &Attributes,
  311. &ObjectName,
  312. OBJ_CASE_INSENSITIVE,
  313. NULL,
  314. NULL );
  315. Status = ZwOpenSymbolicLinkObject( &ObjectHandle,
  316. SYMBOLIC_LINK_ALL_ACCESS,
  317. &Attributes );
  318. #if 0
  319. Status = ZwOpenFile( &ObjectHandle,
  320. FILE_READ_ATTRIBUTES,
  321. &Attributes,
  322. &IoStatusBlock,
  323. 0,
  324. FILE_NON_DIRECTORY_FILE );
  325. #endif
  326. if ( !NT_SUCCESS(Status) ) {
  327. ClusDiskPrint((
  328. 1,
  329. "ClusDisk: OpenObject, open file failed, status %lx.\n",
  330. Status ));
  331. return(NULL);
  332. }
  333. #endif
  334. return(ObjectHandle);
  335. } // GetDeviceObject
  336. #endif