Всем привет! Пишу драйвер динамически подключаемого диска. Для его подключения в систему я использую последовательность: Код (Text): NTSTATUS MountManagerMount (char *NativeDeviceName,UCHAR DriveNumber) { NTSTATUS ntStatus; WCHAR arrVolume[200]; char buf[200]; PMOUNTMGR_TARGET_NAME in = (PMOUNTMGR_TARGET_NAME) buf; PMOUNTMGR_CREATE_POINT_INPUT createPoint; ULONG createPointSize; ANSI_STRING aString; UNICODE_STRING uString; UNICODE_STRING ntName,dosName; RtlInitAnsiString(&aString,NativeDeviceName); RtlAnsiStringToUnicodeString(&uString,&aString,TRUE); wcscpy(arrVolume,uString.Buffer); RtlFreeUnicodeString(&uString); in->DeviceNameLength = (USHORT) wcslen (arrVolume) * sizeof(WCHAR); wcscpy(in->DeviceName, arrVolume); ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, in,sizeof (in->DeviceNameLength) + in->DeviceNameLength, 0, 0); if(ntStatus) return ntStatus; memset (buf, 0, sizeof(buf)); swprintf((WCHAR*)buf, L"\\DosDevices\\%C:", 'A'+DriveNumber); RtlInitUnicodeString(&dosName, (PCWSTR)buf); RtlInitUnicodeString(&ntName, arrVolume); createPointSize = sizeof(MOUNTMGR_CREATE_POINT_INPUT) + dosName.Length + ntName.Length; createPoint = (PMOUNTMGR_CREATE_POINT_INPUT) ExAllocatePool(PagedPool, createPointSize); createPoint->SymbolicLinkNameOffset = sizeof(MOUNTMGR_CREATE_POINT_INPUT); createPoint->SymbolicLinkNameLength = dosName.Length; createPoint->DeviceNameOffset = createPoint -> SymbolicLinkNameOffset + createPoint -> SymbolicLinkNameLength; createPoint->DeviceNameLength = ntName.Length; RtlCopyMemory((PCHAR) createPoint + createPoint -> SymbolicLinkNameOffset, dosName.Buffer, dosName.Length); RtlCopyMemory((PCHAR) createPoint + createPoint->DeviceNameOffset, ntName.Buffer, ntName.Length); ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_CREATE_POINT, createPoint, createPointSize, 0, 0); ExFreePool(createPoint); return ntStatus; } Везде возвращается 0. Для отключения же я использую IOCTL_MOUNTMGR_DELETE_POINTS Код (Text): ///////////////////////////////////////////////////////////////////// NTSTATUS MountManagerUnmount (int DriveNumber) { NTSTATUS ntStatus; char buf[300], out[300]; PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf; PMOUNTDEV_NAME name = (PMOUNTDEV_NAME)buf; memset (buf, 0, sizeof buf); swprintf((PWSTR) &in[1], L"\\DosDevices\\%C:", 'A'+DriveNumber); in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT); in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2; ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS, in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out); return ntStatus; } Тоже возвращает 0. Проблема- под Win2k подключаем-отключаем диск. После повторного подключения к той же букве в свойствах диска исчезают две вкладки, а система не видит файловой системы диска и его метки. Перепробовал всё, что только пришло в голову. Ничего не получилось. Нужна помощь. Обработчики сообщений от MauntManager такие: Код (Text): case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: { ANSI_STRING aString; UNICODE_STRING uString; PMOUNTDEV_NAME MountdevName; USHORT Len; // Check output buffer length if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME) ) { status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } // Set pointer to return buffer MountdevName = (PMOUNTDEV_NAME)Irp->AssociatedIrp.SystemBuffer; MountdevName->NameLength = strlen(DeviceExtension->szDevicePath) * sizeof(WCHAR); Len = MountdevName->NameLength + sizeof(USHORT); // Check output buffer length if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < Len) { KdPrint(("SDPRT: IOCTL_MOUNTDEV_QUERY_DEVICE_NAME input buffer too small\n")); status = STATUS_BUFFER_OVERFLOW; Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME); break; } RtlInitAnsiString(&aString,DeviceExtension->szDevicePath); RtlAnsiStringToUnicodeString(&uString,&aString,TRUE); wcscpy(MountdevName->Name,uString.Buffer); RtlFreeUnicodeString(&uString); RtlInitUnicodeString(&uString,MountdevName->Name); MountdevName->NameLength=uString.Length; status = STATUS_SUCCESS; Irp->IoStatus.Information = Len; } break; case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: { PMOUNTDEV_UNIQUE_ID pMountID; char temp[100]={0}; USHORT Len; if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID) ) { status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } pMountID = (PMOUNTDEV_UNIQUE_ID)Irp->AssociatedIrp.SystemBuffer; sprintf(temp,"GDISK%C",'A'+DeviceExtension->dwDriveNumber); pMountID->UniqueIdLength = strlen(temp); Len = pMountID->UniqueIdLength + sizeof(USHORT); if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < Len) { Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); status = STATUS_BUFFER_OVERFLOW; break; } strcpy(pMountID->UniqueId,temp); status = STATUS_SUCCESS; Irp->IoStatus.Information = Len; } break; case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME: { PMOUNTDEV_SUGGESTED_LINK_NAME pSuggestedLink; USHORT Len; UNICODE_STRING uString; WCHAR temp[200]={0}; if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_SUGGESTED_LINK_NAME) ) { status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } pSuggestedLink = (PMOUNTDEV_SUGGESTED_LINK_NAME)Irp->AssociatedIrp.SystemBuffer; swprintf(temp,L"\\DosDevices\\%C:",'A'+DeviceExtension->dwDriveNumber ); pSuggestedLink->NameLength=wcslen(temp)*sizeof(WCHAR); Len=pSuggestedLink->NameLength+FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_N AME,Name); if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < Len) { Irp->IoStatus.Information = sizeof (MOUNTDEV_SUGGESTED_LINK_NAME); status = STATUS_BUFFER_OVERFLOW; break; } pSuggestedLink->UseOnlyIfThereAreNoOtherLinks=FALSE; wcscpy(pSuggestedLink->Name,temp); RtlInitUnicodeString(&uString,pSuggestedLink->Name); pSuggestedLink->NameLength=uString.Length; status = STATUS_SUCCESS; Irp->IoStatus.Information=uString.Length + FIELD_OFFSET(MOUNTDEV_SUGGESTED_LINK_NAME,Name); } break;
rav Подсказать особо ничего не могу, только идеи. Если идет работа с диском, особенно запись, Винда как-то помечает незавершенные операции и если такой диск "на ходу" размонтировать, то его без chkdsk уже не подключишь... Рой в этом направлении. Вряд ли функция размонтирования такие вещи проверяет. МС и более простые проверки не делает
Мне вот просто смонтировать диск надо через mountmgr, чтоб в эксплорере показывало. Этот код с явно необходимыми исправлениями НЕ работает. Помимо описанных IOCTL, приходят к драйверу - клиенту следующие: IOCTL_MOUNTDEV_CHANGE_UNIQUE_ID_NOTIFY, IOCTL_MOUNTDEV_LINK_CREATED. Написал на них обработку - по МСДНу(правильно вроде) - НЕ работает. Кто знает - напишите про эту тему, в т.ч. как обрабатывать все эти IOCTL., или работающий примерчик, пожалуйста. Задолбался уже .