📄 system.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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:
system.c
Abstract:
WINCE driver for PCMCIA ATA Disk cards
Functions:
Notes:
--*/
#include <windows.h>
#include <windev.h>
#include <types.h>
#include <tchar.h>
#include <cardserv.h>
#include <cardapi.h>
#include <tuple.h>
#include <devload.h>
#include <atapi.h>
#include <diskio.h>
#include <atadisk.h>
#include <storemgr.h>
#include <pm.h>
//
// This module contains the necessary OS interface functions:
// InitPcmciaDll
// ATADiskEntry
// CreateDiskObject
// IsValidDisk
// DiskFromSocket
// GetDiskStateError
// InitFSD
// DSK_Init and the other device API functions
// IsCardInserted
// PcmciaCallBack
// GetATAWindows
// ATAConfig
// ATAInit
// ATAGetSocket
// ATADetect
// DetectATADisk
//
#ifdef DEBUG
//
// These defines must match the ZONE_* defines
//
#define DBG_ERROR 1
#define DBG_WARNING 2
#define DBG_FUNCTION 4
#define DBG_INIT 8
#define DBG_PCMCIA 16
#define DBG_IO 32
DBGPARAM dpCurSettings = {
TEXT("ATA Disk"), {
TEXT("Errors"),TEXT("Warnings"),TEXT("Functions"),TEXT("Initialization"),
TEXT("PCMCIA"),TEXT("Disk I/O"),TEXT("Undefined"),TEXT("Undefined"),
TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"),
TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined") },
DBG_INIT
};
#endif // DEBUG
PDISK ATAInit(CARD_SOCKET_HANDLE hSock, LPTSTR ActivePath);
DWORD ATAGetSocket(LPTSTR ActivePath, CARD_SOCKET_HANDLE * pSock);
BOOL ATADetect(CARD_SOCKET_HANDLE hSock);
BOOL GetFolderName(PDISK pDisk, LPWSTR pOutBuf, DWORD nOutBufSize, DWORD * pBytesReturned);
BOOL GetStorageID(PDISK pDisk, PSTORAGE_IDENTIFICATION pOutBuf, DWORD nOutBufSize, DWORD * pBytesReturned);
HKEY OpenDriverKey(LPTSTR ActiveKey);
//
// Global Variables
//
DWORD v_MemGran; // memory granularity from CardMapMemory (usually 1)
CRITICAL_SECTION v_DiskCrit;
PDISK v_DiskList; // initialized to 0 in bss
HMODULE v_hPcmciaDll;
REGISTERCLIENT v_pfnCardRegisterClient;
DEREGISTERCLIENT v_pfnCardDeregisterClient;
GETFIRSTTUPLE v_pfnCardGetFirstTuple;
GETNEXTTUPLE v_pfnCardGetNextTuple;
GETTUPLEDATA v_pfnCardGetTupleData;
GETPARSEDTUPLE v_pfnCardGetParsedTuple;
REQUESTWINDOW v_pfnCardRequestWindow;
RELEASEWINDOW v_pfnCardReleaseWindow;
MAPWINDOW v_pfnCardMapWindow;
REQUESTCONFIG v_pfnCardRequestConfiguration;
RELEASECONFIG v_pfnCardReleaseConfiguration;
REQUESTIRQ v_pfnCardRequestIRQ;
RELEASEIRQ v_pfnCardReleaseIRQ;
REQUESTSOCKETMASK v_pfnCardRequestSocketMask;
RELEASESOCKETMASK v_pfnCardReleaseSocketMask;
GETSTATUS v_pfnCardGetStatus;
typedef BOOL (WINAPI *GETSYSPOWER)(PSYSTEM_POWER_STATUS_EX pSystemPowerStatusEx, BOOL fUpdate);
GETSYSPOWER v_pfnGetSystemPowerStatusEx = NULL;
//
// InitPcmciaDll - LoadLibrary(PCMCIA.DLL) and GetProcAddress necessary entrypoints
//
BOOL
InitPcmciaDll(VOID)
{
HMODULE hCoreDll;
hCoreDll = (HMODULE)LoadLibrary(TEXT("COREDLL.DLL"));
if (hCoreDll != NULL) {
v_pfnGetSystemPowerStatusEx = (GETSYSPOWER)GetProcAddress(hCoreDll, TEXT("GetSystemPowerStatusEx"));
FreeLibrary(hCoreDll);
}
v_hPcmciaDll = LoadLibrary(TEXT("PCMCIA.DLL"));
if (v_hPcmciaDll) {
v_pfnCardRegisterClient = (REGISTERCLIENT)GetProcAddress(v_hPcmciaDll, TEXT("CardRegisterClient"));
v_pfnCardDeregisterClient = (DEREGISTERCLIENT)GetProcAddress(v_hPcmciaDll, TEXT("CardDeregisterClient"));
v_pfnCardGetFirstTuple = (GETFIRSTTUPLE)GetProcAddress(v_hPcmciaDll, TEXT("CardGetFirstTuple"));
v_pfnCardGetNextTuple = (GETNEXTTUPLE)GetProcAddress(v_hPcmciaDll, TEXT("CardGetNextTuple"));
v_pfnCardGetTupleData = (GETTUPLEDATA)GetProcAddress(v_hPcmciaDll, TEXT("CardGetTupleData"));
v_pfnCardGetParsedTuple = (GETPARSEDTUPLE)GetProcAddress(v_hPcmciaDll, TEXT("CardGetParsedTuple"));
v_pfnCardRequestWindow = (REQUESTWINDOW)GetProcAddress(v_hPcmciaDll, TEXT("CardRequestWindow"));
v_pfnCardReleaseWindow = (RELEASEWINDOW)GetProcAddress(v_hPcmciaDll, TEXT("CardReleaseWindow"));
v_pfnCardMapWindow = (MAPWINDOW)GetProcAddress(v_hPcmciaDll, TEXT("CardMapWindow"));
v_pfnCardRequestConfiguration = (REQUESTCONFIG)GetProcAddress(v_hPcmciaDll, TEXT("CardRequestConfiguration"));
v_pfnCardReleaseConfiguration = (RELEASECONFIG)GetProcAddress(v_hPcmciaDll, TEXT("CardReleaseConfiguration"));
v_pfnCardRequestIRQ = (REQUESTIRQ)GetProcAddress(v_hPcmciaDll, TEXT("CardRequestIRQ"));
v_pfnCardReleaseIRQ = (RELEASEIRQ)GetProcAddress(v_hPcmciaDll, TEXT("CardReleaseIRQ"));
v_pfnCardRequestSocketMask = (REQUESTSOCKETMASK)GetProcAddress(v_hPcmciaDll, TEXT("CardRequestSocketMask"));
v_pfnCardReleaseSocketMask = (RELEASESOCKETMASK)GetProcAddress(v_hPcmciaDll, TEXT("CardReleaseSocketMask"));
v_pfnCardGetStatus = (GETSTATUS)GetProcAddress(v_hPcmciaDll, TEXT("CardGetStatus"));
}
if ((v_hPcmciaDll == NULL) ||
(v_pfnCardRegisterClient == NULL) ||
(v_pfnCardDeregisterClient == NULL) ||
(v_pfnCardGetFirstTuple == NULL) ||
(v_pfnCardGetNextTuple == NULL) ||
(v_pfnCardGetTupleData == NULL) ||
(v_pfnCardGetParsedTuple == NULL) ||
(v_pfnCardRequestWindow == NULL) ||
(v_pfnCardReleaseWindow == NULL) ||
(v_pfnCardMapWindow == NULL) ||
(v_pfnCardRequestConfiguration == NULL) ||
(v_pfnCardReleaseConfiguration == NULL) ||
(v_pfnCardRequestIRQ == NULL) ||
(v_pfnCardReleaseIRQ == NULL) ||
(v_pfnCardRequestSocketMask == NULL) ||
(v_pfnCardReleaseSocketMask == NULL) ||
(v_pfnCardGetStatus == NULL)) {
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK: InitPcmciaDll() failed!\r\n")));
return FALSE;
}
return TRUE;
} // InitPcmciaDll
//
// ATADISK.DLL entry
//
BOOL WINAPI
DllMain(HINSTANCE DllInstance, DWORD Reason, LPVOID Reserved)
{
switch(Reason) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER(DllInstance);
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK: DLL_PROCESS_ATTACH\r\n")));
DisableThreadLibraryCalls((HMODULE) DllInstance);
InitializeCriticalSection(&v_DiskCrit);
return InitPcmciaDll();
case DLL_PROCESS_DETACH:
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK: DLL_PROCESS_DETACH\r\n")));
FreeLibrary(v_hPcmciaDll);
DeleteCriticalSection(&v_DiskCrit);
break;
}
return TRUE;
} // ATADiskEntry
//
// CreateDiskObject - create a DISK structure, init some fields and link it.
//
PDISK
CreateDiskObject(VOID)
{
PDISK pDisk;
pDisk = LocalAlloc(LPTR, sizeof(DISK));
if (pDisk != NULL) {
pDisk->d_OpenCount = 0;
pDisk->d_ActivePath = NULL;
pDisk->d_Flags = 0;
InitializeCriticalSection(&(pDisk->d_DiskCardCrit));
pDisk->d_IRQEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
pDisk->hPwrEvent= CreateEvent(NULL, TRUE, TRUE, NULL);
pDisk->lPwrOff = 0;
if (pDisk->d_IRQEvent == NULL) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR, (TEXT("ATADISK: CreateEvent failed\r\n")));
CloseHandle(pDisk->d_IRQEvent);
LocalFree(pDisk);
pDisk = NULL;
} else {
EnterCriticalSection(&v_DiskCrit);
pDisk->d_next = v_DiskList;
v_DiskList = pDisk;
LeaveCriticalSection(&v_DiskCrit);
}
}
return pDisk;
} // CreateDiskObject
//
// IsValidDisk - verify that pDisk points to something in our list
//
// Return TRUE if pDisk is valid, FALSE if not.
//
BOOL
IsValidDisk(
PDISK pDisk
)
{
PDISK pd;
BOOL ret = FALSE;
EnterCriticalSection(&v_DiskCrit);
pd = v_DiskList;
while (pd) {
if (pd == pDisk) {
ret = TRUE;
break;
}
pd = pd->d_next;
}
LeaveCriticalSection(&v_DiskCrit);
return ret;
} // IsValidDisk
//
// DiskFromSocket - return the address of the DISK structure for the specified
// socket or NULL if there is not disk in that socket.
//
PDISK
DiskFromSocket(
CARD_SOCKET_HANDLE hSock
)
{
PDISK pd;
EnterCriticalSection(&v_DiskCrit);
pd = v_DiskList;
while (pd) {
if ((pd->d_hSock.uSocket == hSock.uSocket ) &&
(pd->d_hSock.uFunction == hSock.uFunction)) {
break;
}
pd = pd->d_next;
}
LeaveCriticalSection(&v_DiskCrit);
return pd;
} // DiskFromSocket
//
// InitFSD - Load and initialize the file system associated with this device
//
// Return TRUE for success
//
BOOL
InitFSD(
PPOST_INIT_BUF pInBuf
)
{
DWORD ValType;
DWORD ValLen;
DWORD status;
TCHAR FSDll[256];
if (IsStorageManagerRunning()) {
DEBUGMSG( ZONE_INIT, (TEXT("Not loading FSD since StorageManager is active\r\n")));
} else {
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK:InitFSD entered\r\n")));
ValLen = sizeof(FSDll);
status = RegQueryValueEx( // get the file system driver dll name
pInBuf->p_hDeviceKey,
TEXT("FSD"),
NULL,
&ValType,
(PUCHAR)FSDll,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK:InitFSD - RegQueryValueEx(FS) returned %d\r\n"),
status));
return FALSE;
}
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK:InitFSD calling LoadFSD(0x%x, %s)\r\n"),
pInBuf->p_hDevice, FSDll));
return LoadFSD(pInBuf->p_hDevice, FSDll);
}
return TRUE;
} // InitFSD
BOOL GetDeviceInfo(PDISK pDisk, PSTORAGEDEVICEINFO psdi)
{
HKEY DriverKey;
DWORD ValType;
DWORD status;
DWORD dwSize;
DriverKey = OpenDriverKey(pDisk->d_ActivePath);
if (DriverKey) {
dwSize = sizeof(psdi->szProfile);
status = RegQueryValueEx(
DriverKey,
TEXT("Profile"),
NULL,
&ValType,
(LPBYTE)psdi->szProfile,
&dwSize);
if ((status != ERROR_SUCCESS) || (dwSize > sizeof(psdi->szProfile))){
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK:GetFolderName - RegQueryValueEx(Profile) returned %d\r\n"),
status));
wcscpy( psdi->szProfile, L"Default");
} else {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("ATADISK:GetProfileName - Profile = %s, length = %d\r\n"),
psdi->szProfile, dwSize));
}
RegCloseKey(DriverKey);
}
psdi->dwDeviceClass = STORAGE_DEVICE_CLASS_BLOCK;
psdi->dwDeviceType = STORAGE_DEVICE_TYPE_PCCARD;
psdi->dwDeviceType |= STORAGE_DEVICE_TYPE_ATA;
psdi->dwDeviceType |= STORAGE_DEVICE_TYPE_REMOVABLE_DRIVE;
psdi->dwDeviceFlags = STORAGE_DEVICE_FLAG_READWRITE;
return TRUE;
}
//
// File system device entrypoints (DSK_????)
//
//
// Returns context data (PDISK) for this Init instance or 0 for failure.
//
// Arguments:
// dwContext - registry path for this device's active key
//
DWORD
DSK_Init(
DWORD dwContext
)
{
DWORD ret;
CARD_SOCKET_HANDLE hSock;
LPTSTR ActiveKey = (LPTSTR)dwContext;
DEBUGMSG(ZONE_INIT,
(TEXT("ATADISK: DSK_Init\r\n")));
//
// Get the socket number from the device's active key.
//
ret = ATAGetSocket(ActiveKey, &hSock);
if (ret) {
DEBUGMSG(ZONE_INIT,
(TEXT("ATADISK:DSK_Init ATAGetSocket failed %d\r\n"),
ret));
return 0;
}
if (ATADetect(hSock) == TRUE) {
return (DWORD)ATAInit(hSock, ActiveKey);
} else {
DEBUGMSG(ZONE_INIT,
(TEXT("ATADISK:DSK_Init Non-ATA device inserted\r\n")));
return 0;
}
} // DSK_Init
BOOL
DSK_Close(
DWORD Handle
)
{
BOOL bClose = TRUE;
PDISK pDisk = (PDISK)Handle;
DEBUGMSG(ZONE_IO, (TEXT("ATADISK: DSK_Close\r\n")));
if (!IsValidDisk(pDisk)) {
return FALSE;
}
EnterCriticalSection(&(pDisk->d_DiskCardCrit));
pDisk->d_OpenCount--;
if (pDisk->d_OpenCount != 0) {
bClose = FALSE;
}
LeaveCriticalSection(&(pDisk->d_DiskCardCrit));
if (bClose == TRUE) {
SetEvent(pDisk->d_IRQEvent);
}
return TRUE;
} // DSK_Close
//
// Device deinit - devices are expected to close down.
// The device manager does not check the return code.
//
BOOL
DSK_Deinit(
DWORD dwContext // pointer to the per disk structure
)
{
PDISK pDisk = (PDISK)dwContext;
DEBUGMSG(ZONE_INIT, (TEXT("ATADISK: DSK_Deinit\r\n")));
DSK_Close(dwContext);
CloseDisk(pDisk);
return TRUE;
} // DSK_Deinit
//
// Returns handle value for the open instance.
//
DWORD
DSK_Open(
DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode
)
{
PDISK pDisk = (PDISK)dwData;
DWORD ret = 0;
DEBUGMSG(ZONE_IO, (TEXT("ATADISK: DSK_Open(0x%x)\r\n"),dwData));
if (IsValidDisk(pDisk) == FALSE) {
DEBUGMSG(ZONE_IO, (TEXT("ATADISK: DSK_Open - Passed invalid disk handle\r\n")));
return ret;
}
EnterCriticalSection(&(pDisk->d_DiskCardCrit));
ret = (DWORD)pDisk;
pDisk->d_OpenCount++;
LeaveCriticalSection(&(pDisk->d_DiskCardCrit));
return ret;
} // DSK_Open
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -