part.cpp
来自「WinCE5.0部分核心源码」· C++ 代码 · 共 1,292 行 · 第 1/3 页
CPP
1,292 行
snNextPBRSector = 0;
snPrevPBRSector = 0;
// we are linking up to an existing partition
if (pTmpPartState) {
snPrevPBRSector = pTmpPartState->snPBRSector;
if (pTmpPartState->pNextPartState)
snNextPBRSector = pTmpPartState->pNextPartState->snPBRSector;
} else {
// this partition may be added to the front of the list
if (pState->pPartState)
snNextPBRSector = pState->pPartState->snPBRSector;
}
// update info for new partition
wcscpy(pNewPartState->cPartName, szPartitionName);
pNewPartState->snStartSector = snStartSector;
if (snPBRSector)
pNewPartState->snNumSectors = snSectorCount - (snStartSector - snPBRSector);
else
pNewPartState->snNumSectors = snSectorCount;
pNewPartState->pNextPartState = NULL;
pNewPartState->pState = pState;
pNewPartState->snPBRSector = snPBRSector;
bResult = InitPartition (pState, pNewPartState);
if (!bResult) {
LocalFree(pNewPartState);
return ERROR_PARTITION_FAILURE;
}
// add the partition info the DriverState structure
if (pTmpPartState == NULL) {
// we're adding to the front of the list
if (pState->pPartState)
pNewPartState->pNextPartState = pState->pPartState;
pState->pPartState = pNewPartState;
} else {
// if this partition is filling a gap, add the link at the right point in the list
if (pTmpPartState->pNextPartState)
pNewPartState->pNextPartState = pTmpPartState->pNextPartState;
pTmpPartState->pNextPartState = pNewPartState;
}
pState->dwNumParts++;
#if HIDDEN_PARTITIONS
if (pState->bUseHiddenPartitions) {
UpdateFileTime(pState, pNewPartState, FALSE, TRUE);
// add this to the partition table on the media
WriteHiddenPartitionTable(pState);
}
#endif
if (bResult) {
if (bAuto)
GenerateFATFSType(pState, pNewPartState->snNumSectors, &pNewPartState->partType);
else
pNewPartState->partType = bPartType;
DEBUGMSG(ZONE_STORE,(L"MSPART!PD_CreatePartition - type is %d\n", pNewPartState->partType));
// after everything that can fail succeeds, hook this partition in to the partition tables
if (snPBRSector)
bResult = CreatePBR(pState, snPrevPBRSector, snNextPBRSector, snPBRSector, snSectorCount, pNewPartState->partType);
else
bResult = WriteMBR(pState, snStartSector, snSectorCount, pNewPartState->partType, FALSE);
}
// if we failed to write out the partition table, set the pState back to the way it was
if (!bResult) {
if (pTmpPartState == NULL)
pState->pPartState = NULL;
else
pTmpPartState->pNextPartState = pNewPartState->pNextPartState;
pState->dwNumParts--;
LocalFree(pNewPartState);
return ERROR_PARTITION_FAILURE;
}
// the last thing we do is to fix up any search pStates for this store that may be in process
if (pNewPartState->pNextPartState) {
pSearchState = pState->pSearchState;
// walk through the list of SearchStates to see if any need to be adjusted for this new partition
while(pSearchState) {
// if the new partition is added at the search point, set the search point to the new partition
if (pSearchState->pPartState == pNewPartState->pNextPartState)
pSearchState->pPartState = pNewPartState;
pSearchState = pSearchState->pNextSearchState;
}
}
return ERROR_SUCCESS;
}
/*****************************************************************************/
DWORD PD_OpenPartition(DWORD dwStoreId, LPCTSTR szPartitionName, LPDWORD pdwPartitionId)
{
PartState * pPartState;
DriverState *pState = (PDriverState) dwStoreId;
DEBUGMSG(1,(L"MSPART!PD_OpenPartition: dwStoreId=%08X, PartName=%s\n", dwStoreId, szPartitionName));
if (!pState) {
return ERROR_INVALID_PARAMETER;
}
GetPartition(pState, &pPartState, NULL, szPartitionName);
// don't allow the create if the name is not unique
if (!pPartState) {
return ERROR_NOT_FOUND;
}
*pdwPartitionId = (DWORD)pPartState;
return ERROR_SUCCESS;
}
/*****************************************************************************/
DWORD ReadPartition(DWORD dwPartitionId,
PBYTE pInBuf, DWORD nInBufSize,
PBYTE pOutBuf, DWORD nOutBufSize,
PDWORD pBytesReturned)
{
PartState *pPartState = (PPartState)dwPartitionId;
DWORD dwError = ERROR_SUCCESS;
SG_REQ *req;
req = (SG_REQ *)pInBuf;
// be sure the sector # is within range of the partition
if ((req->sr_start >= pPartState->snNumSectors) ||
(pPartState->snNumSectors - req->sr_start < req->sr_num_sec))
{
return ERROR_INVALID_BLOCK;
}
req->sr_start += (DWORD)pPartState->snStartSector;
if (!FSDMGR_DiskIoControl(pPartState->pState->hDsk, DISK_IOCTL_READ, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned, NULL)) {
dwError = GetLastError();
if (dwError == ERROR_SUCCESS)
dwError = ERROR_GEN_FAILURE;
}
req->sr_start -= (DWORD)pPartState->snStartSector;
return dwError;
}
/*****************************************************************************/
DWORD WritePartition(DWORD dwPartitionId,
PBYTE pInBuf, DWORD nInBufSize,
PBYTE pOutBuf, DWORD nOutBufSize,
PDWORD pBytesReturned)
{
PartState *pPartState = (PPartState)dwPartitionId;
DEBUGMSG( ZONE_PARTITION, (L"MSPART!WritePartition dwPartitionId=%08X pInBuf=%08X nInBufSize=%ld\r\n", dwPartitionId, pInBuf, nInBufSize));
DWORD dwError = ERROR_SUCCESS;
SG_REQ *req;
req = (SG_REQ *)pInBuf;
// be sure the sector # is within range of the partition
if ((req->sr_start >= pPartState->snNumSectors) ||
(pPartState->snNumSectors - req->sr_start < req->sr_num_sec))
{
return ERROR_INVALID_BLOCK;
}
if (pPartState->dwAttributes & PARTITION_ATTRIBUTE_READONLY) {
return ERROR_ACCESS_DENIED;
}
req->sr_start += (DWORD)pPartState->snStartSector;
if (!FSDMGR_DiskIoControl(pPartState->pState->hDsk, DISK_IOCTL_WRITE, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned, NULL)) {
dwError = GetLastError();
if (dwError == ERROR_SUCCESS)
dwError = ERROR_GEN_FAILURE;
}
req->sr_start -= (DWORD)pPartState->snStartSector;
return dwError;
}
DWORD DeleteSectors(PartState *pPartState, DELETE_SECTOR_INFO *pdsi, PDWORD pBytesReturned)
{
DWORD dwError = ERROR_SUCCESS;
if (pdsi->cbSize != sizeof(DELETE_SECTOR_INFO)) {
return ERROR_INVALID_PARAMETER;
}
if ((pdsi->startsector >= pPartState->snNumSectors) || (pdsi->startsector + pdsi->numsectors > pPartState->snNumSectors)) {
return ERROR_INVALID_BLOCK;
}
if (pPartState->dwAttributes & PARTITION_ATTRIBUTE_READONLY) {
return ERROR_ACCESS_DENIED;
}
pdsi->startsector += (DWORD)pPartState->snStartSector;
if (!FSDMGR_DiskIoControl(pPartState->pState->hDsk, IOCTL_DISK_DELETE_SECTORS, (PBYTE)pdsi, sizeof(DELETE_SECTOR_INFO), NULL, 0, pBytesReturned, NULL)) {
dwError = GetLastError();
}
pdsi->startsector -= (DWORD)pPartState->snStartSector;
return dwError;
}
DWORD GetSectorAddrs(PartState *pPartState, DWORD *pdwSectorList, DWORD cbSectorList, DWORD *pdwAddrList, DWORD cbAddrList, DWORD *pBytesReturned)
{
DWORD dwError = ERROR_SUCCESS;
DWORD iSector, cSectors = cbSectorList / sizeof(DWORD);
// change partition relative sector addrs to absolute sector addrs
for (iSector = 0; iSector < cSectors; iSector++) {
pdwSectorList[iSector] += (DWORD)pPartState->snStartSector;
}
if (!FSDMGR_DiskIoControl(pPartState->pState->hDsk, IOCTL_DISK_GET_SECTOR_ADDR, pdwSectorList, cbSectorList, pdwAddrList, cbAddrList, pBytesReturned, NULL)) {
dwError = GetLastError();
if (ERROR_SUCCESS == dwError) {
dwError = ERROR_GEN_FAILURE;
}
}
// revert addrs back to partition relative
for (iSector = 0; iSector < cSectors; iSector++) {
pdwSectorList[iSector] -= (DWORD)pPartState->snStartSector;
}
return dwError;
}
DWORD CopyExternal(PartState *pPartState, DISK_COPY_EXTERNAL *pdce, LPBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
DWORD dwError = ERROR_SUCCESS;
DWORD dwNumSectors = pdce->cbSectorListSize / sizeof(SECTOR_LIST_ENTRY);
SECTOR_LIST_ENTRY *pSectorList = (SECTOR_LIST_ENTRY *)(pdce+1);
while(dwNumSectors--) {
pSectorList->dwStartSector += (DWORD)pPartState->snStartSector;
pSectorList++;
}
if (!FSDMGR_DiskIoControl(pPartState->pState->hDsk, IOCTL_DISK_COPY_EXTERNAL_START, (PBYTE)pdce, sizeof(DISK_COPY_EXTERNAL)+pdce->cbSectorListSize, pOutBuf, nOutBufSize, pBytesReturned, NULL)) {
dwError = GetLastError();
}
return dwError;
}
/*****************************************************************************/
DWORD PD_DeviceIoControl(DWORD dwPartitionId, DWORD dwCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned)
{
PartState *pPartState = (PPartState)dwPartitionId;
DWORD dwError=ERROR_SUCCESS;
DISK_INFO *pdi = NULL;
DEBUGMSG( ZONE_API, (L"MSPART!PD_DeviceIoControl dwPartitionId=%08X pInBuf=%08X nInBufSize=%ld pOutBuf=%08X nOutBufSize=%ld\r\n",
dwPartitionId,
pInBuf,
nInBufSize,
pOutBuf,
nOutBufSize));
if ((dwCode == IOCTL_DISK_READ) || (dwCode == DISK_IOCTL_READ)) {
dwError = ReadPartition(dwPartitionId, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned);
} else
if ((dwCode == IOCTL_DISK_WRITE) || (dwCode == DISK_IOCTL_WRITE)) {
dwError = WritePartition(dwPartitionId, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned);
} else
if (dwCode == IOCTL_DISK_DELETE_SECTORS) {
if (nInBufSize != sizeof(DELETE_SECTOR_INFO)) {
return ERROR_INVALID_PARAMETER;
} else {
dwError = DeleteSectors( pPartState, (DELETE_SECTOR_INFO *)pInBuf, pBytesReturned);
}
} else
if (dwCode == IOCTL_DISK_COPY_EXTERNAL_START) {
if (nInBufSize >= sizeof(DISK_COPY_EXTERNAL)) {
dwError = CopyExternal( pPartState, (DISK_COPY_EXTERNAL *)pInBuf, pOutBuf, nOutBufSize, pBytesReturned);
} else {
return ERROR_INVALID_PARAMETER;
}
} else
if ((dwCode == IOCTL_DISK_GETINFO) || (dwCode == DISK_IOCTL_GETINFO)) {
if (pInBuf) {
if (nInBufSize != sizeof(DISK_INFO))
return ERROR_INVALID_PARAMETER;
pdi = (DISK_INFO *)pInBuf;
}
if (pOutBuf) {
if (nOutBufSize!= sizeof(DISK_INFO))
return ERROR_INVALID_PARAMETER;
pdi = (DISK_INFO *)pOutBuf;
}
if (pdi) {
if (FSDMGR_DiskIoControl(pPartState->pState->hDsk, dwCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned, NULL)) {
pdi->di_total_sectors = (DWORD)pPartState->snNumSectors;
pdi->di_cylinders = 1;
pdi->di_heads = 1;
pdi->di_sectors = 1;
pdi->di_flags &= ~DISK_INFO_FLAG_MBR;
if (pPartState->pState->bFormatState) {
pdi->di_flags &= ~DISK_INFO_FLAG_UNFORMATTED;
}
if (pBytesReturned)
*pBytesReturned = sizeof(DISK_INFO);
dwError = ERROR_SUCCESS;
} else {
dwError = GetLastError();
if (dwError == ERROR_SUCCESS)
dwError = ERROR_GEN_FAILURE;
}
} else {
dwError = ERROR_INVALID_PARAMETER;
}
} else
if (dwCode == IOCTL_DISK_GET_SECTOR_ADDR) {
if (nOutBufSize && (nInBufSize == nOutBufSize) && pInBuf && pOutBuf) {
dwError = GetSectorAddrs( pPartState, (DWORD*)pInBuf, nInBufSize, (DWORD*)pOutBuf, nOutBufSize, pBytesReturned);
} else {
dwError = ERROR_INVALID_PARAMETER;
}
} else {
if (!FSDMGR_DiskIoControl(pPartState->pState->hDsk, dwCode, pInBuf, nInBufSize, pOutBuf, nOutBufSize, pBytesReturned, NULL)) {
dwError = GetLastError();
if (dwError == ERROR_SUCCESS)
dwError = ERROR_GEN_FAILURE;
}
}
return dwError;
}
/*****************************************************************************/
void PD_ClosePartition(DWORD dwPartitionId)
{
PartState *pPartState = (PPartState)dwPartitionId;
DEBUGMSG( ZONE_API, (L"MSPART!PD_ClosePartition dwPartitionId=%08X\r\n", dwPartitionId));
// the partition structures are freed when the store is closed
// we use them even if the partition isn't 'mounted' by the file system
// to perform other partitioning functions
return;
}
/*****************************************************************************/
DWORD PD_DeletePartition(DWORD dwStoreId, LPCTSTR szPartitionName)
{
DriverState *pState = (PDriverState) dwStoreId;
PartState *pPartState;
PartState *pPrevPartState;
SearchState *pSearchState;
BOOL bResult = TRUE;
DELETE_SECTOR_INFO dsi;
DWORD dwRet;
DEBUGMSG(ZONE_API,(L"MSPART!PD_DeletePartition: dwStoreId=%08X PartName=%s\n", dwStoreId, szPartitionName));
GetPartition(pState, &pPartState, &pPrevPartState, szPartitionName);
if (!pPartState) {
SetLastError(ERROR_NOT_FOUND);
return ERROR_NOT_FOUND;
}
if (pPartState->dwAttributes & PARTITION_ATTRIBUTE_READONLY) {
SetLastError(ERROR_ACCESS_DENIED);
return ERROR_ACCESS_DENIED;
}
#if HIDDEN_PARTITIONS
// don't allow the hidden partition to be deleted
if (pPartState == pState->pHiddenPartState) {
SetLastError(ERROR_NOT_FOUND);
return ERROR_NOT_FOUND;
}
#endif
// remove the link from the DOS partition table
if (pPartState->snPBRSector)
bResult = DeletePBR(pState, pPartState, pPrevPartState);
else
bResult = DeleteMBR(pState, pPartState);
if (!bResult)
return ERROR_GEN_FAILURE;
// Delete the sectors that made up the partition to indicate they are no longer needed. Used by flash drivers.
dsi.cbSize = sizeof(DELETE_SECTOR_INFO);
dsi.startsector = (DWORD)pPartState->snStartSector;
dsi.numsectors = (DWORD)pPartState->snNumSectors;
FSDMGR_DiskIoControl(pState->hDsk, IOCTL_DISK_DELETE_SECTORS, (PBYTE)&dsi,
sizeof(DELETE_SECTOR_INFO), NULL, 0, &dwRet, NULL);
// remove this partition from the linked list
if (pPrevPartState)
pPrevPartState->pNextPartState = pPartState->pNextPartState;
else
pState->pPartState = pPartState->pNextPartState;
pState->dwNumParts--;
#if HIDDEN_PARTITIONS
if (pState->bUseHiddenPartitions) {
UpdateFileTime(pState, NULL, FALSE, FALSE);
WriteHiddenPartitionTable(pState);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?