📄 disk.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
disk.c
Abstract:
DSK_Xxx Streams Interface for USB Disk Class:
bInterfaceSubClass = 0x02 : SFF8020i (ATAPI) CD-ROM
bInterfaceSubClass = 0x04 : USB Floppy Interface (UFI)
bInterfaceSubClass = 0x06 : SCSI Passthrough
Notes:
--*/
#include <windows.h>
#include <pkfuncs.h>
#include <devload.h>
#include <storemgr.h>
#include <ntddscsi.h>
#include "usbmsc.h"
#include "scsi2.h"
BOOL
WaitForUnitReady(
IN PSCSI_DEVICE pDevice
);
UCHAR
DiscoverLuns(
IN PSCSI_DEVICE pDevice
);
DWORD
GetDiskInfo(
IN PSCSI_DEVICE pDevice,
IN OUT PDISK_INFO pDiskInfo,
IN UCHAR Lun
);
DWORD
GetMediumInfo(
IN PSCSI_DEVICE pDevice,
IN UCHAR Lun
);
VOID
RemoveDeviceContext(
PSCSI_DEVICE pDevice
);
DWORD WINAPI
MediaChangeThread(
LPVOID Context
);
DWORD
MountUpperDriver(
IN PSCSI_DEVICE pDevice,
IN PPOST_INIT_BUF pInBuf
);
DWORD
DismountUpperDriver(
IN PSCSI_DEVICE pDevice
);
DWORD
GetDeviceInfo(
IN PSCSI_DEVICE pDevice,
IN OUT STORAGEDEVICEINFO *psdi
);
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("USBDISK6"), {
TEXT("Errors"), TEXT("Warnings"), TEXT("Init"), TEXT("Trace"),
TEXT("SCSI"), TEXT("CDROM"), TEXT("CDDA"), TEXT("IOCTL"),
TEXT("Read"), TEXT("Write"), TEXT("Thread"), TEXT("Event"),
TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"), TEXT("Undefined"),
},
0x0003 //0x0123 // 0x0003 // ZONE_WRN|ZONE_ERR
};
#endif // DEBUG
static
BOOL
SterilizeIoRequest(
PSG_REQ pSafeIoRequest,
PSG_REQ pUnsafeIoRequest,
DWORD cbUnsafeIoRequest
)
{
DWORD i = 0;
if (NULL == pSafeIoRequest) {
return FALSE;
}
if (NULL == pUnsafeIoRequest) {
return FALSE;
}
if (cbUnsafeIoRequest < sizeof(SG_REQ)) {
return FALSE;
}
if (cbUnsafeIoRequest > (sizeof(SG_REQ) + ((MAX_SG_BUF - 1) * sizeof(SG_BUF)))) {
return FALSE;
}
if (0 == CeSafeCopyMemory((LPVOID)pSafeIoRequest, (LPVOID)pUnsafeIoRequest, cbUnsafeIoRequest)) {
return FALSE;
}
for (i = 0; i < pSafeIoRequest->sr_num_sg; i += 1) {
if (
NULL == pSafeIoRequest->sr_sglist[i].sb_buf ||
0 == pSafeIoRequest->sr_sglist[i].sb_len
) {
return FALSE;
}
// NOTENOTE: Embedded Scatter/Gather buffer ptrs are validated before
// use in the ScsiRWSG function.
}
return TRUE;
}
BOOL
DllEntry(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpreserved
)
{
BOOL bRc = TRUE;
UNREFERENCED_PARAMETER(hDllHandle);
UNREFERENCED_PARAMETER(lpreserved);
switch (dwReason) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE)hDllHandle);
DisableThreadLibraryCalls((HMODULE) hDllHandle);
break;
case DLL_PROCESS_DETACH:
break;
default:
break;
}
return bRc;
}
//*****************************************************************************
// S T R E A M S I N T E R F A C E
//*****************************************************************************
/*++
DSK_Init:
Called by Device Manager to initialize our streams interface in response to our call to
ActivateDevice. We passed ActivateDevice a pointer to our device context, but must read
it out of the registry as "ClientInfo".
Returns:
Context pointer used in Xxx_Open, Xxx_PowerDown, Xxx_PowerUp, and Xxx_Deinit
--*/
PSCSI_DEVICE
DSK_Init(
PVOID Context
)
{
LPTSTR ActivePath = (LPTSTR)Context;
PSCSI_DEVICE pDevice = NULL;
BOOL bRc = TRUE;
DEBUGMSG(ZONE_INIT, (TEXT("USBDISK6>DSK_Init(%p)\n"), Context));
//
// Get and verify our Context from the Registry
//
pDevice = UsbsGetContextFromReg( ActivePath );
if ( VALID_CONTEXT( pDevice ) ) {
//
// Acquire the remove lock. We release it in DSK_Deinit
//
if (ERROR_SUCCESS == AcquireRemoveLock(&pDevice->RemoveLock,NULL)) {
//
// Initialize state
//
EnterCriticalSection(&pDevice->Lock);
pDevice->DeviceType = SCSI_DEVICE_UNKNOWN;
pDevice->MediumType = SCSI_MEDIUM_UNKNOWN;
pDevice->Flags.MediumPresent = FALSE;
pDevice->Flags.Open = FALSE;
pDevice->Flags.MediumChanged = TRUE;
pDevice->hProc = GetCallerProcess();
LeaveCriticalSection(&pDevice->Lock);
//
// Try to get Medium information
//
GetMediumInfo(pDevice, pDevice->Lun);
} else {
bRc = FALSE;
TEST_TRAP();
}
} else {
bRc = FALSE;
TEST_TRAP();
}
DEBUGMSG(ZONE_INIT, (TEXT("USBDISK6<DSK_Init:0x%x\n"), pDevice ));
return (bRc ? pDevice : NULL);
}
//
// Called by Device Manager when we Deregister our DSK interface.
//
BOOL
DSK_Deinit(
PSCSI_DEVICE pDevice
)
{
BOOL bRc = FALSE;
DEBUGMSG(ZONE_INIT, (TEXT("USBDISK6>DSK_Deinit\n")));
if ( VALID_CONTEXT( pDevice ) ) {
//EnterCriticalSection( &pDevice->Lock );
// ...
//LeaveCriticalSection(&pDevice->Lock);
//
// Release the remove lock acquired in DSK_Init
//
ReleaseRemoveLock(&pDevice->RemoveLock,NULL);
}
DEBUGMSG(ZONE_INIT, (TEXT("USBDISK6<DSK_Deinit:%d\n"), bRc));
return bRc;
}
/*++
DSK_Open:
Called by device mgr after DSK_Init if you requested post-init ioctl.
Called by FSD when it mounts on top of this disk driver.
If successful then you can expect the DSK_Close when it unmounts.
If not successful then you should not expect the call to DSK_Close.
Returns:
Open context to be used in the Xxx_Read, Xxx_Write, Xxx_Seek, and Xxx_IOControl functions.
If the device cannot be opened, this function returns NULL.
BUGBUG: check AccessCode & ShareMode
--*/
PSCSI_DEVICE
DSK_Open(
PSCSI_DEVICE Context, // context returned by DSK_Init.
DWORD AccessCode, // @parm access code
DWORD ShareMode // @parm share mode
)
{
PSCSI_DEVICE pDevice = Context;
BOOL bRc = TRUE;
UNREFERENCED_PARAMETER(AccessCode);
UNREFERENCED_PARAMETER(ShareMode);
DEBUGMSG(ZONE_INIT,(TEXT("USBDISK6>DSK_Open(0x%x, 0x%x, 0x%x)\n"),pDevice, AccessCode, ShareMode));
//
// acquire the remove lock; release it in DSK_Close
//
if ( VALID_CONTEXT( pDevice ) ) {
EnterCriticalSection(&pDevice->Lock);
if ( !pDevice->Flags.DeviceRemoved && !pDevice->Flags.PoweredDown) {
pDevice->OpenCount++;
pDevice->Flags.Open = TRUE;
} else {
DEBUGMSG( ZONE_ERR,(TEXT("DSK_Open: ERROR_ACCESS_DENIED\n")));
SetLastError(ERROR_ACCESS_DENIED);
bRc = FALSE;
}
LeaveCriticalSection(&pDevice->Lock);
} else {
DEBUGMSG( ZONE_ERR,(TEXT("DSK_Open: ERROR_FILE_NOT_FOUND\n")));
SetLastError(ERROR_FILE_NOT_FOUND);
bRc = FALSE;
}
DEBUGMSG(ZONE_INIT,(TEXT("USBDISK6<DSK_Open:%d\n"), bRc ));
return (bRc ? pDevice : NULL);
}
BOOL
DSK_Close(
PSCSI_DEVICE Context
)
{
PSCSI_DEVICE pDevice = Context;
BOOL bRc = TRUE;
DEBUGMSG(ZONE_INIT,(TEXT("USBDISK6>DSK_Close(0x%x)\n"),pDevice));
if ( VALID_CONTEXT( pDevice ) ) {
EnterCriticalSection(&pDevice->Lock);
if ( 0 == --pDevice->OpenCount ) {
pDevice->Flags.Open = FALSE;
}
ASSERT( pDevice->OpenCount >= 0);
LeaveCriticalSection(&pDevice->Lock);
} else {
DEBUGMSG( ZONE_ERR,(TEXT("DSK_Close: ERROR_INVALID_HANDLE\n")));
SetLastError(ERROR_INVALID_HANDLE);
bRc = FALSE;
}
DEBUGMSG( ZONE_INIT,(TEXT("USBDISK6<DSK_Close:%d\n"), bRc));
return bRc;
}
ULONG
DSK_Read(
PSCSI_DEVICE pDevice,
PUCHAR pBuffer,
ULONG BufferLength
)
{
UNREFERENCED_PARAMETER(pDevice);
UNREFERENCED_PARAMETER(pBuffer);
UNREFERENCED_PARAMETER(BufferLength);
DEBUGMSG(ZONE_ERR,(TEXT("DSK_Read\n")));
SetLastError(ERROR_INVALID_FUNCTION);
return 0;
}
ULONG
DSK_Write(
PSCSI_DEVICE pDevice,
PUCHAR pBuffer,
ULONG BufferLength
)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -