|
|
/****************************************************************************
FILE: oactests.cxx
****************************************************************************/
#include <windows.h>
#include <oleext.h>
#include <stdio.h>
#include "oactest.h" // header file generated by MIDL compiler
HRESULT RegisterClassFactory(); HRESULT RevokeClassFactory();
//Prototypes for local functions
HRESULT RegisterLocalServer(REFCLSID rclsid); HRESULT RegisterProxyDll(const char *pszProxyDll); HRESULT UnregisterLocalServer(REFCLSID rclsid); HRESULT UnregisterProxyDll(const char *pszProxyDll);
extern "C" const CLSID CLSID_COAccessControlTest = {0x20692b00,0xe710,0x11cf,{0xaf,0x0b,0x00,0xaa,0x00,0x44,0xfb,0x89}};
extern ULONG g_ulFrequency; long g_LockCount = 0; long g_ObjectCount = 0; DWORD g_dwThreadID; ULONG g_ulFrequency; //+---------------------------------------------------------------------------
//
// Function: DecrementLockCount
//
// Synopsis: Decrements the lock count. The lock count controls the
// registration of the class factory in the class table.
// DecrementLockCount revokes the class factory when the
// lock count is zero.
//
// Called By: ~CAccessControlTest, IClassFactory::LockServer(FALSE).
//
// See Also: ObjectCreated, ObjectDestroyed, IncrementLockCount.
//
//----------------------------------------------------------------------------
void DecrementLockCount() { //Decrement the lock count.
if(InterlockedDecrement(&g_LockCount) == 0) { //When the lock count is decremented to zero,
//revoke the class factory.
RevokeClassFactory(); } }
//+---------------------------------------------------------------------------
//
// Function: IncrementLockCount
//
// Synopsis: Increments the lock count. The lock count controls the
// registration of the class factory in the class table.
// If necessary, IncrementLockCount will reregister the class
// factory in the class table.
//
// Called By: CAccessControlTest, IClassFactory::LockServer(TRUE).
//
// See Also: DecrementLockCount, ObjectCreated, ObjectDestroyed.
//
//----------------------------------------------------------------------------
void IncrementLockCount() { if(g_LockCount == 0) { //Increment the lock count.
InterlockedIncrement(&g_LockCount);
//Reregister the class factory if necessary.
RegisterClassFactory(); } else { //Increment the lock count.
InterlockedIncrement(&g_LockCount); } }
//+---------------------------------------------------------------------------
//
// Function: main
//
// Synopsis: Main entry point for the server application. This function
// initializes the server and processes the message loop.
//
//----------------------------------------------------------------------------
int _cdecl main(int argc, char *argv[]) { HRESULT hr = S_OK; int i; BOOL fRegisterServer = FALSE; BOOL fUnregisterServer = FALSE; BOOL fEmbedding = FALSE; BOOL fHelp = FALSE; MSG msg;
// Parse each item, skip the command name
for (i = 1; i < argc; i++) { if (lstrcmpiA( argv[i], "-Embedding" ) == 0) { //This server has been activated by OLE.
fEmbedding = TRUE; } else if (lstrcmpiA( argv[i], "/REGSERVER" ) == 0) { fRegisterServer = TRUE; } else if (lstrcmpiA( argv[i], "/UNREGSERVER" ) == 0) { fUnregisterServer = TRUE; } else { fHelp = TRUE; } }
if(fHelp == TRUE) { printf("USAGE: server /REGSERVER - Installs server in the registry.\n"); printf(" server /UNREGSERVER - Removes server from the registry.\n"); printf(" server -Embedding - Server was auto-started by OLE.\n"); return 0; } else if(fUnregisterServer == TRUE) { hr = UnregisterLocalServer(CLSID_COAccessControlTest); if(FAILED(hr)) { printf("Failed to remove local server from the registry.\n"); }
hr = UnregisterProxyDll("oactest.dll"); if(FAILED(hr)) { printf("Failed to remove proxy DLL from the registry.\n"); } return 0; }
//Install the local server in the registry.
hr = RegisterLocalServer(CLSID_COAccessControlTest); if(FAILED(hr)) { printf("Failed to install local server in the registry.\n"); }
//Install the proxy DLL in the registry.
hr = RegisterProxyDll("oactest.dll"); if(FAILED(hr)) { printf("Failed to install proxy DLL in the registry.\n"); }
if(fRegisterServer == TRUE) return 0;
//
// Initialize OLE before calling any other OLE functions.
//
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(SUCCEEDED(hr)) { hr = RegisterClassFactory();
if(SUCCEEDED(hr)) {
LARGE_INTEGER liFreq;
QueryPerformanceFrequency(&liFreq);
g_ulFrequency = liFreq.LowPart;
printf("Waiting for client to connect...\n"); g_dwThreadID = GetCurrentThreadId(); // Main message loop. We will remain in the message loop
// until we get a WM_QUIT message.
while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
//If the class factory is still registered in the
//class table, revoke it before we shut down.
RevokeClassFactory(); } else { printf("Failed to register class factory.\n"); }
CoUninitialize(); } else { printf("CoInitialize failed.\n"); }
return 0; }
//+---------------------------------------------------------------------------
//
// Function: ObjectCreated
//
// Synopsis: Increments the object count controlling the main message loop
// of the server process.
//
// Called By: CAccessControlTest, CAccessControlTestFactory.
//
// See Also: DecrementLockCount, IncrementLockCount, ObjectDestroyed.
//
//----------------------------------------------------------------------------
void ObjectCreated() { InterlockedIncrement(&g_ObjectCount); }
//+---------------------------------------------------------------------------
//
// Function: ObjectDestroyed
//
// Synopsis: Decrements the object count controlling the main message loop
// of the server process. When the object count is decremented
// to zero, we post a WM_QUIT message. The main message loop will
// exit and terminate the server process.
//
// Called By: ~CAccessControlTest, ~CAccessControlTestFactory.
//
// See Also: DecrementLockCount, IncrementLockCount, ObjectCreated.
//
//----------------------------------------------------------------------------
void ObjectDestroyed() { if(InterlockedDecrement(&g_ObjectCount) == 0) { //When the last object is released, post a quit message.
PostThreadMessage(g_dwThreadID, WM_QUIT, NULL, NULL); } }
//+---------------------------------------------------------------------------
//
// Function: RegisterLocalServer
//
// Synopsis: Creates a registry key for a local server.
//
// Parameters: rclsid - Supplies the class ID of the local server.
//
//----------------------------------------------------------------------------
HRESULT RegisterLocalServer(REFCLSID rclsid) { HRESULT hr; LONG error; HKEY hKeyCLSID; // key for ...\Classes\CLSID
HKEY hKeyClassID; HKEY hKey; // current key
DWORD dwDisposition; char szServer[MAX_PATH]; char szClassID[39]; unsigned long length;
length = GetModuleFileNameA(0, szServer, sizeof(szServer));
if(length == 0) { hr = HRESULT_FROM_WIN32(GetLastError()); return hr; }
//create the CLSID key
error = RegCreateKeyExA( HKEY_CLASSES_ROOT, "CLSID", 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKeyCLSID, &dwDisposition);
if(!error) { //convert the class ID to a registry key name.
sprintf(szClassID, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", rclsid.Data1, rclsid.Data2, rclsid.Data3, rclsid.Data4[0], rclsid.Data4[1], rclsid.Data4[2], rclsid.Data4[3], rclsid.Data4[4], rclsid.Data4[5], rclsid.Data4[6], rclsid.Data4[7]); //create key for the server class
error = RegCreateKeyExA(hKeyCLSID, szClassID, 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKeyClassID, &dwDisposition);
if(!error) { //create LocalServer32 key.
error = RegCreateKeyExA(hKeyClassID, "LocalServer32", 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &hKey, &dwDisposition);
if(!error) { //Set the server name.
error = RegSetValueExA(hKey, "", 0, REG_SZ, (const unsigned char *)szServer, lstrlenA(szServer) + 1);
// Specifies in the registry that this
// server supports both threading models
error = RegSetValueExA( hKey , "ThreadingModel" , 0 , REG_SZ , (const unsigned char *)"Both" , lstrlenA("Both") + 1);
RegFlushKey(hKey); RegCloseKey(hKey); } RegCloseKey(hKeyClassID); } RegCloseKey(hKeyCLSID); }
if(!error) hr = S_OK; else hr = HRESULT_FROM_WIN32(error);
return hr; }
//+---------------------------------------------------------------------------
//
// Function: RegisterProxyDll
//
// Synopsis: Creates registry entries for the interfaces contained in a
// proxy DLL.
//
// Parameters: pszProxyDll - Supplies the filename of the proxy DLL.
//
// Notes: RegisterProxyDll calls the DllRegisterServer function
// exported from the proxy DLL.
//
//----------------------------------------------------------------------------
HRESULT RegisterProxyDll(const char *pszProxyDll) { HRESULT hr; HINSTANCE hProxyDll; HRESULT (STDAPICALLTYPE *pfnDllRegisterServer)(); hProxyDll = LoadLibraryA(pszProxyDll); if(hProxyDll != 0) { pfnDllRegisterServer = (HRESULT (STDAPICALLTYPE *)()) GetProcAddress(hProxyDll, "DllRegisterServer"); if(pfnDllRegisterServer != 0) hr = (*pfnDllRegisterServer)(); else hr = HRESULT_FROM_WIN32(GetLastError());
FreeLibrary(hProxyDll); } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
//+---------------------------------------------------------------------------
//
// Function: UnregisterLocalServer
//
// Synopsis: Removes the registry key for a local server.
//
// Parameters: rclsid - Supplies the class ID of the local server.
//
//----------------------------------------------------------------------------
HRESULT UnregisterLocalServer(REFCLSID rclsid) { HRESULT hr; HKEY hKeyCLSID; HKEY hKeyClassID; long error; char szClassID[39];
//open the CLSID key
error = RegOpenKeyExA( HKEY_CLASSES_ROOT, "CLSID", 0, KEY_ALL_ACCESS, &hKeyCLSID);
if(!error) { //convert the class ID to a registry key name.
sprintf(szClassID, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", rclsid.Data1, rclsid.Data2, rclsid.Data3, rclsid.Data4[0], rclsid.Data4[1], rclsid.Data4[2], rclsid.Data4[3], rclsid.Data4[4], rclsid.Data4[5], rclsid.Data4[6], rclsid.Data4[7]);
//open registry key for class ID string
error = RegOpenKeyExA( hKeyCLSID, szClassID, 0, KEY_ALL_ACCESS, &hKeyClassID);
if(!error) { //delete LocalServer32 key.
error = RegDeleteKeyA(hKeyClassID, "LocalServer32"); RegCloseKey(hKeyClassID); }
error = RegDeleteKeyA(hKeyCLSID, szClassID); RegCloseKey(hKeyCLSID); }
if(!error) hr = S_OK; else hr = HRESULT_FROM_WIN32(error);
return hr; }
//+---------------------------------------------------------------------------
//
// Function: UnregisterProxyDll
//
// Synopsis: Removes registry entries for the interfaces contained in a
// proxy DLL.
//
// Parameters: pszProxyDll - Supplies the filename of the proxy DLL.
//
// Notes: UnregisterProxyDll calls the DllUnregisterServer function
// exported from the proxy DLL.
//
//----------------------------------------------------------------------------
HRESULT UnregisterProxyDll(const char *pszProxyDll) { HRESULT hr; HINSTANCE hProxyDll; HRESULT (STDAPICALLTYPE *pfnDllUnregisterServer)(); hProxyDll = LoadLibraryA(pszProxyDll); if(hProxyDll != 0) { pfnDllUnregisterServer = (HRESULT (STDAPICALLTYPE *)()) GetProcAddress(hProxyDll, "DllUnregisterServer"); if(pfnDllUnregisterServer != 0) hr = (*pfnDllUnregisterServer)(); else hr = HRESULT_FROM_WIN32(GetLastError()); FreeLibrary(hProxyDll); } else { hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
/* end file actestss.c */
|