📄 scmain.cxx
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
Module Name:
scmain.cxx
Abstract:
Small client driver
--*/
#include <sc.hxx>
#include <mq.h>
#include <scapi.h>
#include <scqman.hxx>
#include <scsman.hxx>
#include <scoverio.hxx>
#include <scqueue.hxx>
#include <scpacket.hxx>
#include <scorder.hxx>
#include <scsrmp.hxx>
#include <service.h>
MachineParameters *gMachine = NULL;
GlobalMemory *gMem = NULL;
ScQueueManager *gQueueMan = NULL;
ScSessionManager *gSessionMan = NULL;
ScOverlappedSupport *gOverlappedSupport = NULL;
ScSequenceCollection *gSeqMan = NULL;
HANDLE ghStartThread = 0; // administration thread
int fApiInitialized = FALSE;
unsigned int gMemCount = 0;
long gfInitStarted = FALSE;
static int scmain_InitializeGlobalSubsystems (void) {
static sfSubsystemsInitialized = FALSE;
if (sfSubsystemsInitialized)
return TRUE;
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Initializing global subsystems...\n");
#endif
WSADATA wsd;
int err = WSAStartup (MAKEWORD(1,1), &wsd);
if (err != 0) {
scerror_Complain (MSMQ_SC_ERRMSG_NOSOCKETS, err);
return FALSE;
}
sfSubsystemsInitialized = TRUE;
return TRUE;
}
#define LANA_UP_FL 0x01
static void scsmain_NetChangeHook(unsigned char lananum, int flags, int unused) {
gMem->Lock ();
int iIntf = scutil_IsLocalTCP (NULL); // This updates the IP table
gMem->Unlock ();
if (iIntf == 1)
SetEvent (ScSessionManager::hNetUP);
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_SESSION, L"NETWORK change (%d interfaces)!!!\n");
#endif
}
static int scmain_InitializeNetworkTracker (void) {
if (! gMachine->fNetworkTracking)
return TRUE;
return scce_RegisterNET((LPVOID)scsmain_NetChangeHook);
}
static ROUTER_LIST *scmain_GetRoutingInfo (HKEY hk) {
ROUTER_LIST *pList = NULL;
for (DWORD dwIndex = 0 ; ; ++dwIndex) {
WCHAR szValueName[_MAX_PATH];
DWORD cchValueName = _MAX_PATH;
DWORD dwType;
WCHAR szRouterQueueName[_MAX_PATH];
DWORD cbRouterNameSize = sizeof(szRouterQueueName);
szRouterQueueName[0] = L'\0';
LONG res = RegEnumValue (hk, dwIndex, szValueName, &cchValueName, NULL, &dwType, (LPBYTE)szRouterQueueName, &cbRouterNameSize);
if (res == ERROR_NO_MORE_ITEMS)
break;
if ((res != ERROR_SUCCESS) || (dwType != REG_SZ) || (cbRouterNameSize > sizeof(szRouterQueueName) - 2) || (cbRouterNameSize & 1))
continue;
szRouterQueueName[cbRouterNameSize/2] = '\0';
ROUTER_LIST *pNew = NULL;
GUID guid;
WCHAR *szEOL = (WCHAR *)scutil_ParseGuidString (szValueName, &guid);
if ((szEOL == NULL) || (*szEOL != '\0')) { // string
unsigned char cb = offsetof (ROUTER_LIST, uri) + (wcslen (szValueName) + 1) * sizeof(WCHAR);
pNew = (ROUTER_LIST *)g_funcAlloc (cb, g_pvAllocData);
if (! pNew)
continue;
pNew->uiFlags = 0;
WCHAR *p = wcschr (szValueName, '*');
if (p) {
pNew->fWildCard = TRUE;
pNew->cUriLen = p - szValueName;
}
wcscpy (pNew->uri, szValueName);
} else { // GUID
pNew = (ROUTER_LIST *)g_funcAlloc (sizeof(ROUTER_LIST), g_pvAllocData);
if (! pNew)
continue;
pNew->uiFlags = 0;
pNew->fGUID = TRUE;
pNew->guid = guid;
}
if (szRouterQueueName[0] != L'\0') {
pNew->szFormatName = svsutil_StringHashAlloc (gMem->pStringHash, szRouterQueueName);
if (NULL == pNew->szFormatName) {
g_funcFree(pNew,g_pvFreeData);
continue;
}
}
else
pNew->szFormatName = NULL;
pNew->pNext = pList;
pList = pNew;
}
return pList;
}
static int scmain_LoadGlobalParameters (void) {
//
// Check ever more global things
//
if (! scmain_InitializeGlobalSubsystems ())
return FALSE;
#if defined (SC_VERBOSE)
scerror_DebugOut (VERBOSE_MASK_INIT, L"Loading global parameters...\n");
#endif
gMem->Lock ();
if (fApiInitialized) {
gMem->Unlock ();
return FALSE;
}
#if defined (SC_COUNT_MEMORY)
gMemCount = svsutil_TotalAlloc ();
#endif
gMachine = new MachineParameters;
if (! gMachine) {
scerror_Complain (MSMQ_SC_ERRMSG_OUTOFMEMORY);
gMem->Unlock();
return FALSE;
}
memset (gMachine, 0, sizeof (*gMachine));
gMachine->hLibLPCRT = LoadLibrary (L"lpcrt.dll");
if (gMachine->hLibLPCRT) {
gMachine->CeGenerateGUID = (CeGenerateGUID_t)GetProcAddress (gMachine->hLibLPCRT, L"CeGenerateGUID");
}
//
// Reset cached local IP table
//
scutil_IsLocalTCP (NULL);
//
// 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) {
scerror_Complain (MSMQ_SC_ERRMSG_CANTOPENREGISTRY, hr);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
HKEY hk2;
if (ERROR_SUCCESS == RegOpenKeyEx (hKey, L"RouteTo", 0, KEY_READ, &hk2)) {
gMachine->pRouteTo = scmain_GetRoutingInfo (hk2);
RegCloseKey (hk2);
}
if (ERROR_SUCCESS == RegOpenKeyEx (hKey, L"RouteFrom", 0, KEY_READ, &hk2)) {
gMachine->pRouteFrom = scmain_GetRoutingInfo (hk2);
RegCloseKey (hk2);
}
if (ERROR_SUCCESS == RegOpenKeyEx (hKey, L"RouteLocal", 0, KEY_READ, &hk2)) {
gMachine->pRouteLocal = scmain_GetRoutingInfo (hk2);
RegCloseKey (hk2);
}
DWORD dwType;
DWORD dwSize = sizeof(gMachine->uiPort);
hr = RegQueryValueEx (hKey, L"Port", NULL, &dwType, (LPBYTE)&gMachine->uiPort, &dwSize);
if ((hr != ERROR_SUCCESS) || (dwType != REG_DWORD) || (dwSize != sizeof(gMachine->uiPort))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("Port"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
dwSize = sizeof(gMachine->uiPingPort);
hr = RegQueryValueEx (hKey, L"PingPort", NULL, &dwType, (LPBYTE)&gMachine->uiPingPort, &dwSize);
if ((hr != ERROR_SUCCESS) || (dwType != REG_DWORD) || (dwSize != sizeof(gMachine->uiPingPort))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("PingPort"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
dwSize = sizeof(gMachine->uiDefaultOutQuotaK);
hr = RegQueryValueEx (hKey, L"DefaultQuota", NULL, &dwType, (LPBYTE)&gMachine->uiDefaultOutQuotaK, &dwSize);
if (hr != ERROR_SUCCESS)
gMachine->uiDefaultOutQuotaK = MSMQ_SC_DEFAULT_OUTGOING_QUOTA;
else if ((dwType != REG_DWORD) || (dwSize != sizeof(gMachine->uiDefaultOutQuotaK))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("DefaultQuota"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
dwSize = sizeof(gMachine->uiDefaultInQuotaK);
hr = RegQueryValueEx (hKey, L"DefaultLocalQuota", NULL, &dwType, (LPBYTE)&gMachine->uiDefaultInQuotaK, &dwSize);
if (hr != ERROR_SUCCESS)
gMachine->uiDefaultInQuotaK = (unsigned long)MSMQ_SC_DEFAULT_INCOMING_QUOTA;
else if ((dwType != REG_DWORD) || (dwSize != sizeof(gMachine->uiDefaultInQuotaK))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("DefaultLocalQuota"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
dwSize = sizeof(gMachine->uiMachineQuotaK);
hr = RegQueryValueEx (hKey, L"MachineQuota", NULL, &dwType, (LPBYTE)&gMachine->uiMachineQuotaK, &dwSize);
if (hr != ERROR_SUCCESS)
gMachine->uiMachineQuotaK = (unsigned long)MSMQ_SC_DEFAULT_MACHINE_QUOTA;
else if ((dwType != REG_DWORD) || (dwSize != sizeof(gMachine->uiMachineQuotaK))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("MachineQuota"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
dwSize = sizeof(gMachine->uiOrderAckWindow);
hr = RegQueryValueEx (hKey, L"OrderedAckWindow", NULL, &dwType, (LPBYTE)&gMachine->uiOrderAckWindow, &dwSize);
if (hr != ERROR_SUCCESS)
gMachine->uiOrderAckWindow = MSMQ_SC_DEFAULT_ORDERWINDOW;
else if ((dwType != REG_DWORD) || (dwSize != sizeof(gMachine->uiOrderAckWindow))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("OrderedAckWindow"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
dwSize = sizeof(gMachine->uiOrderAckScale);
hr = RegQueryValueEx (hKey, L"OrderedAckScale", NULL, &dwType, (LPBYTE)&gMachine->uiOrderAckScale, &dwSize);
if (hr != ERROR_SUCCESS)
gMachine->uiOrderAckScale = MSMQ_SC_DEFAULT_ORDERACKSCALE;
else if ((dwType != REG_DWORD) || (dwSize != sizeof(gMachine->uiOrderAckScale))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("OrderedAckScale"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
dwSize = sizeof(gMachine->uiPingTimeout);
hr = RegQueryValueEx (hKey, L"PingTimeout", NULL, &dwType, (LPBYTE)&gMachine->uiPingTimeout, &dwSize);
if (hr != ERROR_SUCCESS)
gMachine->uiPingTimeout = MSMQ_SC_DEFAULT_PINGTIMEOUT;
else if ((dwType != REG_DWORD) || (dwSize != sizeof(gMachine->uiPingTimeout))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("PingTimeout"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
dwSize = sizeof(GUID);
hr = RegQueryValueEx (hKey, L"QueueManagerGUID", NULL, &dwType, (LPBYTE)&gMachine->guid, &dwSize);
if ((hr != ERROR_SUCCESS) || (dwType != REG_BINARY) || (dwSize != sizeof(GUID))) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("QueueManagerGUID"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
WCHAR szOutFRSFormat[2 * _MAX_PATH];
dwSize = sizeof(szOutFRSFormat);
hr = RegQueryValueEx (hKey, L"OutFRSQueue", NULL, &dwType, (LPBYTE)szOutFRSFormat, &dwSize);
if ((hr == ERROR_SUCCESS) && (dwType == REG_SZ) && (szOutFRSFormat[0] != L'\0'))
gMachine->lpszOutFRSQueueFormatName = svsutil_wcsdup (szOutFRSFormat);
WCHAR szDebugFormat[2 * _MAX_PATH];
dwSize = sizeof(szDebugFormat);
hr = RegQueryValueEx (hKey, L"DebugQueue", NULL, &dwType, (LPBYTE)szDebugFormat, &dwSize);
if ((hr == ERROR_SUCCESS) && (dwType == REG_SZ) && (szDebugFormat[0] != L'\0'))
gMachine->lpszDebugQueueFormatName = svsutil_wcsdup (szDebugFormat);
WCHAR szDirectoryPath[_MAX_PATH];
dwSize = sizeof(szDirectoryPath);
hr = RegQueryValueEx (hKey, L"BaseDir", NULL, &dwType, (LPBYTE)szDirectoryPath, &dwSize);
if ((hr != ERROR_SUCCESS) || (dwType != REG_SZ) || (szDirectoryPath[0] == L'\0')) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDKEY, TEXT("BaseDir"), hr);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
int ccDirLen = wcslen (szDirectoryPath);
while ((ccDirLen > 1) && szDirectoryPath[ccDirLen-1] == L'\\')
szDirectoryPath[--ccDirLen] = L'\0';
int iMaxRetry = -1;
dwSize = sizeof(iMaxRetry);
hr = RegQueryValueEx (hKey, L"FSMaxTimeout", NULL, &dwType, (BYTE *)&iMaxRetry, &dwSize);
if ((hr != ERROR_SUCCESS) || (iMaxRetry < 0) || (dwType != REG_DWORD))
iMaxRetry = MSMQ_SC_DEFAULT_FSTIMEOUT;
DWORD fAttr = GetFileAttributes(szDirectoryPath);
for (int iCount = 0 ; (iCount < iMaxRetry) && (fAttr == 0xFFFFFFFF) ; ++iCount, (fAttr = GetFileAttributes(szDirectoryPath)))
Sleep(1000);
if ((fAttr == 0xFFFFFFFF) || (! (fAttr & FILE_ATTRIBUTE_DIRECTORY)) ||
(fAttr & FILE_ATTRIBUTE_READONLY)) {
scerror_Complain (MSMQ_SC_ERRMSG_INVALIDDIR, szDirectoryPath);
RegCloseKey (hKey);
delete gMachine;
gMachine = NULL;
gMem->Unlock();
return FALSE;
}
gMachine->lpszDirName = svsutil_wcsdup (szDirectoryPath);
int fIPSelected = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -