ReactOS 0.4.16-dev-258-g81860b4
point.c File Reference
#include "mntmgr.h"
#include <debug.h>
Include dependency graph for point.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS MountMgrCreatePointWorker (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName)
 
NTSTATUS QueryPointsFromMemory (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN PMOUNTDEV_UNIQUE_ID UniqueId OPTIONAL, IN PUNICODE_STRING SymbolicName OPTIONAL)
 
NTSTATUS QueryPointsFromSymbolicLinkName (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN PIRP Irp)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 28 of file point.c.

Function Documentation

◆ MountMgrCreatePointWorker()

NTSTATUS MountMgrCreatePointWorker ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicLinkName,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 35 of file point.c.

38{
40 PLIST_ENTRY DeviceEntry;
41 PMOUNTDEV_UNIQUE_ID UniqueId;
42 PSYMLINK_INFORMATION SymlinkInformation;
43 UNICODE_STRING SymLink, TargetDeviceName;
44 PDEVICE_INFORMATION DeviceInformation = NULL, DeviceInfo;
45
46 /* Get device name */
48 &TargetDeviceName,
49 NULL, NULL, NULL,
50 NULL, NULL, NULL);
51 if (!NT_SUCCESS(Status))
52 {
53 return Status;
54 }
55
56 /* First of all, try to find device */
57 for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
58 DeviceEntry != &(DeviceExtension->DeviceListHead);
59 DeviceEntry = DeviceEntry->Flink)
60 {
61 DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
62
63 if (RtlEqualUnicodeString(&TargetDeviceName, &(DeviceInformation->DeviceName), TRUE))
64 {
65 break;
66 }
67 }
68
69 /* Copy symbolic link name and null terminate it */
70 SymLink.Buffer = AllocatePool(SymbolicLinkName->Length + sizeof(UNICODE_NULL));
71 if (!SymLink.Buffer)
72 {
73 FreePool(TargetDeviceName.Buffer);
75 }
76
77 RtlCopyMemory(SymLink.Buffer, SymbolicLinkName->Buffer, SymbolicLinkName->Length);
78 SymLink.Buffer[SymbolicLinkName->Length / sizeof(WCHAR)] = UNICODE_NULL;
79 SymLink.Length = SymbolicLinkName->Length;
80 SymLink.MaximumLength = SymbolicLinkName->Length + sizeof(UNICODE_NULL);
81
82 /* If we didn't find device */
83 if (DeviceEntry == &(DeviceExtension->DeviceListHead))
84 {
85 /* Then, try with unique ID */
87 NULL, &UniqueId,
88 NULL, NULL, NULL,
89 NULL, NULL);
90 if (!NT_SUCCESS(Status))
91 {
92 FreePool(TargetDeviceName.Buffer);
93 FreePool(SymLink.Buffer);
94 return Status;
95 }
96
97 /* Create a link to the device */
98 Status = GlobalCreateSymbolicLink(&SymLink, &TargetDeviceName);
99 if (!NT_SUCCESS(Status))
100 {
101 FreePool(UniqueId);
102 FreePool(TargetDeviceName.Buffer);
103 FreePool(SymLink.Buffer);
104 return Status;
105 }
106
107 /* If caller provided driver letter, delete it */
108 if (IsDriveLetter(&SymLink))
109 {
111 }
112
113 /* Device will be identified with its unique ID */
116 SymLink.Buffer,
118 UniqueId->UniqueId,
119 UniqueId->UniqueIdLength);
120
121 FreePool(UniqueId);
122 FreePool(TargetDeviceName.Buffer);
123 FreePool(SymLink.Buffer);
124 return Status;
125 }
126
127 /* If call provided a driver letter whereas device already has one
128 * fail, this is not doable
129 */
130 if (IsDriveLetter(&SymLink) && HasDriveLetter(DeviceInformation))
131 {
132 FreePool(TargetDeviceName.Buffer);
133 FreePool(SymLink.Buffer);
135 }
136
137 /* Now, create a link */
138 Status = GlobalCreateSymbolicLink(&SymLink, &TargetDeviceName);
139 FreePool(TargetDeviceName.Buffer);
140 if (!NT_SUCCESS(Status))
141 {
142 FreePool(SymLink.Buffer);
143 return Status;
144 }
145
146 /* Associate Unique ID <-> symbolic name */
147 UniqueId = DeviceInformation->UniqueId;
150 SymLink.Buffer,
152 UniqueId->UniqueId,
153 UniqueId->UniqueIdLength);
154 if (!NT_SUCCESS(Status))
155 {
156 GlobalDeleteSymbolicLink(&SymLink);
157 FreePool(SymLink.Buffer);
158 return Status;
159 }
160
161 /* Now, prepare to save the link with the device */
162 SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
163 if (!SymlinkInformation)
164 {
166 GlobalDeleteSymbolicLink(&SymLink);
167 FreePool(SymLink.Buffer);
168 return Status;
169 }
170
171 SymlinkInformation->Name.Length = SymLink.Length;
172 SymlinkInformation->Name.MaximumLength = SymLink.Length + sizeof(UNICODE_NULL);
173 SymlinkInformation->Name.Buffer = AllocatePool(SymlinkInformation->Name.MaximumLength);
174 if (!SymlinkInformation->Name.Buffer)
175 {
177 FreePool(SymlinkInformation);
178 GlobalDeleteSymbolicLink(&SymLink);
179 FreePool(SymLink.Buffer);
180 return Status;
181 }
182
183 /* Save the link and mark it online */
184 RtlCopyMemory(SymlinkInformation->Name.Buffer, SymLink.Buffer, SymlinkInformation->Name.Length);
185 SymlinkInformation->Name.Buffer[SymlinkInformation->Name.Length / sizeof(WCHAR)] = UNICODE_NULL;
186 SymlinkInformation->Online = TRUE;
187 InsertTailList(&DeviceInformation->SymbolicLinksListHead, &SymlinkInformation->SymbolicLinksListEntry);
188 SendLinkCreated(&(SymlinkInformation->Name));
189
190 /* If we have a drive letter */
191 if (IsDriveLetter(&SymLink))
192 {
193 /* Then, delete the no drive letter entry */
194 DeleteNoDriveLetterEntry(UniqueId);
195
196 /* And post online notification if asked */
197 if (!DeviceInformation->SkipNotifications)
198 {
199 PostOnlineNotification(DeviceExtension, &DeviceInformation->SymbolicName);
200 }
201 }
202
203 /* If that's a volume with automatic drive letter, it's now time to resync databases */
204 if (MOUNTMGR_IS_VOLUME_NAME(&SymLink) && DeviceExtension->AutomaticDriveLetter)
205 {
206 for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
207 DeviceEntry != &(DeviceExtension->DeviceListHead);
208 DeviceEntry = DeviceEntry->Flink)
209 {
210 DeviceInfo = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
211
212 /* If there's one, ofc! */
213 if (!DeviceInfo->NoDatabase)
214 {
216 }
217 }
218 }
219
220 /* Notify & quit */
221 FreePool(SymLink.Buffer);
222 MountMgrNotify(DeviceExtension);
223
224 if (!DeviceInformation->ManuallyRegistered)
225 {
226 MountMgrNotifyNameChange(DeviceExtension, DeviceName, FALSE);
227 }
228
229 return Status;
230}
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
BOOL NTAPI QueryDeviceInformation(_In_ PWCHAR DriveRoot, _Out_ PVOID DeviceInformation, _In_ ULONG BufferSize)
Retrieves disk device information.
Definition: query.c:79
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
VOID DeleteRegistryDriveLetter(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:2048
VOID DeleteNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:2100
PWSTR DatabasePath
Definition: database.c:31
#define InsertTailList(ListHead, Entry)
Status
Definition: gdiplustypes.h:25
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
VOID SendLinkCreated(IN PUNICODE_STRING SymbolicName)
Definition: symlink.c:169
NTSTATUS GlobalCreateSymbolicLink(IN PUNICODE_STRING DosName, IN PUNICODE_STRING DeviceName)
Definition: symlink.c:120
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:145
VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
Definition: notify.c:328
VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
Definition: notify.c:122
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:812
VOID MountMgrNotify(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:288
BOOLEAN HasDriveLetter(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:167
#define AllocatePool(Size)
Definition: mntmgr.h:153
#define FreePool(P)
Definition: mntmgr.h:154
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:81
#define REG_BINARY
Definition: nt_native.h:1496
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define UNICODE_NULL
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
BOOLEAN SkipNotifications
Definition: mntmgr.h:58
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT UniqueIdLength
Definition: imports.h:136
UCHAR UniqueId[1]
Definition: imports.h:137
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING SymbolicLinkName
Definition: wdfdevice.h:3739
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by MountMgrCreatePoint(), MountMgrNextDriveLetterWorker(), ProcessSuggestedDriveLetters(), and WriteUniqueIdToMaster().

◆ QueryPointsFromMemory()

NTSTATUS QueryPointsFromMemory ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp,
IN PMOUNTDEV_UNIQUE_ID UniqueId  OPTIONAL,
IN PUNICODE_STRING SymbolicName  OPTIONAL 
)

Definition at line 236 of file point.c.

240{
244 PMOUNTMGR_MOUNT_POINTS MountPoints;
245 PDEVICE_INFORMATION DeviceInformation;
246 PLIST_ENTRY DeviceEntry, SymlinksEntry;
247 PSYMLINK_INFORMATION SymlinkInformation;
248 USHORT UniqueIdLength, DeviceNameLength;
249 ULONG TotalSize, TotalSymLinks, UniqueIdOffset, DeviceNameOffset;
250
251 /* If we got a symbolic link, query device */
252 if (SymbolicName)
253 {
255 &DeviceName,
256 NULL, NULL,
257 NULL, NULL,
258 NULL, NULL);
259 if (!NT_SUCCESS(Status))
260 {
261 return Status;
262 }
263 }
264
265 /* Browse all the links to count number of links & size used */
266 TotalSize = 0;
267 TotalSymLinks = 0;
268 for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
269 DeviceEntry != &(DeviceExtension->DeviceListHead);
270 DeviceEntry = DeviceEntry->Flink)
271 {
272 DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
273
274 /* If we were given an unique ID, it has to match */
275 if (UniqueId)
276 {
277 if (UniqueId->UniqueIdLength != DeviceInformation->UniqueId->UniqueIdLength)
278 {
279 continue;
280 }
281
282 if (RtlCompareMemory(UniqueId->UniqueId,
283 DeviceInformation->UniqueId->UniqueId,
284 UniqueId->UniqueIdLength) != UniqueId->UniqueIdLength)
285 {
286 continue;
287 }
288 }
289 /* Or, if we had a symlink, it has to match */
290 else if (SymbolicName)
291 {
292 if (!RtlEqualUnicodeString(&DeviceName, &(DeviceInformation->DeviceName), TRUE))
293 {
294 continue;
295 }
296 }
297
298 /* Once here, it matched, save device name & unique ID size */
299 TotalSize += DeviceInformation->DeviceName.Length + DeviceInformation->UniqueId->UniqueIdLength;
300
301 /* And count number of symlinks (and their size) */
302 for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
303 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
304 SymlinksEntry = SymlinksEntry->Flink)
305 {
306 SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
307
308 TotalSize += SymlinkInformation->Name.Length;
309 TotalSymLinks++;
310 }
311
312 /* We had a specific item to find
313 * if we reach that point, we found it, no need to continue
314 */
315 if (UniqueId || SymbolicName)
316 {
317 break;
318 }
319 }
320
321 /* If we were looking for specific item, ensure we found it */
322 if (UniqueId || SymbolicName)
323 {
324 if (DeviceEntry == &(DeviceExtension->DeviceListHead))
325 {
326 if (SymbolicName)
327 {
328 FreePool(DeviceName.Buffer);
329 }
330
332 }
333 }
334
335 /* Now, ensure output buffer can hold everything */
337 MountPoints = (PMOUNTMGR_MOUNT_POINTS)Irp->AssociatedIrp.SystemBuffer;
338 RtlZeroMemory(MountPoints, Stack->Parameters.DeviceIoControl.OutputBufferLength);
339
340 /* Ensure we set output to let user reallocate! */
341 MountPoints->Size = sizeof(MOUNTMGR_MOUNT_POINTS) + TotalSymLinks * sizeof(MOUNTMGR_MOUNT_POINT) + TotalSize;
342 MountPoints->NumberOfMountPoints = TotalSymLinks;
343 Irp->IoStatus.Information = MountPoints->Size;
344
345 if (MountPoints->Size > Stack->Parameters.DeviceIoControl.OutputBufferLength)
346 {
347 Irp->IoStatus.Information = sizeof(MOUNTMGR_MOUNT_POINTS);
348
349 if (SymbolicName)
350 {
351 FreePool(DeviceName.Buffer);
352 }
353
355 }
356
357 /* Now, start putting mount points */
358 TotalSize = sizeof(MOUNTMGR_MOUNT_POINTS) + TotalSymLinks * sizeof(MOUNTMGR_MOUNT_POINT);
359 TotalSymLinks = 0;
360 for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
361 DeviceEntry != &(DeviceExtension->DeviceListHead);
362 DeviceEntry = DeviceEntry->Flink)
363 {
364 DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
365
366 /* Find back correct mount point */
367 if (UniqueId)
368 {
369 if (UniqueId->UniqueIdLength != DeviceInformation->UniqueId->UniqueIdLength)
370 {
371 continue;
372 }
373
374 if (RtlCompareMemory(UniqueId->UniqueId,
375 DeviceInformation->UniqueId->UniqueId,
376 UniqueId->UniqueIdLength) != UniqueId->UniqueIdLength)
377 {
378 continue;
379 }
380 }
381 else if (SymbolicName)
382 {
383 if (!RtlEqualUnicodeString(&DeviceName, &(DeviceInformation->DeviceName), TRUE))
384 {
385 continue;
386 }
387 }
388
389 /* Save our information about shared data */
390 UniqueIdOffset = TotalSize;
391 UniqueIdLength = DeviceInformation->UniqueId->UniqueIdLength;
392 DeviceNameOffset = TotalSize + UniqueIdLength;
393 DeviceNameLength = DeviceInformation->DeviceName.Length;
394
395 /* Initialize first symlink */
396 MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = UniqueIdOffset;
397 MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = UniqueIdLength;
398 MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset = DeviceNameOffset;
399 MountPoints->MountPoints[TotalSymLinks].DeviceNameLength = DeviceNameLength;
400
401 /* And copy data */
402 RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + UniqueIdOffset),
403 DeviceInformation->UniqueId->UniqueId, UniqueIdLength);
404 RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + DeviceNameOffset),
405 DeviceInformation->DeviceName.Buffer, DeviceNameLength);
406
407 TotalSize += DeviceInformation->UniqueId->UniqueIdLength + DeviceInformation->DeviceName.Length;
408
409 /* Now we've got it, but all the data */
410 for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
411 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
412 SymlinksEntry = SymlinksEntry->Flink)
413 {
414 SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
415
416 /* First, set shared data */
417
418 /* Only put UniqueID if online */
419 if (SymlinkInformation->Online)
420 {
421 MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = UniqueIdOffset;
422 MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = UniqueIdLength;
423 }
424 else
425 {
426 MountPoints->MountPoints[TotalSymLinks].UniqueIdOffset = 0;
427 MountPoints->MountPoints[TotalSymLinks].UniqueIdLength = 0;
428 }
429
430 MountPoints->MountPoints[TotalSymLinks].DeviceNameOffset = DeviceNameOffset;
431 MountPoints->MountPoints[TotalSymLinks].DeviceNameLength = DeviceNameLength;
432
433 /* And now, copy specific symlink info */
434 MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameOffset = TotalSize;
435 MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameLength = SymlinkInformation->Name.Length;
436
437 RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[TotalSymLinks].SymbolicLinkNameOffset),
438 SymlinkInformation->Name.Buffer, SymlinkInformation->Name.Length);
439
440 /* Update counters */
441 TotalSymLinks++;
442 TotalSize += SymlinkInformation->Name.Length;
443 }
444
445 if (UniqueId || SymbolicName)
446 {
447 break;
448 }
449 }
450
451 if (SymbolicName)
452 {
453 FreePool(DeviceName.Buffer);
454 }
455
456 return STATUS_SUCCESS;
457}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
_In_ PIRP Irp
Definition: csq.h:116
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
struct _MOUNTMGR_MOUNT_POINTS * PMOUNTMGR_MOUNT_POINTS
struct _MOUNTMGR_MOUNT_POINTS MOUNTMGR_MOUNT_POINTS
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4677
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:175
USHORT DeviceNameLength
Definition: imports.h:169
USHORT SymbolicLinkNameLength
Definition: imports.h:165
ULONG SymbolicLinkNameOffset
Definition: imports.h:164
uint16_t * PWSTR
Definition: typedefs.h:56
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639

Referenced by MountMgrQueryPoints().

◆ QueryPointsFromSymbolicLinkName()

NTSTATUS QueryPointsFromSymbolicLinkName ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicName,
IN PIRP  Irp 
)

Definition at line 463 of file point.c.

466{
471 PMOUNTMGR_MOUNT_POINTS MountPoints;
472 PDEVICE_INFORMATION DeviceInformation = NULL;
473 PLIST_ENTRY DeviceEntry, SymlinksEntry;
474 PSYMLINK_INFORMATION SymlinkInformation;
475
476 /* Find device */
478 NULL, NULL, NULL,
479 NULL, NULL, NULL);
480 if (NT_SUCCESS(Status))
481 {
482 /* Look for the device information */
483 for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
484 DeviceEntry != &(DeviceExtension->DeviceListHead);
485 DeviceEntry = DeviceEntry->Flink)
486 {
487 DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
488
489 if (RtlEqualUnicodeString(&DeviceName, &(DeviceInformation->DeviceName), TRUE))
490 {
491 break;
492 }
493 }
494
495 FreePool(DeviceName.Buffer);
496
497 if (DeviceEntry == &(DeviceExtension->DeviceListHead))
498 {
500 }
501
502 /* Check for the link */
503 for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
504 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
505 SymlinksEntry = SymlinksEntry->Flink)
506 {
507 SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
508
509 if (RtlEqualUnicodeString(SymbolicName, &SymlinkInformation->Name, TRUE))
510 {
511 break;
512 }
513 }
514
515 if (SymlinksEntry == &(DeviceInformation->SymbolicLinksListHead))
516 {
518 }
519 }
520 else
521 {
522 /* Browse all the devices to try to find the one
523 * that has the given link...
524 */
525 for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
526 DeviceEntry != &(DeviceExtension->DeviceListHead);
527 DeviceEntry = DeviceEntry->Flink)
528 {
529 DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
530
531 for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
532 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
533 SymlinksEntry = SymlinksEntry->Flink)
534 {
535 SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
536
537 if (RtlEqualUnicodeString(SymbolicName, &SymlinkInformation->Name, TRUE))
538 {
539 break;
540 }
541 }
542
543 if (SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead))
544 {
545 break;
546 }
547 }
548
549 /* Even that way we didn't find, give up! */
550 if (DeviceEntry == &(DeviceExtension->DeviceListHead))
551 {
553 }
554 }
555
556 /* Get output buffer */
558 MountPoints = (PMOUNTMGR_MOUNT_POINTS)Irp->AssociatedIrp.SystemBuffer;
559
560 /* Compute output length */
561 TotalLength = DeviceInformation->UniqueId->UniqueIdLength +
562 SymlinkInformation->Name.Length + DeviceInformation->DeviceName.Length;
563
564 /* Give length to allow reallocation */
565 MountPoints->Size = sizeof(MOUNTMGR_MOUNT_POINTS) + TotalLength;
566 MountPoints->NumberOfMountPoints = 1;
567 Irp->IoStatus.Information = sizeof(MOUNTMGR_MOUNT_POINTS) + TotalLength;
568
569 if (MountPoints->Size > Stack->Parameters.DeviceIoControl.OutputBufferLength)
570 {
571 Irp->IoStatus.Information = sizeof(MOUNTMGR_MOUNT_POINTS);
572
574 }
575
576 /* Write out data */
578 MountPoints->MountPoints[0].SymbolicLinkNameLength = SymlinkInformation->Name.Length;
579 /* If link is online write it's unique ID, otherwise, forget about it */
580 if (SymlinkInformation->Online)
581 {
582 MountPoints->MountPoints[0].UniqueIdOffset = sizeof(MOUNTMGR_MOUNT_POINTS) +
583 SymlinkInformation->Name.Length;
584 MountPoints->MountPoints[0].UniqueIdLength = DeviceInformation->UniqueId->UniqueIdLength;
585 }
586 else
587 {
588 MountPoints->MountPoints[0].UniqueIdOffset = 0;
589 MountPoints->MountPoints[0].UniqueIdLength = 0;
590 }
591
592 MountPoints->MountPoints[0].DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINTS) +
593 SymlinkInformation->Name.Length +
594 DeviceInformation->UniqueId->UniqueIdLength;
595 MountPoints->MountPoints[0].DeviceNameLength = DeviceInformation->DeviceName.Length;
596
597 RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[0].SymbolicLinkNameOffset),
598 SymlinkInformation->Name.Buffer, SymlinkInformation->Name.Length);
599
600 if (SymlinkInformation->Online)
601 {
602 RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[0].UniqueIdOffset),
603 DeviceInformation->UniqueId->UniqueId, DeviceInformation->UniqueId->UniqueIdLength);
604 }
605
606 RtlCopyMemory((PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[0].DeviceNameOffset),
607 DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length);
608
609 return STATUS_SUCCESS;
610}
#define ULONG_PTR
Definition: config.h:101
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_In_ ULONG TotalLength
Definition: usbdlib.h:158

Referenced by MountMgrQueryPoints().