NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath
)
/*++
Routine Description:
Called on loading. We create a device object to handle user-mode requests
on, and register ourselves as a protocol with NDIS.
Arguments:
pDriverObject - Pointer to driver object created by system.
pRegistryPath - Pointer to the Unicode name of the registry path
for this driver.
Return Value:
NT Status code
--*/
{
NDIS_PROTOCOL_DRIVER_CHARACTERISTICS protocolChar = {0};
NTSTATUS status = STATUS_SUCCESS;
NDIS_STRING protoName = NDIS_STRING_CONST("NDISPROT");
UNICODE_STRING ntDeviceName;
UNICODE_STRING win32DeviceName;
BOOLEAN fSymbolicLink = FALSE;
PDEVICE_OBJECT deviceObject = NULL;
NDIS_HANDLE ProtocolDriverContext={0};
UNREFERENCED_PARAMETER(pRegistryPath);
DEBUGP(DL_LOUD, ("DriverEntry\n"));
Globals.pDriverObject = pDriverObject;
Globals.EthType = NPROT_ETH_TYPE;
NPROT_INIT_EVENT(&Globals.BindsComplete);
do
{
//
// Create our device object using which an application can
// access NDIS devices.
//
RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
status = IoCreateDevice (pDriverObject,
0,
&ntDeviceName,
FILE_DEVICE_NETWORK,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&deviceObject);
if (!NT_SUCCESS (status))
{
//
// Either not enough memory to create a deviceobject or another
// deviceobject with the same name exits. This could happen
// if you install another instance of this device.
//
break;
}
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);
if (!NT_SUCCESS(status))
{
break;
}
fSymbolicLink = TRUE;
deviceObject->Flags |= DO_DIRECT_IO;
Globals.ControlDeviceObject = deviceObject;
NPROT_INIT_LIST_HEAD(&Globals.OpenList);
NPROT_INIT_LOCK(&Globals.GlobalLock);
//
// Initialize the protocol characterstic structure
//
#if (NDIS_SUPPORT_NDIS630)
{C_ASSERT(sizeof(protocolChar) >= NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2);}
protocolChar.Header.Type = NDIS_OBJECT_TYPE_PROTOCOL_DRIVER_CHARACTERISTICS,
protocolChar.Header.Size = NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2;
protocolChar.Header.Revision = NDIS_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2;
#elif (NDIS_SUPPORT_NDIS6)
{C_ASSERT(sizeof(protocolChar) >= NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1);}
protocolChar.Header.Type = NDIS_OBJECT_TYPE_PROTOCOL_DRIVER_CHARACTERISTICS,
protocolChar.Header.Size = NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1;
protocolChar.Header.Revision = NDIS_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1;
#endif // NDIS MINIPORT VERSION
//.........这里部分代码省略.........
NTSTATUS
NTAPI
SmpSbCreateSession(IN PVOID Reserved,
IN PSMP_SUBSYSTEM OtherSubsystem,
IN PRTL_USER_PROCESS_INFORMATION ProcessInformation,
IN ULONG MuSessionId,
IN PCLIENT_ID DbgClientId)
{
NTSTATUS Status;
PSMP_SUBSYSTEM KnownSubsys;
SB_API_MSG SbApiMsg;
ULONG SessionId;
PSB_CREATE_SESSION_MSG CreateSessionMsg;
/* Write out the create session message including its initial process */
CreateSessionMsg = &SbApiMsg.CreateSession;
CreateSessionMsg->ProcessInfo = *ProcessInformation;
CreateSessionMsg->MuSessionId = MuSessionId;
if (DbgClientId)
{
CreateSessionMsg->ClientId = *DbgClientId;
}
else
{
CreateSessionMsg->ClientId.UniqueThread = NULL;
CreateSessionMsg->ClientId.UniqueProcess = NULL;
}
/* Find a subsystem responsible for this session */
SmpGetProcessMuSessionId(ProcessInformation->ProcessHandle, &MuSessionId);
if (!SmpCheckDuplicateMuSessionId(MuSessionId))
{
NtClose(ProcessInformation->ProcessHandle);
NtClose(ProcessInformation->ThreadHandle);
DPRINT1("SMSS: CreateSession status=%x\n", STATUS_OBJECT_NAME_NOT_FOUND);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
/* Find the subsystem we have for this initial process */
KnownSubsys = SmpLocateKnownSubSysByType(MuSessionId,
ProcessInformation->
ImageInformation.SubSystemType);
if (KnownSubsys)
{
/* Duplicate the process handle into the message */
Status = NtDuplicateObject(NtCurrentProcess(),
ProcessInformation->ProcessHandle,
KnownSubsys->ProcessHandle,
&CreateSessionMsg->ProcessInfo.ProcessHandle,
PROCESS_ALL_ACCESS,
0,
0);
if (NT_SUCCESS(Status))
{
/* Duplicate the thread handle into the message */
Status = NtDuplicateObject(NtCurrentProcess(),
ProcessInformation->ThreadHandle,
KnownSubsys->ProcessHandle,
&CreateSessionMsg->ProcessInfo.ThreadHandle,
THREAD_ALL_ACCESS,
0,
0);
if (!NT_SUCCESS(Status))
{
/* Close everything on failure */
NtClose(ProcessInformation->ProcessHandle);
NtClose(ProcessInformation->ThreadHandle);
SmpDereferenceSubsystem(KnownSubsys);
DbgPrint("SmpSbCreateSession: NtDuplicateObject (Thread) Failed %lx\n", Status);
return Status;
}
/* Close the original handles as they are no longer needed */
NtClose(ProcessInformation->ProcessHandle);
NtClose(ProcessInformation->ThreadHandle);
/* Finally, allocate a new SMSS session ID for this session */
SessionId = SmpAllocateSessionId(KnownSubsys, OtherSubsystem);
CreateSessionMsg->SessionId = SessionId;
/* Fill out the LPC message header and send it to the client! */
SbApiMsg.ApiNumber = SbpCreateSession;
SbApiMsg.h.u2.ZeroInit = 0;
SbApiMsg.h.u1.s1.DataLength = sizeof(SB_CREATE_SESSION_MSG) + 8;
SbApiMsg.h.u1.s1.TotalLength = sizeof(SbApiMsg);
Status = NtRequestWaitReplyPort(KnownSubsys->SbApiPort,
&SbApiMsg.h,
&SbApiMsg.h);
if (!NT_SUCCESS(Status))
{
/* Bail out */
DPRINT1("SmpSbCreateSession: NtRequestWaitReply Failed %lx\n", Status);
}
else
{
/* If the API succeeded, get the result value from the LPC */
Status = SbApiMsg.ReturnValue;
}
/* Delete the session on any kind of failure */
//.........这里部分代码省略.........
//.........这里部分代码省略.........
/* Determine directory index */
if (Stack->Flags & SL_INDEX_SPECIFIED)
{
Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart;
}
else if (First || (Stack->Flags & SL_RESTART_SCAN))
{
Ccb->Entry = 0;
}
/* Determine Buffer for result */
if (Irp->MdlAddress)
{
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
}
else
{
Buffer = Irp->UserBuffer;
}
DPRINT("Buffer=%p tofind=%S\n", Buffer, Ccb->DirectorySearchPattern);
while (Status == STATUS_SUCCESS && BufferLength > 0)
{
Status = NtfsFindFileAt(DeviceExtension,
&Pattern,
&Ccb->Entry,
&FileRecord,
&DataContext,
&MFTRecord,
Fcb->MFTIndex);
if (NT_SUCCESS(Status))
{
/* HACK: files with both a short name and a long name are present twice in the index.
* Ignore the second entry, if it is immediately following the first one.
*/
if (MFTRecord == OldMFTRecord)
{
DPRINT("Ignoring duplicate MFT entry 0x%x\n", MFTRecord);
Ccb->Entry++;
ExFreePoolWithTag(FileRecord, TAG_NTFS);
continue;
}
OldMFTRecord = MFTRecord;
switch (FileInformationClass)
{
case FileNameInformation:
Status = NtfsGetNameInformation(DeviceExtension,
FileRecord,
DataContext,
(PFILE_NAMES_INFORMATION)Buffer,
BufferLength);
break;
case FileDirectoryInformation:
Status = NtfsGetDirectoryInformation(DeviceExtension,
FileRecord,
DataContext,
(PFILE_DIRECTORY_INFORMATION)Buffer,
BufferLength);
break;
case FileFullDirectoryInformation:
/*++////////////////////////////////////////////////////////////////////////////
ClasspPowerDownCompletion()
Routine Description:
This routine is used for intermediate completion of a power up request.
PowerUp requires four requests to be sent to the lower driver in sequence.
* The queue is "power locked" to ensure that the class driver power-up
work can be done before request processing resumes.
* The power irp is sent down the stack for any filter drivers and the
port driver to return power and resume command processing for the
device. Since the queue is locked, no queued irps will be sent
immediately.
* A start unit command is issued to the device with appropriate flags
to override the "power locked" queue.
* The queue is "power unlocked" to start processing requests again.
This routine uses the function in the srb which just completed to determine
which state it is in.
Arguments:
DeviceObject - the device object being powered up
Irp - the IO_REQUEST_PACKET containing the power request
Srb - the SRB used to perform port/class operations.
Return Value:
STATUS_MORE_PROCESSING_REQUIRED or
STATUS_SUCCESS
--*/
NTSTATUS
NTAPI
ClasspPowerDownCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PCLASS_POWER_CONTEXT Context
)
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(Irp);
NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
DebugPrint((1, "ClasspPowerDownCompletion: Device Object %p, "
"Irp %p, Context %p\n",
DeviceObject, Irp, Context));
ASSERT(!TEST_FLAG(Context->Srb.SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER));
ASSERT(!TEST_FLAG(Context->Srb.SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE));
ASSERT(Context->Options.PowerDown == TRUE);
ASSERT(Context->Options.HandleSpinDown);
if(Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
Context->PowerChangeState.PowerDown2++;
switch(Context->PowerChangeState.PowerDown2) {
case PowerDownDeviceLocked2: {
PCDB cdb;
DebugPrint((1, "(%p)\tPreviously sent power lock\n", Irp));
if((Context->Options.LockQueue == TRUE) &&
(!NT_SUCCESS(Irp->IoStatus.Status))) {
DebugPrint((1, "(%p)\tIrp status was %lx\n",
Irp,
Irp->IoStatus.Status));
DebugPrint((1, "(%p)\tSrb status was %lx\n",
Irp,
Context->Srb.SrbStatus));
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
//
// Lock was not successful - throw down the power IRP
// by itself and don't try to spin down the drive or unlock
// the queue.
//
Context->InUse = FALSE;
Context = NULL;
//
//.........这里部分代码省略.........
/*++////////////////////////////////////////////////////////////////////////////
ClasspPowerUpCompletion()
Routine Description:
This routine is used for intermediate completion of a power up request.
PowerUp requires four requests to be sent to the lower driver in sequence.
* The queue is "power locked" to ensure that the class driver power-up
work can be done before request processing resumes.
* The power irp is sent down the stack for any filter drivers and the
port driver to return power and resume command processing for the
device. Since the queue is locked, no queued irps will be sent
immediately.
* A start unit command is issued to the device with appropriate flags
to override the "power locked" queue.
* The queue is "power unlocked" to start processing requests again.
This routine uses the function in the srb which just completed to determine
which state it is in.
Arguments:
DeviceObject - the device object being powered up
Irp - the IO_REQUEST_PACKET containing the power request
Srb - the SRB used to perform port/class operations.
Return Value:
STATUS_MORE_PROCESSING_REQUIRED or
STATUS_SUCCESS
--*/
NTSTATUS
NTAPI
ClasspPowerUpCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PCLASS_POWER_CONTEXT Context
)
{
PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation(Irp);
NTSTATUS status = STATUS_MORE_PROCESSING_REQUIRED;
DebugPrint((1, "ClasspPowerUpCompletion: Device Object %p, Irp %p, "
"Context %p\n",
DeviceObject, Irp, Context));
ASSERT(!TEST_FLAG(Context->Srb.SrbFlags, SRB_FLAGS_FREE_SENSE_BUFFER));
ASSERT(!TEST_FLAG(Context->Srb.SrbFlags, SRB_FLAGS_PORT_DRIVER_ALLOCSENSE));
ASSERT(Context->Options.PowerDown == FALSE);
ASSERT(Context->Options.HandleSpinUp);
if(Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
Context->PowerChangeState.PowerUp++;
switch(Context->PowerChangeState.PowerUp) {
case PowerUpDeviceLocked: {
DebugPrint((1, "(%p)\tPreviously sent power lock\n", Irp));
//
// Issue the actual power request to the lower driver.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
//
// If the lock wasn't successful then just bail out on the power
// request unless we can ignore failed locks
//
if((Context->Options.LockQueue == TRUE) &&
(!NT_SUCCESS(Irp->IoStatus.Status))) {
DebugPrint((1, "(%p)\tIrp status was %lx\n",
Irp, Irp->IoStatus.Status));
DebugPrint((1, "(%p)\tSrb status was %lx\n",
Irp, Context->Srb.SrbStatus));
//
// Lock was not successful - throw down the power IRP
// by itself and don't try to spin up the drive or unlock
// the queue.
//.........这里部分代码省略.........
请发表评论