📄 custom.c
字号:
CloseHandle(ThreadHandle);
}
else
file_running_action(package, ThreadHandle, FALSE, Name);
}
else
{
CloseHandle(ThreadHandle);
if (ProcessHandle)
CloseHandle(ProcessHandle);
}
if (finished)
*finished = FALSE;
}
return rc;
}
typedef UINT __stdcall CustomEntry(MSIHANDLE);
typedef struct
{
MSIPACKAGE *package;
WCHAR *target;
WCHAR *source;
} thread_struct;
static DWORD WINAPI ACTION_CallDllFunction(thread_struct *stuff)
{
HANDLE hModule;
LPSTR proc;
CustomEntry *fn;
DWORD rc = ERROR_SUCCESS;
TRACE("calling function (%s, %s)\n", debugstr_w(stuff->source),
debugstr_w(stuff->target));
hModule = LoadLibraryW(stuff->source);
if (hModule)
{
proc = strdupWtoA( stuff->target );
fn = (CustomEntry*)GetProcAddress(hModule,proc);
if (fn)
{
MSIHANDLE hPackage;
MSIPACKAGE *package = stuff->package;
TRACE("Calling function %s\n", proc);
hPackage = alloc_msihandle( &package->hdr );
if (hPackage)
{
rc = fn( hPackage );
MsiCloseHandle( hPackage );
}
else
ERR("Handle for object %p not found\n", package );
}
else
ERR("failed to resolve functon %s\n", debugstr_a(proc));
msi_free(proc);
FreeLibrary(hModule);
}
else
ERR("failed to load dll %s\n", debugstr_w(stuff->source));
msiobj_release( &stuff->package->hdr );
msi_free(stuff->source);
msi_free(stuff->target);
msi_free(stuff);
return rc;
}
static DWORD WINAPI DllThread(LPVOID info)
{
thread_struct *stuff;
DWORD rc = 0;
TRACE("MSI Thread (%x) started for custom action\n", GetCurrentThreadId());
stuff = (thread_struct*)info;
rc = ACTION_CallDllFunction(stuff);
TRACE("MSI Thread (%x) finished (rc %i)\n",GetCurrentThreadId(), rc);
/* clse all handles for this thread */
MsiCloseAllHandles();
return rc;
}
static HANDLE do_msidbCustomActionTypeDll(MSIPACKAGE *package, LPCWSTR dll, LPCWSTR target)
{
thread_struct *info;
info = msi_alloc( sizeof(*info) );
msiobj_addref( &package->hdr );
info->package = package;
info->target = strdupW(target);
info->source = strdupW(dll);
return CreateThread(NULL, 0, DllThread, info, 0, NULL);
}
static UINT HANDLE_CustomType1(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
WCHAR tmp_file[MAX_PATH];
UINT rc = ERROR_SUCCESS;
BOOL finished = FALSE;
HANDLE ThreadHandle;
store_binary_to_temp(package, source, tmp_file);
TRACE("Calling function %s from %s\n",debugstr_w(target),
debugstr_w(tmp_file));
if (!strchrW(tmp_file,'.'))
{
static const WCHAR dot[]={'.',0};
strcatW(tmp_file,dot);
}
ThreadHandle = do_msidbCustomActionTypeDll( package, tmp_file, target );
rc = process_handle(package, type, ThreadHandle, NULL, action, &finished );
if (!finished)
track_tempfile(package, tmp_file, tmp_file);
else
DeleteFileW(tmp_file);
return rc;
}
static UINT HANDLE_CustomType2(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
WCHAR tmp_file[MAX_PATH];
STARTUPINFOW si;
PROCESS_INFORMATION info;
BOOL rc;
INT len;
WCHAR *deformated;
WCHAR *cmd;
static const WCHAR spc[] = {' ',0};
UINT prc = ERROR_SUCCESS;
BOOL finished = FALSE;
memset(&si,0,sizeof(STARTUPINFOW));
store_binary_to_temp(package, source, tmp_file);
deformat_string(package,target,&deformated);
len = strlenW(tmp_file)+2;
if (deformated)
len += strlenW(deformated);
cmd = msi_alloc(sizeof(WCHAR)*len);
strcpyW(cmd,tmp_file);
if (deformated)
{
strcatW(cmd,spc);
strcatW(cmd,deformated);
msi_free(deformated);
}
TRACE("executing exe %s\n", debugstr_w(cmd));
rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
if ( !rc )
{
ERR("Unable to execute command %s\n", debugstr_w(cmd));
msi_free(cmd);
return ERROR_SUCCESS;
}
msi_free(cmd);
prc = process_handle(package, type, info.hThread, info.hProcess, action,
&finished);
if (!finished)
track_tempfile(package, tmp_file, tmp_file);
else
DeleteFileW(tmp_file);
return prc;
}
static UINT HANDLE_CustomType17(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
HANDLE hThread;
MSIFILE *file;
TRACE("%s %s\n", debugstr_w(source), debugstr_w(target));
file = get_loaded_file( package, source );
if (!file)
{
ERR("invalid file key %s\n", debugstr_w( source ));
return ERROR_FUNCTION_FAILED;
}
hThread = do_msidbCustomActionTypeDll( package, file->TargetPath, target );
return process_handle(package, type, hThread, NULL, action, NULL );
}
static UINT HANDLE_CustomType18(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
STARTUPINFOW si;
PROCESS_INFORMATION info;
BOOL rc;
WCHAR *deformated;
WCHAR *cmd;
INT len;
static const WCHAR spc[] = {' ',0};
MSIFILE *file;
UINT prc;
memset(&si,0,sizeof(STARTUPINFOW));
file = get_loaded_file(package,source);
if( !file )
return ERROR_FUNCTION_FAILED;
len = lstrlenW( file->TargetPath );
deformat_string(package,target,&deformated);
if (deformated)
len += strlenW(deformated);
len += 2;
cmd = msi_alloc(len * sizeof(WCHAR));
lstrcpyW( cmd, file->TargetPath);
if (deformated)
{
strcatW(cmd, spc);
strcatW(cmd, deformated);
msi_free(deformated);
}
TRACE("executing exe %s\n", debugstr_w(cmd));
rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
if ( !rc )
{
ERR("Unable to execute command %s\n", debugstr_w(cmd));
msi_free(cmd);
return ERROR_SUCCESS;
}
msi_free(cmd);
prc = process_handle(package, type, info.hThread, info.hProcess, action,
NULL);
return prc;
}
static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ',
'F','R','O','M',' ','`','E','r','r','o','r','`',' ',
'W','H','E','R','E',' ','`','E','r','r','o','r','`',' ','=',' ',
'%','s',0
};
MSIRECORD *row = 0;
LPWSTR deformated = NULL;
deformat_string( package, target, &deformated );
/* first try treat the error as a number */
row = MSI_QueryGetRecord( package->db, query, deformated );
if( row )
{
LPCWSTR error = MSI_RecordGetString( row, 1 );
MessageBoxW( NULL, error, NULL, MB_OK );
msiobj_release( &row->hdr );
}
else
MessageBoxW( NULL, deformated, NULL, MB_OK );
msi_free( deformated );
return ERROR_FUNCTION_FAILED;
}
static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
STARTUPINFOW si;
PROCESS_INFORMATION info;
WCHAR *prop;
BOOL rc;
WCHAR *deformated;
WCHAR *cmd;
INT len;
static const WCHAR spc[] = {' ',0};
memset(&si,0,sizeof(STARTUPINFOW));
memset(&info,0,sizeof(PROCESS_INFORMATION));
prop = msi_dup_property( package, source );
if (!prop)
return ERROR_SUCCESS;
deformat_string(package,target,&deformated);
len = strlenW(prop) + 2;
if (deformated)
len += strlenW(deformated);
cmd = msi_alloc(sizeof(WCHAR)*len);
strcpyW(cmd,prop);
if (deformated)
{
strcatW(cmd,spc);
strcatW(cmd,deformated);
msi_free(deformated);
}
msi_free(prop);
TRACE("executing exe %s\n", debugstr_w(cmd));
rc = CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
if ( !rc )
{
ERR("Unable to execute command %s\n", debugstr_w(cmd));
msi_free(cmd);
return ERROR_SUCCESS;
}
msi_free(cmd);
return process_handle(package, type, info.hThread, info.hProcess, action, NULL);
}
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
LPWSTR filename, deformated;
STARTUPINFOW si;
PROCESS_INFORMATION info;
BOOL rc;
UINT prc;
memset(&si,0,sizeof(STARTUPINFOW));
filename = resolve_folder(package, source, FALSE, FALSE, NULL);
if (!filename)
return ERROR_FUNCTION_FAILED;
SetCurrentDirectoryW(filename);
msi_free(filename);
deformat_string(package,target,&deformated);
if (!deformated)
return ERROR_FUNCTION_FAILED;
TRACE("executing exe %s\n", debugstr_w(deformated));
rc = CreateProcessW(NULL, deformated, NULL, NULL, FALSE, 0, NULL,
c_collen, &si, &info);
if ( !rc )
{
ERR("Unable to execute command %s\n", debugstr_w(deformated));
msi_free(deformated);
return ERROR_SUCCESS;
}
msi_free(deformated);
prc = process_handle(package, type, info.hThread, info.hProcess, action,
NULL);
return prc;
}
void ACTION_FinishCustomActions(MSIPACKAGE* package)
{
struct list *item, *cursor;
DWORD rc;
LIST_FOR_EACH_SAFE( item, cursor, &package->RunningActions )
{
MSIRUNNINGACTION *action = LIST_ENTRY( item, MSIRUNNINGACTION, entry );
TRACE("Checking on action %s\n", debugstr_w(action->name));
list_remove( &action->entry );
if (action->process)
GetExitCodeProcess( action->handle, &rc );
else
GetExitCodeThread( action->handle, &rc );
if (rc == STILL_ACTIVE)
{
TRACE("Waiting on action %s\n", debugstr_w( action->name) );
msi_dialog_check_messages( action->handle );
}
CloseHandle( action->handle );
msi_free( action->name );
msi_free( action );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -