📄 utils.cpp
字号:
CCritSection csLock(&m_csLock);
csLock.Lock();
//
// If we have never been run, fire up our wakeup thread
if(!m_hWakeUpThread) {
ASSERT(NULL == m_hWakeUpThread);
if(NULL == (m_hWakeUpThread = CreateThread(NULL, 0, SMB_WakeupThread, this, 0, NULL))) {
hr = E_OUTOFMEMORY;
goto Done;
}
}
//
// Put our new item into the list
if(FAILED(hr = m_UniqueID.GetID(pID))) {
goto Done;
}
pNode->SetID(*pID);
pNode->SetHandle(h);
if(!m_HandList.push_back(pNode)) {
hr = E_OUTOFMEMORY;
} else {
hr = WakeUp();
}
Done:
return hr;
}
DWORD
WakeUpOnEvent::SMB_WakeupThread(LPVOID _pMyself)
{
WakeUpOnEvent *pMySelf = (WakeUpOnEvent *)_pMyself;
HANDLE HandleArray[1];
USHORT IDs[1];
HANDLE *pHand = HandleArray;
USHORT *pIDs = IDs;
UINT uiMaxHands = sizeof(HandleArray) / sizeof(HandleArray[0]);
CCritSection csLock(&pMySelf->m_csLock);
for(;;)
{
csLock.Lock();
UINT uiUsedHands = pMySelf->m_HandList.size() + 1;
//
// If we dont have a spot for all the items, grow the array
if(pMySelf->m_HandList.size()+1 > uiMaxHands) {
UINT uiNewMax = (pMySelf->m_HandList.size()+1) * 2;
HANDLE *pNewHand = new HANDLE[uiNewMax];
USHORT *pNewIDs = new USHORT[uiNewMax];
if(NULL == pNewHand || NULL == pNewIDs) {
if(pNewHand) {
delete [] pNewHand;
}
if(pNewIDs) {
delete [] pNewIDs;
}
goto Done;
}
//
// Delete the old arrays & assign them to their new values
if(pHand != HandleArray) {
delete [] pHand;
}
if(pIDs != IDs) {
delete [] pIDs;
}
pHand = pNewHand;
pIDs = pNewIDs;
uiMaxHands = uiNewMax;
}
//
// Make a handle/fn array
ce::list<WakeUpNode * >::iterator it;
ce::list<WakeUpNode * >::iterator itEnd = pMySelf->m_HandList.end();
HRESULT hr = E_FAIL;
UINT i=1;
pHand[0] = pMySelf->m_hWakeUpEvent;
IDs[0] = 0xFFFF;
for(it = pMySelf->m_HandList.begin(); it != itEnd; ++it) {
pHand[i] = ((*it)->GetHandle());
pIDs[i] = (*it)->GetID();
ASSERT(i<uiMaxHands);
i++;
}
csLock.UnLock();
//
// Wait for something to happen
DWORD dwRet = WaitForMultipleObjects(uiUsedHands, pHand, FALSE, INFINITE);
if(WAIT_FAILED == dwRet || WAIT_TIMEOUT == dwRet) {
TRACEMSG(ZONE_ERROR, (L"SMB_SRV: ERROR! waiting in wakeup thread failed!"));
ASSERT(FALSE);
goto Done;
} else {
UINT uiIdx = dwRet - WAIT_OBJECT_0;
if(uiIdx >= uiMaxHands) {
TRACEMSG(ZONE_ERROR, (L"SMB_SRV: ERROR! wakeup thread woke up on bogus event!"));
ASSERT(FALSE);
goto Done;
}
//
// Execute the proper fn (0 is a special case, just loop or exit)
//
// Note: we need to actually search out this ID before calling the fn()
// because its possible for it to have been deleted in the brief
// instance between the WaitForMultipleObjects and now
if(0 == uiIdx && TRUE == pMySelf->m_fStop) {
ASSERT(0xFFFF == IDs[uiIdx]);
goto Done;
} else if(0 != uiIdx) {
csLock.Lock();
itEnd = pMySelf->m_HandList.end();
for(it = pMySelf->m_HandList.begin(); it != itEnd; ++it) {
if((*it)->GetID() == pIDs[uiIdx]) {
ASSERT(pHand[uiIdx] == ((*it)->GetHandle()));
(*it)->WakeUp();
break;
}
}
csLock.UnLock();
}
}
}
Done:
if(pHand != HandleArray) {
delete [] pHand;
}
if(pIDs != IDs) {
delete [] pIDs;
}
return 0;
}
HRESULT
WakeUpOnEvent::WakeUp()
{
ASSERT(NULL != m_hWakeUpEvent);
SetEvent(m_hWakeUpEvent);
return S_OK;
}
HRESULT
WakeUpOnEvent::RemoveEvent(USHORT usID)
{
CCritSection csLock(&m_csLock);
csLock.Lock();
ce::list<WakeUpNode * >::iterator it;
ce::list<WakeUpNode * >::iterator itEnd = m_HandList.end();
HRESULT hr = E_FAIL;
for(it = m_HandList.begin(); it != itEnd; ++it) {
if(usID == (*it)->GetID()) {
m_HandList.erase(it++);
m_UniqueID.RemoveID(usID);
hr = S_OK;
break;
}
}
WakeUp();
ASSERT(SUCCEEDED(hr));
return hr;
}
struct ERROR_MAPPING {
DWORD dwGLE;
DWORD smbErr;
DWORD NTErr;
};
ERROR_MAPPING g_ERROR_TABLE[] = {
{ERROR_FILE_EXISTS, SMB_ERR(ERRDOS, ERRfilexists), STATUS_OBJECT_NAME_EXISTS},
{ERROR_FILE_NOT_FOUND, SMB_ERR(ERRDOS, ERRbadfile), STATUS_NO_SUCH_FILE},
{ERROR_PATH_NOT_FOUND, SMB_ERR(ERRDOS, ERRbadpath), STATUS_OBJECT_NAME_INVALID},
{ERROR_INVALID_NAME, SMB_ERR(ERRDOS, ERRbadpath), STATUS_OBJECT_NAME_INVALID},
{ERROR_ACCESS_DENIED, SMB_ERR(ERRDOS, ERRnoaccess), STATUS_ACCESS_DENIED},
{ERROR_SHARING_VIOLATION, SMB_ERR(ERRDOS, ERRnoaccess), STATUS_ACCESS_DENIED},
{ERROR_NOT_SUPPORTED, SMB_ERR(ERRSRV, ERRnosupport), STATUS_NOT_SUPPORTED},
{ERROR_NOT_SUPPORTED, SMB_ERR(ERRHRD, ERRnosupport), STATUS_NOT_SUPPORTED},
{ERROR_ALREADY_EXISTS, SMB_ERR(ERRDOS, ERRfilexists), STATUS_OBJECT_NAME_COLLISION},
{ERROR_DIRECTORY, -1, STATUS_FILE_IS_A_DIRECTORY},
{ERROR_INTERNAL_ERROR, SMB_ERR(ERRSRV, ERRerror), STATUS_INTERNAL_ERROR},
{ERROR_INVALID_LEVEL, SMB_ERR(ERRDOS, ERRBadLevel), STATUS_INVALID_LEVEL},
{ERROR_LOCK_FAILED, SMB_ERR(ERRDOS, ERRlock), STATUS_LOCK_NOT_GRANTED},
{ERROR_LOCK_VIOLATION, SMB_ERR(ERRDOS, ERRlock), STATUS_FILE_LOCK_CONFLICT},
{ERROR_INVALID_HANDLE, SMB_ERR(ERRDOS, ERRbadfid), STATUS_INVALID_HANDLE},
{ERROR_FILE_NOT_FOUND, SMB_ERR(ERRSRV, ERRbadfile), STATUS_OBJECT_NAME_NOT_FOUND},
{ERROR_INVALID_LEVEL, SMB_ERR(ERRDOS, ERRBadLevel), STATUS_INVALID_LEVEL},
{ERROR_PATH_NOT_FOUND, SMB_ERR(ERRSRV, ERRbadpath), STATUS_OBJECT_PATH_NOT_FOUND},
{ERROR_INVALID_PASSWORD, SMB_ERR(ERRSRV, ERRbadpw), STATUS_WRONG_PASSWORD},
{-1, -1, STATUS_MORE_PROCESSING_REQUIRED},
{ERROR_ACCESS_DENIED, SMB_ERR(ERRSRV, ERRaccess), STATUS_NETWORK_ACCESS_DENIED},
{ERROR_BAD_NETPATH, SMB_ERR(ERRSRV, ERRinvnetname), STATUS_BAD_NETWORK_NAME},
{ERROR_LOGON_FAILURE, SMB_ERR(ERRSRV, ERRbadpw), STATUS_LOGON_FAILURE},
{ERROR_SHARING_VIOLATION, SMB_ERR(ERRDOS, ERRbadshare), STATUS_SHARING_VIOLATION},
{ERROR_BAD_DEV_TYPE, SMB_ERR(ERRSRV, ERRbadtype), STATUS_BAD_DEVICE_TYPE},
{ERROR_PIPE_NOT_CONNECTED, SMB_ERR(ERRDOS, ERRnoaccess), STATUS_PIPE_NOT_AVAILABLE},
};
ULONG DownLevelMapLength = sizeof(g_ERROR_TABLE) / sizeof(g_ERROR_TABLE[0]);
typedef struct _STATUS_MAP {
USHORT ErrorCode;
NTSTATUS ResultingStatus;
} STATUS_MAP, *PSTATUS_MAP;
STATUS_MAP
Os2ErrorMap[] = {
/* NOTE: the errors in here are somewhat weird. they are used
when a win32 error was needed but one didnt quite fit the
neet consider them hacks & okay to replace */
{ ERROR_DIR_NOT_ROOT, STATUS_NOT_A_DIRECTORY},
/*********************************************************/
{ ERROR_DIRECTORY, STATUS_FILE_IS_A_DIRECTORY},
{ ERROR_INVALID_FUNCTION, STATUS_NOT_IMPLEMENTED },
{ ERROR_FILE_NOT_FOUND, STATUS_NO_SUCH_FILE },
{ ERROR_PATH_NOT_FOUND, STATUS_OBJECT_PATH_NOT_FOUND },
{ ERROR_TOO_MANY_OPEN_FILES,STATUS_TOO_MANY_OPENED_FILES },
{ ERROR_ACCESS_DENIED, STATUS_ACCESS_DENIED },
{ ERROR_INVALID_HANDLE, STATUS_INVALID_HANDLE },
{ ERROR_NOT_ENOUGH_MEMORY, STATUS_INSUFFICIENT_RESOURCES },
{ ERROR_INVALID_ACCESS, STATUS_ACCESS_DENIED },
{ ERROR_INVALID_DATA, STATUS_DATA_ERROR },
{ ERROR_DIR_NOT_EMPTY, STATUS_DIRECTORY_NOT_EMPTY},
{ ERROR_CURRENT_DIRECTORY, STATUS_DIRECTORY_NOT_EMPTY },
{ ERROR_NOT_SAME_DEVICE, STATUS_NOT_SAME_DEVICE },
{ ERROR_NO_MORE_FILES, STATUS_NO_MORE_FILES },
{ ERROR_WRITE_PROTECT, STATUS_MEDIA_WRITE_PROTECTED},
{ ERROR_NOT_READY, STATUS_DEVICE_NOT_READY },
{ ERROR_CRC, STATUS_CRC_ERROR },
{ ERROR_BAD_LENGTH, STATUS_DATA_ERROR },
{ ERROR_NOT_DOS_DISK, STATUS_DISK_CORRUPT_ERROR }, //***
{ ERROR_SECTOR_NOT_FOUND, STATUS_NONEXISTENT_SECTOR },
{ ERROR_OUT_OF_PAPER, STATUS_DEVICE_PAPER_EMPTY},
{ ERROR_SHARING_VIOLATION, STATUS_SHARING_VIOLATION },
{ ERROR_LOCK_VIOLATION, STATUS_FILE_LOCK_CONFLICT },
{ ERROR_WRONG_DISK, STATUS_WRONG_VOLUME },
{ ERROR_NOT_SUPPORTED, STATUS_NOT_SUPPORTED },
{ ERROR_REM_NOT_LIST, STATUS_REMOTE_NOT_LISTENING },
{ ERROR_DUP_NAME, STATUS_DUPLICATE_NAME },
{ ERROR_BAD_NETPATH, STATUS_BAD_NETWORK_PATH },
{ ERROR_NETWORK_BUSY, STATUS_NETWORK_BUSY },
{ ERROR_DEV_NOT_EXIST, STATUS_DEVICE_DOES_NOT_EXIST },
{ ERROR_TOO_MANY_CMDS, STATUS_TOO_MANY_COMMANDS },
{ ERROR_ADAP_HDW_ERR, STATUS_ADAPTER_HARDWARE_ERROR },
{ ERROR_BAD_NET_RESP, STATUS_INVALID_NETWORK_RESPONSE },
{ ERROR_UNEXP_NET_ERR, STATUS_UNEXPECTED_NETWORK_ERROR },
{ ERROR_BAD_REM_ADAP, STATUS_BAD_REMOTE_ADAPTER },
{ ERROR_PRINTQ_FULL, STATUS_PRINT_QUEUE_FULL },
{ ERROR_NO_SPOOL_SPACE, STATUS_NO_SPOOL_SPACE },
{ ERROR_PRINT_CANCELLED, STATUS_PRINT_CANCELLED },
{ ERROR_NETNAME_DELETED, STATUS_NETWORK_NAME_DELETED },
{ ERROR_NETWORK_ACCESS_DENIED, STATUS_NETWORK_ACCESS_DENIED },
{ ERROR_BAD_DEV_TYPE, STATUS_BAD_DEVICE_TYPE },
{ ERROR_BAD_NET_NAME, STATUS_BAD_NETWORK_NAME },
{ ERROR_TOO_MANY_NAMES, STATUS_TOO_MANY_NAMES },
{ ERROR_TOO_MANY_SESS, STATUS_TOO_MANY_SESSIONS },
{ ERROR_SHARING_PAUSED, STATUS_SHARING_PAUSED },
{ ERROR_REQ_NOT_ACCEP, STATUS_REQUEST_NOT_ACCEPTED },
{ ERROR_REDIR_PAUSED, STATUS_REDIRECTOR_PAUSED },
{ ERROR_FILE_EXISTS, STATUS_OBJECT_NAME_COLLISION },
{ ERROR_INVALID_PASSWORD, STATUS_WRONG_PASSWORD },
{ ERROR_INVALID_PARAMETER, STATUS_INVALID_PARAMETER },
{ ERROR_NET_WRITE_FAULT, STATUS_NET_WRITE_FAULT },
{ ERROR_BROKEN_PIPE, STATUS_PIPE_BROKEN },
{ ERROR_OPEN_FAILED, STATUS_OPEN_FAILED },
{ ERROR_BUFFER_OVERFLOW, STATUS_BUFFER_OVERFLOW },
{ ERROR_DISK_FULL, STATUS_DISK_FULL },
{ ERROR_SEM_TIMEOUT, STATUS_IO_TIMEOUT },
{ ERROR_INSUFFICIENT_BUFFER,STATUS_BUFFER_TOO_SMALL },
{ ERROR_INVALID_NAME, STATUS_OBJECT_NAME_INVALID },
{ ERROR_INVALID_LEVEL, STATUS_INVALID_LEVEL },
{ ERROR_BAD_PATHNAME, STATUS_OBJECT_PATH_INVALID }, //*
{ ERROR_BAD_PIPE, STATUS_INVALID_PARAMETER },
{ ERROR_PIPE_BUSY, STATUS_PIPE_NOT_AVAILABLE },
{ ERROR_NO_DATA, STATUS_PIPE_EMPTY },
{ ERROR_PIPE_NOT_CONNECTED, STATUS_PIPE_DISCONNECTED },
{ ERROR_MORE_DATA, STATUS_BUFFER_OVERFLOW },
{ ERROR_VC_DISCONNECTED, STATUS_VIRTUAL_CIRCUIT_CLOSED },
{ ERROR_INVALID_EA_NAME, STATUS_INVALID_EA_NAME },
{ ERROR_EA_LIST_INCONSISTENT,STATUS_EA_LIST_INCONSISTENT },
{ ERROR_EAS_DIDNT_FIT, STATUS_EA_TOO_LARGE },
{ ERROR_EA_FILE_CORRUPT, STATUS_EA_CORRUPT_ERROR },
{ ERROR_EA_TABLE_FULL, STATUS_EA_CORRUPT_ERROR },
{ ERROR_INVALID_EA_HANDLE, STATUS_EA_CORRUPT_ERROR }
};
ULONG Os2ErrorMapLength = sizeof(Os2ErrorMap) / sizeof(Os2ErrorMap[0]);
DWORD ConvertNTToSMB(DWORD dwNT)
{
//
// First find the NT error
UINT i=0;
ERROR_MAPPING *pMapping = g_ERROR_TABLE;
for(i=0; i<DownLevelMapLength; i++) {
if(g_ERROR_TABLE[i].NTErr == dwNT) {
return g_ERROR_TABLE[i].smbErr;
}
}
//
// If there is no mapping, assert
ASSERT(FALSE);
return SMB_ERR(ERRSRV, ERRerror);
}
DWORD ConvertGLEToError(DWORD dwGLE, SMB_PACKET *pSMB)
{
UINT i;
//
// Prefer WinXP's lookup table
if(pSMB->pInSMB->Flags2&__SMB_FLAGS2_NT_STATUS_CODE) {
for (i = 0; i < Os2ErrorMapLength; i++) {
if (Os2ErrorMap[i].ErrorCode == dwGLE) {
return Os2ErrorMap[i].ResultingStatus;
}
}
}
//
// On failure or if NT status isnt set look up in our own lookup table
for(i=0; i<DownLevelMapLength; i++) {
if(g_ERROR_TABLE[i].dwGLE == dwGLE) {
if(pSMB->pInSMB->Flags2&__SMB_FLAGS2_NT_STATUS_CODE) {
return g_ERROR_TABLE[i].NTErr;
} else {
return g_ERROR_TABLE[i].smbErr;
}
}
}
//
// NOT FOUND, please update the lookup table -- this is a bug
ASSERT(FALSE);
if(pSMB->pInSMB->Flags2&__SMB_FLAGS2_NT_STATUS_CODE) {
return STATUS_INTERNAL_ERROR;
} else {
return SMB_ERR(ERRSRV, ERRerror);
}
}
DWORD ConvertHRToError(HRESULT hr, SMB_PACKET *pSMB)
{
DWORD gle = (E_FAIL == hr) ? ERROR_INTERNAL_ERROR : hr & 0xFFFF;
return ConvertGLEToError(gle, pSMB);
}
DWORD
_ERROR_CODE(DWORD NTError, SMB_PACKET* pSMB) {
if(pSMB->pInSMB->Flags2&__SMB_FLAGS2_NT_STATUS_CODE) {
return NTError;
} else {
return ConvertNTToSMB(NTError);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -