⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disk.c

📁 WIN CE 下storage 存储外设的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// 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 + -