⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 custom.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
                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 + -