📄 scmain.cxx
字号:
memset (&qp, 0, sizeof(qp));
qp.uiPrivacyLevel = MQ_PRIV_LEVEL_NONE;
qp.uiQuotaK = (unsigned int)-1;
qp.bIsIncoming = TRUE;
qp.bIsDeadLetter = TRUE;
qp.bIsProtected = TRUE;
WCHAR szPathName[_MAX_PATH];
wsprintf (szPathName, L".\\private$\\" SC_GUID_FORMAT, SC_GUID_ELEMENTS((&gMachine->guid)));
WCHAR szLabel[_MAX_PATH];
wsprintf (szLabel, L"Dead Letter Queue for " SC_GUID_FORMAT, SC_GUID_ELEMENTS((&gMachine->guid)));
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Dead letter queue not found. Creating using pathname %s\n", szPathName);
#endif
HRESULT hr = MQ_OK;
gQueueMan->pQueueDLQ = gQueueMan->MakeIncomingQueue (szPathName, szLabel, &qp, 0, &hr);
if (! gQueueMan->pQueueDLQ) {
scerror_Complain (MSMQ_SC_ERRMSG_CANTMAKEINTQUEUE, szPathName, hr);
fError = TRUE;
}
}
if ((! fError) && (! gQueueMan->pQueueJournal)) {
ScQueueParms qp;
memset (&qp, 0, sizeof(qp));
qp.uiPrivacyLevel = MQ_PRIV_LEVEL_NONE;
qp.uiQuotaK = (unsigned int)-1;
qp.bIsIncoming = TRUE;
qp.bIsMachineJournal = TRUE;
qp.bIsProtected = TRUE;
WCHAR szPathName[_MAX_PATH];
wsprintf (szPathName, L".\\private$\\" SC_GUID_FORMAT, SC_GUID_ELEMENTS((&gMachine->guid)));
WCHAR szLabel[_MAX_PATH];
wsprintf (szLabel, L"Machine Journal Queue for " SC_GUID_FORMAT, SC_GUID_ELEMENTS((&gMachine->guid)));
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Machine journal queue not found. Creating using pathname %s\n", szPathName);
#endif
HRESULT hr = MQ_OK;
gQueueMan->pQueueJournal = gQueueMan->MakeIncomingQueue (szPathName, szLabel, &qp, 0, &hr);
if (! gQueueMan->pQueueJournal) {
scerror_Complain (MSMQ_SC_ERRMSG_CANTMAKEINTQUEUE, szPathName, hr);
fError = TRUE;
}
}
if ((! fError) && (! gQueueMan->pQueueOrderAck)) {
ScQueueParms qp;
memset (&qp, 0, sizeof(qp));
qp.uiPrivacyLevel = MQ_PRIV_LEVEL_NONE;
qp.uiQuotaK = (unsigned int)-1;
qp.bIsIncoming = TRUE;
qp.bIsOrderAck = TRUE;
qp.bIsProtected = TRUE;
qp.bIsInternal = TRUE;
WCHAR szPathName[_MAX_PATH];
wcscpy (szPathName, L".\\" MSMQ_SC_PATHNAME_PRIVATE L"\\" MSMQ_SC_ORDERQUEUENAME);
WCHAR szLabel[_MAX_PATH];
wsprintf (szLabel, L"Order ACK Queue for " SC_GUID_FORMAT, SC_GUID_ELEMENTS((&gMachine->guid)));
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Order ACK queue not found. Creating using pathname %s\n", szPathName);
#endif
HRESULT hr = MQ_OK;
gQueueMan->pQueueOrderAck = gQueueMan->MakeIncomingQueue (szPathName, szLabel, &qp, 0, &hr);
if (! gQueueMan->pQueueOrderAck) {
scerror_Complain (MSMQ_SC_ERRMSG_CANTMAKEINTQUEUE, szPathName, hr);
fError = TRUE;
}
}
if (! fError) {
if (gQueueMan->pQueueOutFRS && ((! gMachine->lpszOutFRSQueueFormatName) ||
(wcsicmp (gQueueMan->pQueueOutFRS->lpszFormatName, gMachine->lpszOutFRSQueueFormatName) != 0))) {
gQueueMan->pQueueOutFRS->qp.bIsProtected = FALSE;
gQueueMan->pQueueOutFRS->qp.bIsOutFRS = FALSE;
gQueueMan->pQueueOutFRS->UpdateFile ();
gQueueMan->pQueueOutFRS = NULL; // But let it flush...
}
if (gMachine->lpszOutFRSQueueFormatName && (! gQueueMan->pQueueOutFRS)) {
ScQueueParms qp;
memset (&qp, 0, sizeof(qp));
qp.uiPrivacyLevel = MQ_PRIV_LEVEL_NONE;
qp.uiQuotaK = (unsigned int)-1;
qp.bIsOutFRS = TRUE;
qp.bIsProtected = TRUE;
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Out-FRS queue not found. Creating using formatname %s\n", gMachine->lpszOutFRSQueueFormatName);
#endif
HRESULT hr = MQ_OK;
gQueueMan->pQueueOutFRS = gQueueMan->MakeOutgoingQueue (gMachine->lpszOutFRSQueueFormatName, &qp, &hr);
if (! gQueueMan->pQueueOutFRS) {
scerror_Complain (MSMQ_SC_ERRMSG_CANTMAKEINTQUEUE, gMachine->lpszOutFRSQueueFormatName, hr);
fError = TRUE;
}
}
}
if (fError) {
scerror_Complain (MSMQ_SC_ERRMSG_INITSHUTDOWN);
scmain_GeneralCleanup (TRUE);
gMem->Unlock ();
return FALSE;
}
if (! gSeqMan->Load()) {
scerror_Complain (MSMQ_SC_ERRMSG_FAILORDER);
scmain_GeneralCleanup (TRUE);
gMem->Unlock ();
return FALSE;
}
gSessionMan->Start ();
gQueueMan->Start ();
fApiInitialized = TRUE;
glServiceState = SERVICE_STATE_ON;
gMem->Unlock ();
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Initialization of queue manager complete...\n");
#endif
scerror_Inform (MSMQ_SC_ERRMSG_MSMQSTARTED);
return TRUE;
}
DWORD WINAPI scmain_ShutdownThread (LPVOID lpv) {
BOOL fReInitialize = (BOOL) lpv;
if (! fApiInitialized)
return FALSE;
glServiceState = SERVICE_STATE_SHUTTING_DOWN;
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Commencing queue manager shutdown...\n");
#endif
//shut down the tracker thread
scce_UnregisterNET ();
//
// Wait for all systems to enter stable shutdownable state
//
gMem->Lock ();
for (int i = 0 ; i < 10 ; ++i) {
if (((! gOverlappedSupport) || (! gOverlappedSupport->fBusy)) &&
((! gQueueMan) || (! gQueueMan->fBusy)) &&
((! gSessionMan) || (! gSessionMan->fBusy)) &&
((! gSeqMan) || (! gSeqMan->fBusy)))
break;
gMem->Unlock ();
Sleep(100);
gMem->Lock ();
}
if (! fApiInitialized) {
gMem->Unlock ();
return FALSE;
}
if (i == 10)
scerror_Inform (MSMQ_SC_ERRMSG_SHUTDOWNUNSTABLE);
fApiInitialized = FALSE;
gfInitStarted = FALSE;
scmain_GeneralCleanup (fReInitialize);
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"On startup: %d bytes, on shutdown: %d bytes\n", gMemCount, svsutil_TotalAlloc());
#endif
gMem->Unlock ();
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Queue manager shutdown complete...\n");
#endif
scerror_Inform (MSMQ_SC_ERRMSG_MSMQSTOPPED);
glServiceState = SERVICE_STATE_OFF;
return TRUE;
}
int scmain_Shutdown(BOOL fReInitialize) {
DWORD dwRet = 0;
// need to spin a thread in the event we're shutting down Wininet because of TLS issues.
HANDLE h = CreateThread(NULL, 0, scmain_ShutdownThread, (LPVOID)fReInitialize, 0, NULL);
if (h) {
WaitForSingleObject(h,INFINITE);
GetExitCodeThread(h,&dwRet);
CloseHandle(h);
}
return dwRet;
}
GlobalMemory::GlobalMemory (void) {
pPacketMem = svsutil_AllocFixedMemDescr (sizeof (ScPacket), SCPACKET_PACKETS_PER_BLOCK);
pTreeNodeMem = svsutil_AllocFixedMemDescr (sizeof (SVSTNode), SVSUTIL_TREE_INITIAL);
pAckNodeMem = svsutil_AllocFixedMemDescr (sizeof (SentPacket), SVSUTIL_TREE_INITIAL);
pStringHash = svsutil_GetStringHash (0, FALSE);
pTimeoutTree = SVSNewTree(pTreeNodeMem);
pTimer = svsutil_AllocAttrTimer ();
fInitialized = pTimer && pTimeoutTree && pStringHash && pAckNodeMem && pTreeNodeMem && pPacketMem;
}
void GlobalMemory::Cycle (BOOL fReInitialize) {
Lock ();
//
// Free all resources
//
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
unsigned int uiBase = svsutil_TotalAlloc ();
#endif
if (pTimeoutTree) {
delete pTimeoutTree;
pTimeoutTree = NULL;
}
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Timeout tree: %d bytes freed\n", uiBase - svsutil_TotalAlloc ());
unsigned int uiFree, uiTotal;
#endif
if (pPacketMem) {
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
uiFree = uiTotal = 0;
svsutil_GetFixedStats (pPacketMem, &uiFree, &uiTotal);
scerror_DebugOut (VERBOSE_MASK_INIT, L"Packet heap: %d blocks not freed out of %d total\n", uiTotal - uiFree, uiTotal);
#endif
svsutil_ReleaseFixedNonEmpty (pPacketMem);
pPacketMem = NULL;
}
if (pTreeNodeMem) {
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
uiFree = uiTotal = 0;
svsutil_GetFixedStats (pTreeNodeMem, &uiFree, &uiTotal);
scerror_DebugOut (VERBOSE_MASK_INIT, L"Tree nodes: %d blocks not freed out of %d total\n", uiTotal - uiFree, uiTotal);
#endif
svsutil_ReleaseFixedNonEmpty (pTreeNodeMem);
pTreeNodeMem = NULL;
}
if (pAckNodeMem) {
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
uiFree = uiTotal = 0;
svsutil_GetFixedStats (pAckNodeMem, &uiFree, &uiTotal);
scerror_DebugOut (VERBOSE_MASK_INIT, L"Ack nodes: %d blocks not freed out of %d total\n", uiTotal - uiFree, uiTotal);
#endif
svsutil_ReleaseFixedNonEmpty (pAckNodeMem);
pAckNodeMem = NULL;
}
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
uiBase = svsutil_TotalAlloc ();
#endif
if (pTimer) {
svsutil_FreeAttrTimer (pTimer);
pTimer = NULL;
}
if (pStringHash) {
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Attribute timer: %d bytes freed\n", uiBase - svsutil_TotalAlloc ());
unsigned int uiEntries = 0;
svsutil_GetStringHashStats (pStringHash, &uiEntries);
scerror_DebugOut (VERBOSE_MASK_INIT, L"String hash entries: %d unfreed\n", uiEntries);
#endif
svsutil_DestroyStringHash (pStringHash);
pStringHash = NULL;
}
// Note - do destroy remoteAlloc heaps, by design. These will get destroyed
// as processes exit or when MSMQ itself unloads and gMem object is deleted.
#if defined (SC_COUNT_MEMORY) && defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"lowest memory on shutdown: %d bytes\n", svsutil_TotalAlloc());
#endif
//
// And then rebuild anew...
//
if (fReInitialize) {
pPacketMem = svsutil_AllocFixedMemDescr (sizeof (ScPacket), SCPACKET_PACKETS_PER_BLOCK);
pTreeNodeMem = svsutil_AllocFixedMemDescr (sizeof (SVSTNode), SVSUTIL_TREE_INITIAL);
pAckNodeMem = svsutil_AllocFixedMemDescr (sizeof (SentPacket), SVSUTIL_TREE_INITIAL);
pStringHash = svsutil_GetStringHash (0, FALSE);
pTimeoutTree = SVSNewTree(pTreeNodeMem);
pTimer = svsutil_AllocAttrTimer ();
fInitialized = pTimer && pTimeoutTree && pStringHash && pAckNodeMem && pTreeNodeMem && pPacketMem;
}
Unlock ();
}
extern "C" int wmain(int argc, WCHAR **argv) {
svsutil_Initialize ();
g_funcDebugOut = scerror_AssertOut;
if ((argc > 1) && (wcsicmp (argv[1], L"-start") == 0)) {
if (! scmain_Init ())
return MSMQ_SC_ERR_INITFAILED;
SVSUTIL_ASSERT (fApiInitialized);
}
scapi_EnterInputLoop ();
if (fApiInitialized) {
if (! scmain_Shutdown (FALSE))
return MSMQ_SC_ERR_FINALFAILED;
}
return 0;
}
DWORD WINAPI scmain_Startup (LPVOID pvParam) {
DWORD dwRet = (DWORD)scmain_Init ();
ghStartThread =0;
if (dwRet == 0) {
// on failure we only will set state=OFF in the event that we're starting up.
// We do this because theoretically we could already be in state=SERVICE_STATE_ON,
// in which case we'd want to leave the state as-is.
InterlockedCompareExchange((LONG*)&glServiceState,SERVICE_STATE_OFF,SERVICE_STATE_STARTING_UP);
}
return dwRet;
}
extern "C" DWORD WINAPI scmain_StartDLL (LPVOID lpParm) {
if (InterlockedExchange (&gfInitStarted, TRUE))
return FALSE;
g_funcDebugOut = scerror_AssertOut;
SVSUTIL_ASSERT(glServiceState == SERVICE_STATE_OFF);
glServiceState = SERVICE_STATE_STARTING_UP;
for ( ; ; ) {
//
// First, deal with registry
//
HKEY hKey;
LONG hr = RegOpenKeyEx (HKEY_LOCAL_MACHINE, MSMQ_SC_REGISTRY_KEY, 0, KEY_READ | KEY_WRITE, &hKey);
if (hr != ERROR_SUCCESS)
break;
DWORD dwType = 0;
DWORD dwSize = sizeof(DWORD);
DWORD dwStartAtBoot = FALSE;
hr = RegQueryValueEx (hKey, L"CEStartAtBoot", NULL, &dwType, (LPBYTE)&dwStartAtBoot, &dwSize);
if ((hr != ERROR_SUCCESS) || (dwType != REG_DWORD) || (dwSize != sizeof(DWORD)) || (! dwStartAtBoot))
break;
DWORD dwTID = 0;
ghStartThread = CreateThread (NULL, 0, scmain_Startup, NULL, 0, &dwTID);
if (ghStartThread)
CloseHandle (ghStartThread);
break;
}
if (!ghStartThread)
glServiceState = SERVICE_STATE_OFF;
if (! scce_RegisterDLL ()) {
glServiceState = SERVICE_STATE_OFF;
gfInitStarted = FALSE;
return FALSE;
}
return TRUE;
}
extern "C" HRESULT scmain_StopDLL (void) {
if (! scce_UnregisterDLL ())
return MQ_ERROR;
return MQ_OK;
}
int scmain_ForceExit (void) {
// make sure creation thread isn't running when we try to pull DLL down.
if (ghStartThread)
WaitForSingleObject(ghStartThread,INFINITE);
// there's the possible condition scmain_Startup sets ghStartThread=NULL but
// hasn't exited.
Sleep(100);
scmain_Shutdown (FALSE);
scmain_StopDLL ();
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -