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 + -
显示快捷键?