lockmgrapi.cpp
来自「WinCE5.0部分核心源码」· C++ 代码 · 共 552 行 · 第 1/2 页
CPP
552 行
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++
Module Name:
lckmgrapi.cpp
Abstract:
Core Lock Manager API. This module is used by the Lock Manager API for
FSDs/File Systems.
Revision History:
--*/
#include "lockmgrapi.hpp"
#include "lockmgrdbg.hpp"
#include "lockcol.hpp"
#include "lockset.hpp"
#include "locklist.hpp"
#include "lock.hpp"
#include "range.hpp"
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
BOOL RemoveLock(
CFileLockSet *pFileLockSet,
DWORD hOwner,
CRange *pRange
)
{
SETFNAME(_T("RemoveLock"));
CFileLockList *pFileLockList;
CFileLock *pFileLock;
BOOL fInsertFileLockList = TRUE;
BOOL fResult = FALSE;
PREFAST_DEBUGCHK(NULL != pFileLockSet);
PREFAST_DEBUGCHK(NULL != hOwner);
PREFAST_DEBUGCHK(NULL != pRange);
// remove list, remove lock, delete lock, re-insert list
pFileLockList = pFileLockSet->Remove(hOwner);
if (NULL != pFileLockList) {
PREFAST_DEBUGCHK(NULL == pFileLockList->GetNext());
pFileLock = pFileLockList->Remove(pRange);
if (NULL != pFileLock) {
PREFAST_DEBUGCHK(NULL == pFileLock->GetNext());
delete pFileLock;
if (pFileLockList->IsEmpty()) {
delete pFileLockList;
fInsertFileLockList = FALSE;
}
fResult = TRUE;
}
if (fInsertFileLockList) {
pFileLockSet->Insert(pFileLockList);
}
}
return fResult;
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
PVOID
LXX_CreateLockContainer(
)
{
CFileLockCollection *pFileLockCollection = NULL;
// if malloc fails, null is returned; pass null to caller to indicate failure
pFileLockCollection = new CFileLockCollection();
return (PVOID)pFileLockCollection;
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
VOID
LXX_DestroyLockContainer(
PVOID pvLockContainer
)
{
SETFNAME(_T("LXX_DestroyLockContainer"));
CFileLockCollection *pFileLockCollection;
if (NULL == pvLockContainer) {
return;
}
// only our FSD-s use lock manager, so we trust pvLockContainer (__try not required)
pFileLockCollection = (CFileLockCollection *)pvLockContainer;
if (SIG != pFileLockCollection->GetSignature()) {
DEBUGMSG(1, (_T("%s failed to destroy lock container; bad lock container\r\n"), pszFname));
DEBUGCHK(0);
return;
}
delete pFileLockCollection;
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
BOOL
LXX_IsLockContainerEmpty(
PVOID pvLockContainer
)
{
SETFNAME(_T("LXX_IsLockContainerEmpty"));
CFileLockCollection *pFileLockCollection;
if (NULL == pvLockContainer) {
return TRUE;
}
pFileLockCollection = (CFileLockCollection *)pvLockContainer;
if (SIG != pFileLockCollection->GetSignature()) {
DEBUGMSG(1, (_T("%s failed to check if lock container empty; bad lock container\r\n"), pszFname));
DEBUGCHK(0);
return FALSE;
}
return pFileLockCollection->IsEmpty();
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// undo flags
#define DSET (1 << 0)
#define DLIST (1 << 1)
#define DRANGE (1 << 2)
LOCKRESULT
LXX_Lock(
PVOID pvLockContainer,
DWORD dwFile,
DWORD dwFlags,
DWORD dwReserved,
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh,
LPOVERLAPPED lpOverlapped
)
{
SETFNAME(_T("LXX_Lock"));
CFileLockCollection *pFileLockCollection;
CFileLockSet *pFileLockSet;
CFileLockList *pFileLockList;
CFileLock *pFileLock;
CRange *pRange;
DWORD dwUndo = 0;
LOCKRESULT lrResult = LR_ERROR;
if (NULL == pvLockContainer) {
DEBUGMSG(1, (_T("%s failed to install lock; lock container null\r\n"), pszFname));
return LR_ERROR;
}
if (0 == dwFile) {
DEBUGMSG(1, (_T("%s failed to install lock; file handle null\r\n"), pszFname));
return LR_ERROR;
}
if (0 != dwReserved) {
DEBUGMSG(1, (_T("%s (warning) dwReserved should be 0\r\n"), pszFname));
}
if (NULL == lpOverlapped) {
DEBUGMSG(1, (_T("%s failed to install lock; overlapped null\r\n"), pszFname));
return LR_ERROR;
}
if ((0 == nNumberOfBytesToLockLow) && (0 == nNumberOfBytesToLockHigh)) {
DEBUGMSG(1, (_T("%s failed to install lock; bytes to lock 0\r\n"), pszFname));
return LR_ERROR;
}
// only our FSD-s use lock manager, so we trust pvLockContainer (__try not required)
pFileLockCollection = (CFileLockCollection *)pvLockContainer;
if (SIG != pFileLockCollection->GetSignature()) {
DEBUGMSG(1, (_T("%s failed to install lock; bad lock container\r\n"), pszFname));
DEBUGCHK(0);
return LR_ERROR;
}
// create range
pRange = new CRange();
if (NULL == pRange) {
DEBUGMSG(1, (_T("%s failed to install lock; out of memory (new range)\r\n"), pszFname));
return LR_ERROR;
}
pRange->SetOffset(lpOverlapped->Offset, lpOverlapped->OffsetHigh);
pRange->SetLength(nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh);
dwUndo |= DRANGE;
if (!pRange->IsValid()) {
DEBUGMSG(1, (_T("%s failed to install lock; range(%I64u, %I64u) invalid\r\n"), pszFname, pRange->GetStart(), pRange->GetFinish()));
goto exit;
}
// test for conflict
if (NULL != pFileLockCollection->GetExclusive()) {
if (pFileLockCollection->GetExclusive()->IsConflict(pRange)) {
if (dwFlags & LOCKFILE_FAIL_IMMEDIATELY) {
goto exit;
}
lrResult = LR_CONFLICT;
goto exit;
}
}
// this lock does not conflict with an exclusive lock; shared locks can overlap,
// so we only have to check the shared set if this is an exclusive lock
if (NULL != pFileLockCollection->GetShared() && (dwFlags & LOCKFILE_EXCLUSIVE_LOCK)) {
if (pFileLockCollection->GetShared()->IsConflict(pRange)) {
if (dwFlags & LOCKFILE_FAIL_IMMEDIATELY) {
goto exit;
}
lrResult = LR_CONFLICT;
goto exit;
}
}
// range does not conflict with existing lock; get appropriate set; create,
// if necessary
if (dwFlags & LOCKFILE_EXCLUSIVE_LOCK) {
if (NULL == pFileLockCollection->GetExclusive()) {
pFileLockCollection->SetExclusive(new CFileLockSet());
if (NULL == pFileLockCollection->GetExclusive()) {
goto exit;
}
dwUndo |= DSET;
}
pFileLockSet = pFileLockCollection->GetExclusive();
}
else {
if (NULL == pFileLockCollection->GetShared()) {
pFileLockCollection->SetShared(new CFileLockSet());
if (NULL == pFileLockCollection->GetShared()) {
goto exit;
}
dwUndo |= DSET;
}
pFileLockSet = pFileLockCollection->GetShared();
}
// remove owner's list from appropriate set; create, if necessary
pFileLockList = pFileLockSet->Remove(dwFile);
if (NULL == pFileLockList) {
pFileLockList = new CFileLockList();
if (NULL == pFileLockList) {
DEBUGMSG(1, (_T("%s failed to install lock; out of memory (new lock list)\r\n"), pszFname));
goto exit;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?