|
|
//+---------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1993 - 1994.
//
// File: olebind.cxx
//
// Contents: Test OLE COM
//
// Classes:
//
// Functions: TestSetMoniker
// ` DoTest
// ConvertPath
// CreateFile
// CleanUpFiles
// InitFiles
// main
//
// History: 31-Dec-93 ErikGav Chicago port
// 15-Nov-94 BruceMa Added this header
// 15-Nov-94 BruceMa Make long file name test work on
// Chicago
// 11-Jan-95 BruceMa Chicago now use the NT alorithm for
// short file names
// 17-Jan-95 BruceMa Modify registry so olebind works on
// Cairo when running multi-threaded
//
//----------------------------------------------------------------------
#include <windows.h>
#include "widewrap.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <io.h>
#include <ole2.h>
#include <com.hxx>
#include "olebind.hxx"
#include "tmoniker.h"
#include <tchar.h>
const char *szOleBindError = "OLEBIND - Fatal Error"; char wszErrBuf[512];
#pragma hdrstop
BOOL SetRegistryThreadingModel(WCHAR *peszFile, WCHAR *pwszThreadingModel); BOOL ResetRegistryThreadingModel(WCHAR *pwszFile);
#define FILE_SHARE_DELETE 0x00000004
#define INPROC_PATH1 L"p1.ut1"
#define INPROC_PATH2 L"p2.ut1"
#define LOCAL_SERVER_PATH1 L"p1.ut2"
#define LOCAL_SERVER_PATH2 L"p2.ut2"
#define LOCAL_SERVER_PATH4 L"p2.ut4"
WCHAR InprocPath1[MAX_PATH]; WCHAR InprocPath2[MAX_PATH]; WCHAR LocalServerPath1[MAX_PATH]; WCHAR LocalServerPath2[MAX_PATH]; WCHAR LocalServerPath4[MAX_PATH];
#define LONG_SHORT_DIR L"\\LongDire"
#define LONG_DIR L"\\LongDirectory"
#define LONG_SHORT_NAME L"\\Short.Fil"
#define LONG_LONG_NAME L"\\LongFileName.File"
#define LONG_LONG_SHORT_EQUIV L"\\LongFi~1.Fil"
WCHAR LongDir[MAX_PATH]; WCHAR LongDirShort[MAX_PATH]; WCHAR LongDirLong[MAX_PATH]; WCHAR LongDirLongSe[MAX_PATH];
// DON"T MODIFY THIS
const DWORD dwRESERVED = 0l;
// string version of process id
WCHAR wszPid[10];
int TestSetMoniker(IUnknown *punk) { HRESULT hr; XOleObject poleobject; XMoniker pmk; XMalloc pIMalloc; XBindCtx pbc;
hr = punk->QueryInterface(IID_IOleObject, (void **) &poleobject);
// Create an item moniker to the object
hr = CreateItemMoniker(L"\\", L"1", &pmk);
TEST_FAILED_HR(FAILED(hr), "TestSetMoniker:CreateItemMoniker failed")
// Set the moniker
hr = poleobject->SetMoniker(OLEWHICHMK_CONTAINER, pmk);
TEST_FAILED_HR(FAILED(hr), "TestSetMoniker:SetMoniker failed")
pmk.Set(NULL);
// Get the moniker back
hr = poleobject->GetMoniker(OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pmk);
TEST_FAILED_HR(FAILED(hr), "TestSetMoniker:GetMoniker failed")
// Get & Verify name is as expected
WCHAR *pwszName;
hr = CreateBindCtx(0, &pbc);
TEST_FAILED_HR(FAILED(hr), "CreateBindCtx TestSetMoniker:GetDisplayName failed!")
hr = pmk->GetDisplayName(pbc, NULL, &pwszName);
TEST_FAILED_HR(FAILED(hr), "TestSetMoniker:GetDisplayName failed")
TEST_FAILED((wcscmp(pwszName, L"\\1") != 0), "TestSetMoniker: Returned name mismatch!\n")
// Test OleIsRunning
hr = OleIsRunning(poleobject);
TEST_FAILED_HR(FAILED(hr), "OleIsRunning call failed")
// Free resources
hr = CoGetMalloc(MEMCTX_TASK, &pIMalloc);
TEST_FAILED_HR(FAILED(hr), "CoGetMalloc failed")
pIMalloc->Free(pwszName);
return 0; }
static GUID CLSID_Invalid = {0xfffffffe,0xffff,0xffff,{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}};
// prototypes for private entry points. These are here to support VB94.
STDAPI CoGetState(IUnknown **ppUnkState); STDAPI CoSetState(IUnknown *pUnkState);
int DoTest( GUID guidToTest, LPWSTR pszPath1, LPWSTR pszPath2) { XMoniker pmnk; // ptr to moniker
XUnknown pUnk; XUnknown punk; XUnknown pUnkTheSame; XOleItemContainer poleitmcon; XDispatch pdispatch;
XBindCtx pbc1; XBindCtx pbc2; XUnknown pUnkState1; XUnknown pUnkState2; XUnknown pUnkState3; XUnknown pUnkState4; XUnknown pUnkState5;
HRESULT hr; DWORD grfOpt = 0;
// Test the private CoSetState/CoGetState APIs. We just need an
// IUnknown so we will use a BindCtx for this.
// test Set/Get
hr = CreateBindCtx(0, &pbc1); TEST_FAILED_HR(FAILED(hr), "Create BindCtx 1 failed"); hr = pbc1->QueryInterface(IID_IUnknown, (void **)&pUnkState1); TEST_FAILED_HR(FAILED(hr), "QI for IUnknown 1 failed.");
hr = CoSetState(pUnkState1); TEST_FAILED_HR(hr != S_OK, "CoSetState failed.");
hr = CoGetState(&pUnkState2); TEST_FAILED_HR(hr != S_OK, "CoGetState failed."); if ((IUnknown *)pUnkState2 != (IUnknown *)pUnkState1) TEST_FAILED(TRUE, "GetState returned wrong value.\n");
// test replacement
hr = CreateBindCtx(0, &pbc2); TEST_FAILED_HR(FAILED(hr), "Create BindCtx 2 failed"); hr = pbc2->QueryInterface(IID_IUnknown, (void **)&pUnkState3); TEST_FAILED_HR(FAILED(hr), "QI for IUnknown 2 failed.");
hr = CoSetState(pUnkState3); TEST_FAILED_HR(hr != S_OK, "CoSetState failed.");
hr = CoGetState(&pUnkState4); TEST_FAILED_HR(hr != S_OK, "CoGetState failed."); if ((IUnknown *)pUnkState4 != (IUnknown *)pUnkState3) TEST_FAILED(TRUE, "GetState returned wrong value.");
// test Set/Get NULL
hr = CoSetState(NULL); TEST_FAILED_HR(hr != S_OK, "CoSetState NULL failed.");
hr = CoGetState(&pUnkState5); TEST_FAILED_HR(hr != S_FALSE, "CoGetState NULL failed."); if ((IUnknown *)pUnkState5 != NULL) TEST_FAILED(TRUE, "GetState NULL returned wrong value.");
// Test for a bogus class
hr = CoGetClassObject(CLSID_Invalid, CLSCTX_SERVER, NULL, IID_IClassFactory, (void **) &pUnk);
TEST_FAILED_HR(SUCCEEDED(hr), "CoGetClassObject succeed on invalid class!");
// Bind to something that does not exist either in the registry
// or anywhere else.
hr = CreateFileMoniker(L"C:\\KKK.KKK", &pmnk); hr = BindMoniker(pmnk, grfOpt, IID_IUnknown, (void **)&pUnk); pmnk.Set(NULL);
TEST_FAILED_HR(SUCCEEDED(hr), "Succeeded binding a moniker to a file that doesn't exist!");
/*
* Create a file moniker to start with */
hr = CreateFileMoniker(pszPath1, &pmnk);
TEST_FAILED_HR(FAILED(hr), "CreateFileMoniker Failed");
hr = BindMoniker(pmnk, grfOpt, IID_IUnknown, (void **)&pUnk);
TEST_FAILED_HR(FAILED(hr), "BindMoniker to file Failed")
// Confirm bind to same object produces same object pointer
hr = BindMoniker(pmnk, grfOpt, IID_IUnknown, (void **)&pUnkTheSame);
TEST_FAILED_HR(FAILED(hr), "BindMoniker to file Failed") #ifdef NOT_YET
TEST_FAILED((pUnkTheSame != pUnk), "Object pointers not ==\n") #endif // NOT_YET
pUnkTheSame.Set(NULL); pmnk.Set(NULL);
/*
* OK - we've bound to the IUnknown interface, lets * QueryInterface to something more interesting (for test reasons) */ hr = pUnk->QueryInterface(IID_IOleItemContainer, (LPVOID FAR*) &poleitmcon);
TEST_FAILED_HR(FAILED(hr), "Query Interface Failed")
/*
* Make sure we get an error when QI'ing for something the server * does not support. */ hr = pUnk->QueryInterface(IID_IDispatch, (LPVOID FAR*) &pdispatch);
TEST_FAILED_HR(SUCCEEDED(hr), "QueryInterface to unsupported interface")
pdispatch.Set(NULL); pUnk.Set(NULL);
/*
* Call get the class ID using IPersistFile */
hr = poleitmcon->GetObject(L"1", 1, NULL, IID_IUnknown, (void **) &punk);
TEST_FAILED_HR(FAILED(hr), "GetObject Failed")
TEST_FAILED((punk == NULL), "GetObject returned a NULL for punk\n")
poleitmcon.Set(NULL);
if (TestSetMoniker(punk)) { return 1; }
hr = punk->QueryInterface(IID_IOleLink, (LPVOID FAR*) &poleitmcon);
TEST_FAILED_HR(SUCCEEDED(hr), "Query Interface to invalid interface succeeded")
punk.Set(NULL);
// Do moniker tests:
if (TestBindCtx()) { return TRUE; }
if (TestROT(guidToTest)) { return TRUE; }
return TestMoniker(pszPath1, pszPath2); }
// TRUE on failure
BOOL TestPrematureDeath() { XMoniker pmnk; XUnknown pUnk; HRESULT hr; TCHAR tszFileName[MAX_PATH+1]; HANDLE hTouchFile; SYSTEMTIME st1, st2; FILETIME ft1, ft2; LONG l; DWORD dw;
ZeroMemory(&st1, sizeof(st1)); ZeroMemory(&st2, sizeof(st2));
hr = CreateFileMoniker(LocalServerPath4, &pmnk); TEST_FAILED_HR(FAILED(hr), "CreateFileMoniker Failed")
GetSystemDirectory(tszFileName, MAX_PATH+1); _tcscat(tszFileName, TEXT("\\failtst.tst"));
hTouchFile = CreateFileT(tszFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hTouchFile == INVALID_HANDLE_VALUE) { wsprintfA(&wszErrBuf[0], "Couldn't open touch file - err = %x.\n", GetLastError()); MessageBoxA(NULL, &wszErrBuf[0], szOleBindError, MB_OK); return TRUE; }
GetSystemTime(&st1); WriteFile(hTouchFile, &st1, sizeof(st1), &dw, NULL);
l = GetTickCount();
// This takes awhile, so tell the user
printf("SCM dead server test (60 sec) started\n");
hr = BindMoniker(pmnk, 0, IID_IUnknown, (void **)&pUnk);
TEST_FAILED_HR((hr != CO_E_SERVER_EXEC_FAILURE), "Unexpected hr from BindMoniker in premature death test")
// Tell the BVT guys
printf("SCM dead server test succeeded\n");
//
// The above bind should have caused fail.exe to execute and write a new
// time to the file as proof of execution.
//
SetFilePointer(hTouchFile, 0, NULL, FILE_BEGIN); ReadFile(hTouchFile, &st2, sizeof(st2), &dw, NULL); CloseHandle(hTouchFile);
DeleteFileT(tszFileName);
SystemTimeToFileTime(&st1, &ft1); SystemTimeToFileTime(&st2, &ft2); if (0 == CompareFileTime(&ft1, &ft2)) { wsprintfA(&wszErrBuf[0], "Test not configured properly: PROGID50(fail.exe) did not run."); MessageBoxA(NULL, &wszErrBuf[0], szOleBindError, MB_OK); return TRUE; }
if (GetTickCount() - l > 2*60*1000) { wsprintfA(&wszErrBuf[0], "Premature death test failed: too long to detect death."); MessageBoxA(NULL, &wszErrBuf[0], szOleBindError, MB_OK); return TRUE; }
return FALSE; }
char * ConvertPath(LPWSTR pwsz) { static char szPath[MAX_PATH]; wcstombs(szPath, pwsz, wcslen(pwsz) + 1); return szPath; }
int CreateFile(LPWSTR pwszPath) { // Try to create the file
int fh = _creat(ConvertPath(pwszPath), _S_IWRITE|S_IREAD);
// Did file create fail?
if (fh != -1) { // Write some data to file -- makes sure docfile won't delete
// the file.
_write(fh, "This is a test file\n", sizeof("This is a test file\n"));
// No -- then set to success and close the newly created file
_close(fh); fh = 0; }
return fh; }
void CleanUpFiles(void) { // Delete all the test files.
remove(ConvertPath(InprocPath1)); remove(ConvertPath(InprocPath2)); remove(ConvertPath(LocalServerPath1)); remove(ConvertPath(LocalServerPath2)); remove(ConvertPath(LocalServerPath4)); remove(ConvertPath(LongDirShort)); remove(ConvertPath(LongDirLong)); #if !defined(_CHICAGO_)
RemoveDirectory(LongDir); #else
RemoveDirectory(ConvertPath(LongDir)); #endif
}
int InitFiles(void) { BOOL fRet;
TCHAR szCurDir[MAX_PATH]; TCHAR szTmpLongDir[MAX_PATH]; WCHAR wcCurDir[MAX_PATH]; WCHAR wcLong[MAX_PATH], *pwcEnd;
DWORD cCurDir = GetCurrentDirectory(MAX_PATH, szCurDir);
#ifdef UNICODE
wcscpy(wcCurDir, szCurDir); #else
mbstowcs(wcCurDir, szCurDir, MAX_PATH); #endif
// Is the current directory the root of a drive?
if (wcCurDir[cCurDir - 1] == '\\') { // We bring the string on char back to take into account
// the fact the string we will concatenate begins with a slash.
wcCurDir[cCurDir - 1] = 0; }
// get the pid. we use the pid to identify the files for a particular
// run of the test (so we may run multiple instances simultaneously
// without interference).
DWORD dwPid = GetCurrentProcessId(); char szPid[9]; _itoa(dwPid, szPid, 16); wszPid[0] = L'\\'; #if defined(_CHICAGO_)
szPid[4] = '\0'; // This is an all platform bug, but zap for Chicago.
#endif
mbstowcs(&wszPid[1], szPid, strlen(szPid)+1);
wcscpy(InprocPath1, wcCurDir); wcscat(InprocPath1, wszPid); wcscat(InprocPath1, INPROC_PATH1);
wcscpy(InprocPath2, wcCurDir); wcscat(InprocPath2, wszPid); wcscat(InprocPath2, INPROC_PATH2);
wcscpy(LocalServerPath1, wcCurDir); wcscat(LocalServerPath1, wszPid); wcscat(LocalServerPath1, LOCAL_SERVER_PATH1);
wcscpy(LocalServerPath2, wcCurDir); wcscat(LocalServerPath2, wszPid); wcscat(LocalServerPath2, LOCAL_SERVER_PATH2);
wcscpy(LocalServerPath4, wcCurDir); wcscat(LocalServerPath4, wszPid); wcscat(LocalServerPath4, LOCAL_SERVER_PATH4);
wcscpy(wcLong, wcCurDir); wcscat(wcLong, LONG_DIR); wcscpy(LongDir, wcLong); pwcEnd = wcLong+wcslen(wcLong);
wcscpy(pwcEnd, LONG_SHORT_NAME); wcscpy(LongDirShort, wcLong);
wcscpy(pwcEnd, LONG_LONG_NAME); wcscpy(LongDirLong, wcLong);
#ifdef _CHICAGO_
wcscpy(LongDirLongSe, wcCurDir); wcscat(LongDirLongSe, LONG_DIR);
#else
wcscpy(pwcEnd, LONG_LONG_SHORT_EQUIV); wcscpy(LongDirLongSe, wcLong); #endif // _CHICAGO_
// Delete any files that exist
CleanUpFiles();
// Create a file for each test file needed.
TEST_FAILED(CreateFile(InprocPath1), "Couldn't create first test file!\n"); TEST_FAILED(CreateFile(InprocPath2), "Couldn't create second test file!\n"); TEST_FAILED(CreateFile(LocalServerPath1), "Couldn't create third test file!\n"); TEST_FAILED(CreateFile(LocalServerPath2), "Couldn't create fourth test file!\n"); TEST_FAILED(CreateFile(LocalServerPath4), "Couldn't create fifth test file!\n");
#if !defined(_CHICAGO_)
fRet = CreateDirectory(LongDir, NULL); #else
fRet = CreateDirectory(ConvertPath(LongDir), NULL); #endif
TEST_FAILED(!fRet, "Couldn't create long directory\n"); TEST_FAILED(CreateFile(LongDirShort), "Couldn't create short file in long directory\n"); TEST_FAILED(CreateFile(LongDirLong), "Couldn't create long file in long directory\n");
#ifdef UNICODE
TEST_FAILED(!GetShortPathName(LongDirLong, LongDirLongSe, sizeof(LongDirLongSe)), "Couldn't GetShortPathname of long directory\n"); #else
TEST_FAILED(!GetShortPathNameT(ConvertPath(LongDirLong), szCurDir, sizeof(szCurDir)), "Couldn't GetShortPathname of long directory\n");
mbstowcs(LongDirLongSe, szCurDir, strlen(szCurDir)+1);
#endif
return 0; }
DWORD CallCoInitUninit(void *) { // Initialize
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (SUCCEEDED(hr)) { // Uninitialize
CoUninitialize(); }
// Return value from function. Note that this is not really used because
// there is a potential race
return (DWORD) hr; }
BOOL DoFreeThreadMultiInitTest(void) { //
// Get an OLE object in another process
//
IClassFactory *pIClassFactory;
HRESULT hr = CoGetClassObject( CLSID_AdvBnd, CLSCTX_LOCAL_SERVER, NULL, IID_IClassFactory, (void **) &pIClassFactory);
TEST_FAILED_HR((hr != NOERROR), "DoFreeThreadMultiInitTest CoGetClassObject")
//
// Create another thread which does a matching call to
// CoInitialize/Uninitialize and then exits.
//
// Create the thread
DWORD dwIdUnused;
HANDLE hInitThread = CreateThread( NULL, // Security - none
0, // Stack - use the same as the primary thread
CallCoInitUninit, // Entry point for thread
NULL, // Parameter to the thread - not used.
0, // Run this thread immediately (if not sooner).
&dwIdUnused); // Id of thread - not used.
// Did the create succeed?
TEST_FAILED_LAST_ERROR((NULL == hInitThread), "DoFreeThreadMultiInitTest CreateThread")
// Wait for the thread to do its work
DWORD dwRes = WaitForSingleObject(hInitThread, INFINITE);
// Did something terrible happen?
TEST_FAILED_LAST_ERROR((WAIT_FAILED == dwRes), "DoFreeThreadMultiInitTest WaitForSingleObject")
// Get the result from the thread
BOOL fGetExitCode = GetExitCodeThread(hInitThread, (DWORD *) &hr);
TEST_FAILED_LAST_ERROR(!fGetExitCode, "DoFreeThreadMultiInitTest GetExitCodeThread")
// Free handles we no longer need
CloseHandle(hInitThread);
//
// Validate the object we originally got is still alive and well.
//
IUnknown *punk;
hr = pIClassFactory->CreateInstance(NULL, IID_IUnknown, (void **) &punk);
TEST_FAILED_HR((hr != NOERROR), "DoFreeThreadMultiInitTest CoGetClassObject")
// Free the objects we got in this routine.
pIClassFactory->Release(); punk->Release();
return FALSE; }
//+--------------------------------------------------------------
// Function: Main
//
// Synopsis: Executes the BasicBnd test
//
// Effects: None
//
//
// Returns: Exits with exit code 0 if success, 1 otherwise
//
// History: 05-Mar-92 Sarahj Created
//
//---------------------------------------------------------------
int _cdecl main(int argc, char *argv[]) { BOOL fFailed = FALSE; HRESULT hr;
if (argc > 1) { if (!strcmp(argv[1], "M")) goto multithreading; }
// BUGBUG: 1-18-95 To be implemented BruceMa
// Correlate the platform we're running on and the platform
// we built for
// Write thread mode to initialization file.
fFailed = !WriteProfileString( TEXT("TestSrv"), TEXT("ThreadMode"), TEXT("ApartmentThreaded"));
if (fFailed) { wsprintfA(&wszErrBuf[0], "Failed writing TestSrv profile string."); MessageBoxA(NULL, &wszErrBuf[0], szOleBindError, MB_OK); goto exit_main; }
fFailed = !WriteProfileString( TEXT("OleSrv"), TEXT("ThreadMode"), TEXT("ApartmentThreaded"));
if (fFailed) { wsprintfA(&wszErrBuf[0], "Failed writing OleSrv profile string."); MessageBoxA(NULL, &wszErrBuf[0], szOleBindError, MB_OK); goto exit_main; }
// Set up test files
fFailed = InitFiles(); if (fFailed) { goto exit_main; }
// Test repeated calls to CoInitialize
hr = CoInitialize(NULL);
TEST_FAILED_HR(FAILED(hr), "CoInitialize Failed")
// must be called before any other OLE API
hr = OleInitialize(NULL);
TEST_FAILED_HR(FAILED(hr), "OleInitialize Failed")
// Call CoUnitialize and see how the rest of the program works!
CoUninitialize();
// Test stdmalloc
if (fFailed = TestStdMalloc()) { goto exit_init; }
fFailed = DoTest(CLSID_BasicBnd, InprocPath1, InprocPath2);
if (fFailed) { printf( "\nOLE failed in Single Threaded Apartment pass.\n" ); goto exit_init; }
printf("BasicBnd tests succeeded\n");
fFailed = DoTest(CLSID_AdvBnd, LocalServerPath1, LocalServerPath1);
if (fFailed) { printf( "\nOLE failed in Single Threaded Apartment pass.\n" ); goto exit_init; }
printf("AdvBnd tests succeeded\n");
if (TestPrematureDeath()) { printf("\nOLE failed testing server premature death.\n"); goto exit_init; }
OleUninitialize();
CleanUpFiles();
multithreading:
#ifdef MULTI_THREADING
// Run the whole thing all over again.
// Write thread mode to initialization file.
fFailed = !WriteProfileString( TEXT("TestSrv"), TEXT("ThreadMode"), TEXT("ApartmentThreaded"));
if (fFailed) { wsprintfA(&wszErrBuf[0], "Failed writing TestSrv profile string."); MessageBoxA(NULL, &wszErrBuf[0], szOleBindError, MB_OK); goto exit_main; }
fFailed = !WriteProfileString( TEXT("OleSrv"), TEXT("ThreadMode"), TEXT("MultiThreaded"));
if (fFailed) { wsprintfA(&wszErrBuf[0], "Failed writing OleSrv profile string."); MessageBoxA(NULL, &wszErrBuf[0], szOleBindError, MB_OK); goto exit_main; }
// Set up test files
if (InitFiles()) { fFailed = TRUE; goto exit_main; }
// Mark the dll in the registry as "ThreadingdModel: Free"
if (!SetRegistryThreadingModel(InprocPath1, L"Free")) { wsprintfA(&wszErrBuf[0], "Failed trying to set reg ThreadingModel."); MessageBoxA(NULL, &wszErrBuf[0], szOleBindError, MB_OK); goto exit_main; }
// Test repeated calls to CoInitialize
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
TEST_FAILED_HR(FAILED(hr), "CoInitializeEx Multi Threaded Failed")
// must be called before any other OLE API
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
TEST_FAILED_HR(FAILED(hr), "CoInitializeEx Multi Threaded Failed")
// Call CoUnitialize and see how the rest of the program works!
CoUninitialize();
// Test stdmalloc
if (fFailed = TestStdMalloc()) { goto exit_init; }
fFailed = DoTest(CLSID_BasicBnd, InprocPath1, InprocPath2); if (fFailed) { printf( "\nOLE failed in Multi Threaded Apartment pass.\n" ); goto exit_init; }
fFailed = DoTest(CLSID_AdvBnd, LocalServerPath1, LocalServerPath1);
if (fFailed) { printf( "\nOLE failed in Multi Threaded Apartment pass.\n" ); goto exit_init; }
// Do CoInitialize/Uninitialize on second thread to make sure
// that other threads initialize/uninitialize do not effect
// the running of the test.
if (fFailed = DoFreeThreadMultiInitTest()) { printf( "\nOLE failed in Multi Threaded InitTest.\n" ); goto exit_init; }
#endif // MULTI_THREADING
exit_init:
CoUninitialize();
// Remove the dll's threading model registration
ResetRegistryThreadingModel(InprocPath1);
exit_main:
CleanUpFiles();
if (!fFailed) { printf("\nOLE: PASSED\n"); } else { printf("\nOLE: FAILED\n"); }
return fFailed; }
//+--------------------------------------------------------
//
// Function: SetRegistryThreadingModel
//
// Algorithm: Set the threading model for the InprocServer32 associated
// with the file pwszFile tp pwszThreadingModel
//
// History: 17-Jan-95 BruceMa Created
//
//---------------------------------------------------------
BOOL SetRegistryThreadingModel(WCHAR *pwszFile, WCHAR *pwszThreadingModel) { DWORD dwRESERVED = 0; WCHAR wszExt[8]; HKEY hKey; WCHAR wszProgId[32]; DWORD dwValueType; WCHAR wszCLSID[64]; HKEY hClsidKey; HKEY hInproc32Key; ULONG cbValue;
// Strip the extension off the file name
int k = wcslen(pwszFile) - 1; while (k > 0 && pwszFile[k] != L'.') { k--; } if (k >= 0 && pwszFile[k] == L'.') { for (int j = 0; pwszFile[k]; j++, k++) { wszExt[j] = pwszFile[k]; } wszExt[j] = L'\0'; } else { return FALSE; }
// Open the key for the specified extension
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, wszExt, dwRESERVED, KEY_READ, &hKey) != ERROR_SUCCESS) { return FALSE; }
// Read the ProgId for the extension
cbValue = 32; if (RegQueryValueEx(hKey, NULL, NULL, &dwValueType, (LPBYTE) wszProgId, &cbValue) != ERROR_SUCCESS) { CloseHandle(hKey); return FALSE; }
// Open the ProgIdKey
CloseHandle(hKey); if (RegOpenKeyEx(HKEY_CLASSES_ROOT, wszProgId, dwRESERVED, KEY_READ, &hKey) != ERROR_SUCCESS) { return FALSE; }
// Open the associated CLSID key
if (RegOpenKeyEx(hKey, L"CLSID", dwRESERVED, KEY_READ, &hClsidKey) != ERROR_SUCCESS) { CloseHandle(hKey); return FALSE; }
// Read the CLSID associated with the ProgId
cbValue = 128; if (RegQueryValueEx(hClsidKey, NULL, NULL, &dwValueType, (LPBYTE) wszCLSID, &cbValue) != ERROR_SUCCESS) { CloseHandle(hClsidKey); CloseHandle(hKey); return FALSE; }
// Open the HKEY_CLASSES_ROOT\CLSID key
CloseHandle(hClsidKey); CloseHandle(hKey); if (RegOpenKeyEx(HKEY_CLASSES_ROOT, L"CLSID", dwRESERVED, KEY_READ, &hKey) != ERROR_SUCCESS) { return FALSE; }
// Open the key to our clsid
if (RegOpenKeyEx(hKey, wszCLSID, dwRESERVED, KEY_READ, &hClsidKey) != ERROR_SUCCESS) { CloseHandle(hKey); return FALSE; }
// Open the InprocServer32 key
CloseHandle(hKey); if (RegOpenKeyEx(hClsidKey, L"InprocServer32", dwRESERVED, KEY_SET_VALUE, &hInproc32Key) != ERROR_SUCCESS) { CloseHandle(hClsidKey); return FALSE; }
// Set the threading model for this InprocServer32 key
CloseHandle(hClsidKey); if (RegSetValueEx(hInproc32Key, L"ThreadingModel", dwRESERVED, REG_SZ, (LPBYTE) pwszThreadingModel, (wcslen(pwszThreadingModel)+1) * sizeof(WCHAR)) != ERROR_SUCCESS) { CloseHandle(hInproc32Key); return FALSE; }
// Close the InprocServer32 key and return success
CloseHandle(hInproc32Key); return TRUE; }
//+--------------------------------------------------------
//
// Function: ResetRegistryThreadingModel
//
// Algorithm: Remove the threading model for the InprocServer32 associated
// with the file pwszFile
//
// History: 17-Jan-95 BruceMa Created
//
//---------------------------------------------------------
BOOL ResetRegistryThreadingModel(WCHAR *pwszFile) { DWORD dwRESERVED = 0; WCHAR wszExt[8]; HKEY hKey; WCHAR wszProgId[32]; DWORD dwValueType; WCHAR wszCLSID[64]; HKEY hClsidKey; HKEY hInproc32Key; ULONG cbValue;
// Strip the extension off the file name
int k = wcslen(pwszFile) - 1; while (k > 0 && pwszFile[k] != L'.') { k--; } if (k >= 0 && pwszFile[k] == L'.') { for (int j = 0; pwszFile[k]; j++, k++) { wszExt[j] = pwszFile[k]; } wszExt[j] = L'\0'; } else { return FALSE; }
// Open the key for the specified extension
if (RegOpenKeyEx(HKEY_CLASSES_ROOT, wszExt, dwRESERVED, KEY_READ, &hKey) != ERROR_SUCCESS) { return FALSE; }
// Read the ProgId for the extension
cbValue = 32; if (RegQueryValueEx(hKey, NULL, NULL, &dwValueType, (LPBYTE) wszProgId, &cbValue) != ERROR_SUCCESS) { CloseHandle(hKey); return FALSE; }
// Open the ProgIdKey
CloseHandle(hKey); if (RegOpenKeyEx(HKEY_CLASSES_ROOT, wszProgId, dwRESERVED, KEY_READ, &hKey) != ERROR_SUCCESS) { return FALSE; }
// Open the associated CLSID key
if (RegOpenKeyEx(hKey, L"CLSID", dwRESERVED, KEY_READ, &hClsidKey) != ERROR_SUCCESS) { CloseHandle(hKey); return FALSE; }
// Read the CLSID associated with the ProgId
cbValue = 128; if (RegQueryValueEx(hClsidKey, NULL, NULL, &dwValueType, (LPBYTE) wszCLSID, &cbValue) != ERROR_SUCCESS) { CloseHandle(hClsidKey); CloseHandle(hKey); return FALSE; }
// Open the HKEY_CLASSES_ROOT\CLSID key
CloseHandle(hClsidKey); CloseHandle(hKey); if (RegOpenKeyEx(HKEY_CLASSES_ROOT, L"CLSID", dwRESERVED, KEY_READ, &hKey) != ERROR_SUCCESS) { return FALSE; }
// Open the key to our clsid
if (RegOpenKeyEx(hKey, wszCLSID, dwRESERVED, KEY_READ, &hClsidKey) != ERROR_SUCCESS) { CloseHandle(hKey); return FALSE; }
// Open the InprocServer32 key
CloseHandle(hKey); if (RegOpenKeyEx(hClsidKey, L"InprocServer32", dwRESERVED, KEY_SET_VALUE, &hInproc32Key) != ERROR_SUCCESS) { CloseHandle(hClsidKey); return FALSE; }
// Reset the threading model for this InprocServer32 key
CloseHandle(hClsidKey); if (RegDeleteValue(hInproc32Key, TEXT("ThreadingModel")) != ERROR_SUCCESS) { CloseHandle(hInproc32Key); return FALSE; }
// Close the InprocServer32 key and return success
CloseHandle(hInproc32Key); return TRUE; }
|