示例#1
0
/* Abort the installation (called as an immediate custom action) */
MSIDLLEXPORT AbortMsiImmediate( MSIHANDLE hInstall ) {
    DWORD rv;
	DWORD dwSize = 0;
	LPTSTR sReason = NULL;
	LPTSTR sFormatted = NULL;
	MSIHANDLE hRecord = NULL;
	LPTSTR cAbortReason = _T("ABORTREASON");

	rv = MsiGetProperty( hInstall, cAbortReason, _T(""), &dwSize );
	if(rv != ERROR_MORE_DATA) goto _cleanup;

	sReason = new TCHAR[ ++dwSize ];

	rv = MsiGetProperty( hInstall, cAbortReason, sReason, &dwSize );

	if(rv != ERROR_SUCCESS) goto _cleanup;

    hRecord = MsiCreateRecord(3);
	MsiRecordClearData(hRecord);
	MsiRecordSetString(hRecord, 0, sReason);

	dwSize = 0;

	rv = MsiFormatRecord(hInstall, hRecord, "", &dwSize);
	if(rv != ERROR_MORE_DATA) goto _cleanup;

	sFormatted = new TCHAR[ ++dwSize ];

	rv = MsiFormatRecord(hInstall, hRecord, sFormatted, &dwSize);

	if(rv != ERROR_SUCCESS) goto _cleanup;

	MsiCloseHandle(hRecord);

	hRecord = MsiCreateRecord(3);
	MsiRecordClearData(hRecord);
	MsiRecordSetInteger(hRecord, 1, ERR_ABORT);
	MsiRecordSetString(hRecord,2, sFormatted);
	MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecord);

_cleanup:
	if(sFormatted) delete[] sFormatted;
	if(hRecord) MsiCloseHandle( hRecord );
	if(sReason) delete[] sReason;

	return ~ERROR_SUCCESS;
}
示例#2
0
static PyObject*
record_cleardata(msiobj* record, PyObject *args)
{
    int status = MsiRecordClearData(record->h);
    if (status != ERROR_SUCCESS)
        return msierror(status);

    Py_RETURN_NONE;
}
示例#3
0
文件: _msi.c 项目: cocoatomo/CTPython
static PyObject*
record_cleardata(msiobj* record, PyObject *args)
{
    int status = MsiRecordClearData(record->h);
    if (status != ERROR_SUCCESS)
	return msierror(status);

    Py_INCREF(Py_None);
    return Py_None;
}
示例#4
0
void ShowMsiError( MSIHANDLE hInstall, DWORD errcode, DWORD param ){
	MSIHANDLE hRecord;

	hRecord = MsiCreateRecord(3);
	MsiRecordClearData(hRecord);
	MsiRecordSetInteger(hRecord, 1, errcode);
	MsiRecordSetInteger(hRecord, 2, param);

	MsiProcessMessage( hInstall, INSTALLMESSAGE_ERROR, hRecord );
	
	MsiCloseHandle( hRecord );
}
extern "C" UINT __stdcall DevEnvNotRunning(MSIHANDLE hInstall)
{
    UINT errCode;
    DevEnvStatus status;
    bool cancelled = false;
    MSIHANDLE hMessage = NULL;

    status = GetDevEnvStatus(hInstall);
    while (!cancelled && status == StatusRunning)
    {
        if (hMessage == NULL)
        {
            hMessage = MsiCreateRecord(2);
        }

        MsiRecordClearData(hMessage);
        MsiRecordSetInteger(hMessage, 1, messageIdCloseDevEnv);

        int result = MsiProcessMessage(
            hInstall,
            static_cast<INSTALLMESSAGE>(INSTALLMESSAGE_WARNING | MB_RETRYCANCEL),
            hMessage);
        cancelled = (result == IDCANCEL);

        if (!cancelled)
        {
            status = GetDevEnvStatus(hInstall);
        }
    }

    switch (status)
    {
    case StatusNotRunning:
        errCode = ERROR_SUCCESS;
        break;

    case StatusRunning:
        errCode = ERROR_INSTALL_USEREXIT;
        break;

    case StatusError:
    default:
        Log(LogError, hInstall, L"Failed to search for running DevEnv.exe process.");
        errCode = ERROR_INSTALL_FAILURE;
        break;
    }

    if (hMessage != NULL) MsiCloseHandle(hMessage);

    return errCode;
}
示例#6
0
extern "C" void ReportMessage(int level, LPCSTR msg, LPCSTR str, LPCWSTR wstr, DWORD dw) {
    if(dwReporterType == REPORT_PRINTF)
		printf("%s:[%s][%S][%d]\n", (msg?msg:""), (str?str:""), (wstr?wstr:L""), dw);
	else if(dwReporterType == REPORT_MSI && hMsiHandle && level == 0) {
		MSIHANDLE hRec = MsiCreateRecord(5);
        
		MsiRecordClearData(hRec);
		MsiRecordSetStringA(hRec,1,(msg)?msg:"");
		MsiRecordSetStringA(hRec,2,(str)?str:"");
		MsiRecordSetStringW(hRec,3,(wstr)?wstr:L"");
		MsiRecordSetInteger(hRec,4,dw);

		MsiProcessMessage(hMsiHandle,INSTALLMESSAGE_ACTIONDATA,hRec);

		MsiCloseHandle(hRec);
	}
}
示例#7
0
extern "C" void SetMsiReporter(LPCSTR strAction, LPCSTR strDesc,DWORD h) {
	dwReporterType = REPORT_MSI;
	hMsiHandle = h;

#ifdef DONT_NEED
    /* this is performed in the Wix installer */
	MSIHANDLE hRec = MsiCreateRecord(4);
  
    MsiRecordClearData(hRec);
	MsiRecordSetStringA(hRec,1,strAction);
	MsiRecordSetStringA(hRec,2,strDesc);
	MsiRecordSetStringA(hRec,3,"[1]:([2])([3])([4])");

	MsiProcessMessage(h,INSTALLMESSAGE_ACTIONSTART, hRec);
	
    MsiCloseHandle(hRec);
#endif
}
示例#8
0
static void test_msirecord(void)
{
    DWORD r, sz;
    INT i;
    MSIHANDLE h;
    char buf[10];
    WCHAR bufW[10];
    const char str[] = "hello";
    const WCHAR strW[] = { 'h','e','l','l','o',0};
    char filename[MAX_PATH];

    /* check behaviour with an invalid record */
    r = MsiRecordGetFieldCount(0);
    ok(r==-1, "field count for invalid record not -1\n");
    SetLastError(0);
    r = MsiRecordIsNull(0, 0);
    ok(r==0, "invalid handle not considered to be non-null...\n");
    ok(GetLastError()==0, "MsiRecordIsNull set LastError\n");
    r = MsiRecordGetInteger(0,0);
    ok(r == MSI_NULL_INTEGER, "got integer from invalid record\n");
    r = MsiRecordSetInteger(0,0,0);
    ok(r == ERROR_INVALID_HANDLE, "MsiRecordSetInteger returned wrong error\n");
    r = MsiRecordSetInteger(0,-1,0);
    ok(r == ERROR_INVALID_HANDLE, "MsiRecordSetInteger returned wrong error\n");
    SetLastError(0);
    h = MsiCreateRecord(-1);
    ok(h==0, "created record with -1 elements\n");
    h = MsiCreateRecord(0x10000);
    ok(h==0, "created record with 0x10000 elements\n");
    /* doesn't set LastError */
    ok(GetLastError()==0, "MsiCreateRecord set last error\n");
    r = MsiRecordClearData(0);
    ok(r == ERROR_INVALID_HANDLE, "MsiRecordClearData returned wrong error\n");
    r = MsiRecordDataSize(0,0);
    ok(r == 0, "MsiRecordDataSize returned wrong error\n");


    /* check behaviour of a record with 0 elements */
    h = MsiCreateRecord(0);
    ok(h!=0, "couldn't create record with zero elements\n");
    r = MsiRecordGetFieldCount(h);
    ok(r==0, "field count should be zero\n");
    r = MsiRecordIsNull(h,0);
    ok(r, "new record wasn't null\n");
    r = MsiRecordIsNull(h,1);
    ok(r, "out of range record wasn't null\n");
    r = MsiRecordIsNull(h,-1);
    ok(r, "out of range record wasn't null\n");
    r = MsiRecordDataSize(h,0);
    ok(r==0, "size of null record is 0\n");
    sz = sizeof buf;
    strcpy(buf,"x");
    r = MsiRecordGetString(h, 0, buf, &sz);
    ok(r==ERROR_SUCCESS, "failed to get null string\n");
    ok(sz==0, "null string too long\n");
    ok(buf[0]==0, "null string not set\n");

    /* same record, but add an integer to it */
    r = MsiRecordSetInteger(h, 0, 0);
    ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 0\n");
    r = MsiRecordIsNull(h,0);
    ok(r==0, "new record is null after setting an integer\n");
    r = MsiRecordDataSize(h,0);
    ok(r==sizeof(DWORD), "size of integer record is 4\n");
    r = MsiRecordSetInteger(h, 0, 1);
    ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 1\n");
    r = MsiRecordSetInteger(h, 1, 1);
    ok(r == ERROR_INVALID_PARAMETER, "set integer at 1\n");
    r = MsiRecordSetInteger(h, -1, 0);
    ok(r == ERROR_INVALID_PARAMETER, "set integer at -1\n");
    r = MsiRecordIsNull(h,0);
    ok(r==0, "new record is null after setting an integer\n");
    r = MsiRecordGetInteger(h, 0);
    ok(r == 1, "failed to get integer\n");

    /* same record, but add a string to it */
    r = MsiRecordSetString(h, 0, NULL);
    ok(r == ERROR_SUCCESS, "Failed to set null string at 0\n");
    r = MsiRecordIsNull(h, 0);
    ok(r == TRUE, "null string not null field\n");
    r = MsiRecordSetString(h, 0, "");
    ok(r == ERROR_SUCCESS, "Failed to set empty string at 0\n");
    r = MsiRecordIsNull(h, 0);
    ok(r == TRUE, "null string not null field\n");
    r = MsiRecordSetString(h,0,str);
    ok(r == ERROR_SUCCESS, "Failed to set string at 0\n");
    r = MsiRecordGetInteger(h, 0);
    ok(r == MSI_NULL_INTEGER, "should get invalid integer\n");
    r = MsiRecordDataSize(h,0);
    ok(r==sizeof str-1, "size of string record is strlen\n");
    buf[0]=0;
    sz = sizeof buf;
    r = MsiRecordGetString(h,0,buf,&sz);
    ok(r == ERROR_SUCCESS, "Failed to get string at 0\n");
    ok(0==strcmp(buf,str), "MsiRecordGetString returned the wrong string\n");
    ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n");
    buf[0]=0;
    sz = sizeof str - 2;
    r = MsiRecordGetString(h,0,buf,&sz);
    ok(r == ERROR_MORE_DATA, "small buffer should yield ERROR_MORE_DATA\n");
    ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n");
    ok(0==strncmp(buf,str,sizeof str-3), "MsiRecordGetString returned the wrong string\n");
    ok(buf[sizeof str - 3]==0, "string wasn't nul terminated\n");

    buf[0]=0;
    sz = sizeof str;
    r = MsiRecordGetString(h,0,buf,&sz);
    ok(r == ERROR_SUCCESS, "wrong error\n");
    ok(sz == sizeof str-1, "MsiRecordGetString returned the wrong length\n");
    ok(0==strcmp(buf,str), "MsiRecordGetString returned the wrong string\n");


    memset(bufW, 0, sizeof bufW);
    sz = 5;
    r = MsiRecordGetStringW(h,0,bufW,&sz);
    ok(r == ERROR_MORE_DATA, "wrong error\n");
    ok(sz == 5, "MsiRecordGetString returned the wrong length\n");
    ok(0==memcmp(bufW,strW,8), "MsiRecordGetString returned the wrong string\n");

    sz = 0;
    bufW[0] = 'x';
    r = MsiRecordGetStringW(h,0,bufW,&sz);
    ok(r == ERROR_MORE_DATA, "wrong error\n");
    ok(sz == 5, "MsiRecordGetString returned the wrong length\n");
    ok('x'==bufW[0], "MsiRecordGetString returned the wrong string\n");

    memset(buf, 0, sizeof buf);
    sz = 5;
    r = MsiRecordGetStringA(h,0,buf,&sz);
    ok(r == ERROR_MORE_DATA, "wrong error\n");
    ok(sz == 5, "MsiRecordGetString returned the wrong length\n");
    ok(0==memcmp(buf,str,4), "MsiRecordGetString returned the wrong string\n");

    sz = 0;
    buf[0] = 'x';
    r = MsiRecordGetStringA(h,0,buf,&sz);
    ok(r == ERROR_MORE_DATA, "wrong error\n");
    ok(sz == 5, "MsiRecordGetString returned the wrong length\n");
    ok('x'==buf[0], "MsiRecordGetString returned the wrong string\n");

    /* same record, check we can wipe all the data */
    r = MsiRecordClearData(h);
    ok(r == ERROR_SUCCESS, "Failed to clear record\n");
    r = MsiRecordClearData(h);
    ok(r == ERROR_SUCCESS, "Failed to clear record again\n");
    r = MsiRecordIsNull(h,0);
    ok(r, "cleared record wasn't null\n");

    /* same record, try converting strings to integers */
    i = MsiRecordSetString(h,0,"42");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == 42, "should get invalid integer\n");
    i = MsiRecordSetString(h,0,"-42");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == -42, "should get invalid integer\n");
    i = MsiRecordSetString(h,0," 42");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
    i = MsiRecordSetString(h,0,"42 ");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
    i = MsiRecordSetString(h,0,"42.0");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
    i = MsiRecordSetString(h,0,"0x42");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == MSI_NULL_INTEGER, "should get invalid integer\n");
    i = MsiRecordSetString(h,0,"1000000000000000");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == -1530494976, "should get truncated integer\n");
    i = MsiRecordSetString(h,0,"2147483647");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == 2147483647, "should get maxint\n");
    i = MsiRecordSetString(h,0,"-2147483647");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == -2147483647, "should get -maxint-1\n");
    i = MsiRecordSetString(h,0,"4294967297");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == 1, "should get one\n");
    i = MsiRecordSetString(h,0,"foo");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == MSI_NULL_INTEGER, "should get zero\n");
    i = MsiRecordSetString(h,0,"");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == MSI_NULL_INTEGER, "should get zero\n");
    i = MsiRecordSetString(h,0,"+1");
    ok(i == ERROR_SUCCESS, "Failed to set string at 0\n");
    i = MsiRecordGetInteger(h, 0);
    ok(i == MSI_NULL_INTEGER, "should get zero\n");

    /* same record, try converting integers to strings */
    r = MsiRecordSetInteger(h, 0, 32);
    ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 32\n");
    sz = 1;
    r = MsiRecordGetString(h, 0, NULL, &sz);
    ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
    ok(sz == 2, "length wrong\n");
    buf[0]=0;
    sz = sizeof buf;
    r = MsiRecordGetString(h, 0, buf, &sz);
    ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
    ok(0==strcmp(buf,"32"), "failed to get string from integer\n");
    r = MsiRecordSetInteger(h, 0, -32);
    ok(r == ERROR_SUCCESS, "Failed to set integer at 0 to 32\n");
    buf[0]=0;
    sz = 1;
    r = MsiRecordGetString(h, 0, NULL, &sz);
    ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
    ok(sz == 3, "length wrong\n");
    sz = sizeof buf;
    r = MsiRecordGetString(h, 0, buf, &sz);
    ok(r == ERROR_SUCCESS, "failed to get string from integer\n");
    ok(0==strcmp(buf,"-32"), "failed to get string from integer\n");
    buf[0]=0;

    /* same record, now try streams */
    r = MsiRecordSetStream(h, 0, NULL);
    ok(r == ERROR_INVALID_PARAMETER, "set NULL stream\n");
    sz = sizeof buf;
    r = MsiRecordReadStream(h, 0, buf, &sz);
    ok(r == ERROR_INVALID_DATATYPE, "read non-stream type\n");
    ok(sz == sizeof buf, "set sz\n");
    r = MsiRecordDataSize( h, -1);
    ok(r == 0,"MsiRecordDataSize returned wrong size\n");
    r = MsiRecordDataSize( h, 0);
    ok(r == 4,"MsiRecordDataSize returned wrong size\n");

    /* same record, now close it */
    r = MsiCloseHandle(h);
    ok(r == ERROR_SUCCESS, "Failed to close handle\n");

    /* now try streams in a new record - need to create a file to play with */
    r = create_temp_file(filename); 
    if(!r)
        return;

    /* streams can't be inserted in field 0 for some reason */
    h = MsiCreateRecord(2);
    ok(h, "couldn't create a two field record\n");
    r = MsiRecordSetStream(h, 0, filename);
    ok(r == ERROR_INVALID_PARAMETER, "added stream to field 0\n");
    r = MsiRecordSetStream(h, 1, filename);
    ok(r == ERROR_SUCCESS, "failed to add stream to record\n");
    r = MsiRecordReadStream(h, 1, buf, NULL);
    ok(r == ERROR_INVALID_PARAMETER, "should return error\n");
    /* http://test.winehq.org/data/200503181000/98_jmelgarejo98casa/msi:record.txt */
    DeleteFile(filename); /* Windows 98 doesn't like this at all, so don't check return. */
    r = MsiRecordReadStream(h, 1, NULL, NULL);
    ok(r == ERROR_INVALID_PARAMETER, "should return error\n");
    sz = sizeof buf;
    r = MsiRecordReadStream(h, 1, NULL, &sz);
    ok(r == ERROR_SUCCESS, "failed to read stream\n");
    ok(sz==26,"couldn't get size of stream\n");
    sz = 0;
    r = MsiRecordReadStream(h, 1, buf, &sz);
    ok(r == ERROR_SUCCESS, "failed to read stream\n");
    ok(sz==0,"short read\n");
    sz = sizeof buf;
    r = MsiRecordReadStream(h, 1, buf, &sz);
    ok(r == ERROR_SUCCESS, "failed to read stream\n");
    ok(sz==sizeof buf,"short read\n");
    ok(!strncmp(buf,"abcdefghij",10), "read the wrong thing\n");
    sz = sizeof buf;
    r = MsiRecordReadStream(h, 1, buf, &sz);
    ok(r == ERROR_SUCCESS, "failed to read stream\n");
    ok(sz==sizeof buf,"short read\n");
    ok(!strncmp(buf,"klmnopqrst",10), "read the wrong thing\n");
    memset(buf,0,sizeof buf);
    sz = sizeof buf;
    r = MsiRecordReadStream(h, 1, buf, &sz);
    ok(r == ERROR_SUCCESS, "failed to read stream\n");
    ok(sz==6,"short read\n");
    ok(!strcmp(buf,"uvwxyz"), "read the wrong thing\n");
    memset(buf,0,sizeof buf);
    sz = sizeof buf;
    r = MsiRecordReadStream(h, 1, buf, &sz);
    ok(r == ERROR_SUCCESS, "failed to read stream\n");
    ok(sz==0,"size non-zero at end of stream\n");
    ok(buf[0]==0, "read something at end of the stream\n");
    r = MsiRecordSetStream(h, 1, NULL);
    ok(r == ERROR_SUCCESS, "failed to reset stream\n");
    sz = 0;
    r = MsiRecordReadStream(h, 1, NULL, &sz);
    ok(r == ERROR_SUCCESS, "bytes left wrong after reset\n");
    ok(sz==26,"couldn't get size of stream\n");
    r = MsiRecordDataSize(h,1);
    ok(r == 26,"MsiRecordDataSize returned wrong size\n");

    /* now close the stream record */
    r = MsiCloseHandle(h);
    ok(r == ERROR_SUCCESS, "Failed to close handle\n");
    DeleteFile(filename); /* Delete it for sure, when everything else is closed. */
}
示例#9
0
/* Uninstall NSIS */
MSIDLLEXPORT UninstallNsisInstallation( MSIHANDLE hInstall )
{
	DWORD rv = ERROR_SUCCESS;
	// lookup the NSISUNINSTALL property value
	LPTSTR cNsisUninstall = _T("UPGRADENSIS");
	HANDLE hIo = NULL;
	DWORD dwSize = 0;
	LPTSTR strPathUninst = NULL;
	HANDLE hJob = NULL;
	STARTUPINFO sInfo;
	PROCESS_INFORMATION pInfo;

	pInfo.hProcess = NULL;
	pInfo.hThread = NULL;

	rv = MsiGetProperty( hInstall, cNsisUninstall, _T(""), &dwSize );
	if(rv != ERROR_MORE_DATA) goto _cleanup;

	strPathUninst = new TCHAR[ ++dwSize ];

	rv = MsiGetProperty( hInstall, cNsisUninstall, strPathUninst, &dwSize );
	if(rv != ERROR_SUCCESS) goto _cleanup;

	// Create a process for the uninstaller
	sInfo.cb = sizeof(sInfo);
	sInfo.lpReserved = NULL;
	sInfo.lpDesktop = _T("");
	sInfo.lpTitle = _T("NSIS Uninstaller for Kerberos for Windows");
	sInfo.dwX = 0;
	sInfo.dwY = 0;
	sInfo.dwXSize = 0;
	sInfo.dwYSize = 0;
	sInfo.dwXCountChars = 0;
	sInfo.dwYCountChars = 0;
	sInfo.dwFillAttribute = 0;
	sInfo.dwFlags = 0;
	sInfo.wShowWindow = 0;
	sInfo.cbReserved2 = 0;
	sInfo.lpReserved2 = 0;
	sInfo.hStdInput = 0;
	sInfo.hStdOutput = 0;
	sInfo.hStdError = 0;

	if(!CreateProcess( 
		strPathUninst,
		_T("Uninstall /S"),
		NULL,
		NULL,
		FALSE,
		CREATE_SUSPENDED,
		NULL,
		NULL,
		&sInfo,
		&pInfo)) {
            DWORD lastError = GetLastError();
            MSIHANDLE hRecord;

            hRecord = MsiCreateRecord(4);
            MsiRecordClearData(hRecord);
            MsiRecordSetInteger(hRecord, 1, ERR_NSS_FAILED_CP);
            MsiRecordSetString(hRecord, 2, strPathUninst);
            MsiRecordSetInteger(hRecord, 3, lastError);

            MsiProcessMessage( hInstall, INSTALLMESSAGE_ERROR, hRecord );
	
            MsiCloseHandle( hRecord );

            pInfo.hProcess = NULL;
            pInfo.hThread = NULL;
            rv = 40;
            goto _cleanup;
        };

	// Create a job object to contain the NSIS uninstall process tree

	JOBOBJECT_ASSOCIATE_COMPLETION_PORT acp;

	acp.CompletionKey = 0;

	hJob = CreateJobObject(NULL, _T("NSISUninstallObject"));
	if(!hJob) {
		rv = 41;
		goto _cleanup;
	}

	hIo = CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);
	if(!hIo) {
		rv = 42;
		goto _cleanup;
	}

	acp.CompletionPort = hIo;

	SetInformationJobObject( hJob, JobObjectAssociateCompletionPortInformation, &acp, sizeof(acp));

	AssignProcessToJobObject( hJob, pInfo.hProcess );

	ResumeThread( pInfo.hThread );

	DWORD a,b,c;
	for(;;) {
		if(!GetQueuedCompletionStatus(hIo, &a, (PULONG_PTR) &b, (LPOVERLAPPED *) &c, INFINITE)) {
			Sleep(1000);
			continue;
		}
		if(a == JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO) {
			break;
		}
	}

	rv = ERROR_SUCCESS;
    
_cleanup:
	if(hIo) CloseHandle(hIo);
	if(pInfo.hProcess)	CloseHandle( pInfo.hProcess );
	if(pInfo.hThread) 	CloseHandle( pInfo.hThread );
	if(hJob) CloseHandle(hJob);
	if(strPathUninst) delete strPathUninst;

	if(rv != ERROR_SUCCESS && rv != 40) {
            ShowMsiError( hInstall, ERR_NSS_FAILED, rv );
	}
	return rv;
}
示例#10
0
UINT KillRunningProcessesSlave( MSIHANDLE hInstall, BOOL bKill )
{
    UINT rv = ERROR_SUCCESS;
    _KillProc * kpList;
    int nKpList = 0;
    int i;
    int rowNum = 1;
    DWORD size;
    BOOL found = FALSE;

    MSIHANDLE hDatabase = NULL;
    MSIHANDLE hView = NULL;
    MSIHANDLE hViewInsert = NULL;
    MSIHANDLE hRecord = NULL;
    MSIHANDLE hRecordInsert = NULL;

    HANDLE hSnapshot = NULL;

    PROCESSENTRY32 pe;

    kpList = new _KillProc[MAX_KILL_PROCESSES];
    memset(kpList, 0, sizeof(*kpList) * MAX_KILL_PROCESSES);

    hDatabase = MsiGetActiveDatabase( hInstall );
    if( hDatabase == NULL ) {
        rv = GetLastError();
        goto _cleanup;
    }

    // If we are only going to list out the processes, delete all the existing
    // entries first.

    if(!bKill) {

        rv = MsiDatabaseOpenView( hDatabase,
            _T( "DELETE FROM `ListBox` WHERE `ListBox`.`Property` = 'KillableProcesses'" ),
            &hView); RV_BAIL;

        rv = MsiViewExecute( hView, NULL ); RV_BAIL;

        MsiCloseHandle( hView );

        hView = NULL;
        
        rv = MsiDatabaseOpenView( hDatabase,
              _T( "SELECT * FROM `ListBox` WHERE `Property` = 'KillableProcesses'" ),
            &hViewInsert); RV_BAIL;

        MsiViewExecute(hViewInsert, NULL);

        hRecordInsert = MsiCreateRecord(4);

        if(hRecordInsert == NULL) {
            rv = GetLastError();
            goto _cleanup;
        }
    }

    // Open a view
    rv = MsiDatabaseOpenView( hDatabase, 
        _T( "SELECT `Image`,`Desc` FROM `KillProcess`" ),
        &hView); RV_BAIL;

    rv = MsiViewExecute( hView, NULL ); RV_BAIL;

    do {
        rv = MsiViewFetch( hView, &hRecord );
        if(rv != ERROR_SUCCESS) {
            if(hRecord) 
                MsiCloseHandle(hRecord);
            hRecord = NULL;
            break;
        }

        kpList[nKpList].image = new TCHAR[ FIELD_SIZE ]; kpList[nKpList].image[0] = _T('\0');
        kpList[nKpList].desc = new TCHAR[ FIELD_SIZE ];  kpList[nKpList].desc[0] = _T('\0');
        nKpList++;

        size = FIELD_SIZE;
        rv = MsiRecordGetString(hRecord, 1, kpList[nKpList-1].image, &size); RV_BAIL;

        size = FIELD_SIZE;
        rv = MsiRecordGetString(hRecord, 2, kpList[nKpList-1].desc, &size); RV_BAIL;

        MsiCloseHandle(hRecord);
    } while(nKpList < MAX_KILL_PROCESSES);

    hRecord = NULL;

    // now we have all the processes in the array.  Check if they are running.
    
    hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    if(hSnapshot == INVALID_HANDLE_VALUE) {
        rv = GetLastError();
        goto _cleanup;
    }

    pe.dwSize = sizeof( PROCESSENTRY32 );

    if(!Process32First( hSnapshot, &pe )) {
        // technically we should at least find the MSI process, but we let this pass
        rv = ERROR_SUCCESS;
        goto _cleanup;
    }

    do {
        for(i=0; i<nKpList; i++) {
            if(!_tcsicmp( kpList[i].image, pe.szExeFile )) {
                // got one
                if(bKill) {
                    // try to kill the process
                    HANDLE hProcess = NULL;

                    // If we encounter an error, instead of bailing
                    // out, we continue on to the next process.  We
                    // may not have permission to kill all the
                    // processes we want to kill anyway.  If there are
                    // any files that we want to replace that is in
                    // use, Windows Installer will schedule a reboot.
                    // Also, it's not like we have an exhaustive list
                    // of all the programs that use Kerberos anyway.

                    hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe.th32ProcessID);
                    if(hProcess == NULL) {
                        rv = GetLastError();
                        break;
                    }

                    if(!TerminateProcess(hProcess, 0)) {
                        rv = GetLastError();
                        CloseHandle(hProcess);
                        break;
                    }

                    CloseHandle(hProcess);

                } else {
                    TCHAR buf[256];

                    // we are supposed to just list out the processes
                    rv = MsiRecordClearData( hRecordInsert ); RV_BAIL;
                    rv = MsiRecordSetString( hRecordInsert, 1, _T("KillableProcesses"));
                    rv = MsiRecordSetInteger( hRecordInsert, 2, rowNum++ ); RV_BAIL;
                    _itot( rowNum, buf, 10 );
                    rv = MsiRecordSetString( hRecordInsert, 3, buf ); RV_BAIL;
                    if(_tcslen(kpList[i].desc)) {
                        rv = MsiRecordSetString( hRecordInsert, 4, kpList[i].desc ); RV_BAIL;
                    } else {
                        rv = MsiRecordSetString( hRecordInsert, 4, kpList[i].image ); RV_BAIL;
                    }
                    MsiViewModify(hViewInsert, MSIMODIFY_INSERT_TEMPORARY, hRecordInsert); RV_BAIL;

                    found = TRUE;
                }
                break;
            }
        }
   } while( Process32Next( hSnapshot, &pe ) );

    if(!bKill) {
        // set the 'FoundProcceses' property
        if(found) {
            MsiSetProperty( hInstall, _T("FoundProcesses"), _T("1"));
        } else {
            MsiSetProperty( hInstall, _T("FoundProcesses"), _T(""));
        }
    }

    // Finally:
    rv = ERROR_SUCCESS;

_cleanup:

    if(hRecordInsert) MsiCloseHandle(hRecordInsert);
    if(hViewInsert) MsiCloseHandle(hView);

    if(hSnapshot && hSnapshot != INVALID_HANDLE_VALUE) CloseHandle(hSnapshot);

    while(nKpList) {
        nKpList--;
        delete kpList[nKpList].image;
        delete kpList[nKpList].desc;
    }
    delete kpList;

    if(hRecord) MsiCloseHandle(hRecord);
    if(hView) MsiCloseHandle(hView);

    if(hDatabase) MsiCloseHandle(hDatabase);

    if(rv != ERROR_SUCCESS) {
        ShowMsiError(hInstall, ERR_PROC_LIST, rv);
    }

    return rv;
}