Ignore:
Timestamp:
Oct 24, 2011, 8:04:27 PM (14 years ago)
Author:
dmik
Message:

Make kernel32 use initdll.lib.

File:
1 moved

Legend:

Unmodified
Added
Removed
  • branches/gcc-kmk/src/kernel32/initterm.cpp

    r21716 r21734  
    66 * Copyright 1998 Peter Fitzsimmons
    77 *
    8  *
    98 * Project Odin Software License can be found in LICENSE.TXT
    10  *
    119 */
    1210
    13 /*-------------------------------------------------------------*/
    14 /* INITERM.C -- Source for a custom dynamic link library       */
    15 /*              initialization and termination (_DLL_InitTerm) */
    16 /*              function.                                      */
    17 /*                                                             */
    18 /* When called to perform initialization, this sample function */
    19 /* gets storage for an array of integers, and initializes its  */
    20 /* elements with random integers.  At termination time, it     */
    21 /* frees the array.  Substitute your own special processing.   */
    22 /*-------------------------------------------------------------*/
    23 
    24 
    25 /* Include files */
    2611#define  INCL_DOSMODULEMGR
    2712#define  INCL_DOSMISC
     
    6853PVOID   SYSTEM _O32_GetEnvironmentStrings( VOID );
    6954
    70 extern "C" {
    71  //Win32 resource table (produced by wrc)
    72  extern DWORD kernel32_PEResTab;
    73 }
     55// Win32 resource table (produced by wrc)
     56extern DWORD kernel32_PEResTab;
     57
     58static HMODULE dllHandle = 0;
    7459
    7560extern PFN pfnImSetMsgQueueProperty;
    7661
    77        ULONG   flAllocMem = 0;    /* flag to optimize DosAllocMem to use all the memory on SMP machines */
    78        ULONG   ulMaxAddr = 0x20000000; /* end of user address space. */
    79        int     loadNr = 0;
    80        char    kernel32Path[CCHMAXPATH] = "";
    81 static HMODULE dllHandle = 0;
    82        BOOL    fInit     = FALSE;
    83        BOOL    fWin32k   = FALSE;
    84        HMODULE imHandle = 0;
    85        char    szModName[ 256 ] = "";
    86 
    87 /****************************************************************************/
    88 /* _DLL_InitTerm is the function that gets called by the operating system   */
    89 /* loader when it loads and frees this DLL for each process that accesses   */
    90 /* this DLL.  However, it only gets called the first time the DLL is loaded */
    91 /* and the last time it is freed for a particular process.  The system      */
    92 /* linkage convention MUST be used because the operating system loader is   */
    93 /* calling this function.                                                   */
    94 /****************************************************************************/
    95 static ULONG APIENTRY inittermKernel32_internal(ULONG hModule, ULONG ulFlag)
     62//Global DLL Data
     63#pragma data_seg(_GLOBALDATA)
     64int globLoadNr = 0;
     65#pragma data_seg()
     66
     67BOOL    fVersionWarp3 = FALSE;
     68BOOL    fCustomBuild  = FALSE;
     69
     70ULONG   flAllocMem = 0;    /* flag to optimize DosAllocMem to use all the memory on SMP machines */
     71ULONG   ulMaxAddr = 0x20000000; /* end of user address space. */
     72int     loadNr = 0;
     73char    kernel32Path[CCHMAXPATH] = "";
     74BOOL    fInit     = FALSE;
     75BOOL    fWin32k   = FALSE;
     76HMODULE imHandle = 0;
     77char    szModName[ 256 ] = "";
     78
     79static ULONG DLL_InitKernel32_internal(ULONG hModule)
    9680{
    9781    size_t i;
     
    9983    ULONG  ulSysinfo, version[2];
    10084
    101     /*-------------------------------------------------------------------------*/
    102     /* If ulFlag is zero then the DLL is being loaded so initialization should */
    103     /* be performed.  If ulFlag is 1 then the DLL is being freed so            */
    104     /* termination should be performed.                                        */
    105     /*-------------------------------------------------------------------------*/
    106 
    107     switch (ulFlag)
    108     {
    109         case 0:
     85    if (fInit)
     86        return 0; // already initialized
     87
     88    rc = DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_VERSION_MINOR,
     89                         version, sizeof(version));
     90    if (rc == 0)
     91        if(version[0] >= 20 && version[1] <= 30)
     92            fVersionWarp3 = TRUE;
     93
     94    // This always must be the first thing to do.
     95    RasInitialize (hModule);
     96#ifdef RAS
     97    extern void rasInitVirtual (void);
     98    rasInitVirtual ();
     99#endif
     100
     101    ParseLogStatusKERNEL32();
     102
     103    /*
     104     * Init the win32k library.
     105     * We will also need to tell win32k where the Odin32 environment is
     106     * located. Currently that is within Open32. I'm quite sure that it's
     107     * not relocated during run, so we're pretty well off.
     108     */
     109    //Note: we do NOT want to use any win32k services with custom builds
     110    if (fCustomBuild == FALSE && !libWin32kInit())
     111    {
     112        rc = libWin32kSetEnvironment((PSZ)_O32_GetEnvironmentStrings(), 0, 0);
     113        if (rc)
    110114        {
    111             if (fInit)
    112                 return 1; // already initialized
    113 
    114             // This always must be the first thing to do.
    115             RasInitialize (hModule);
    116 #ifdef RAS
    117             extern void rasInitVirtual (void);
    118             rasInitVirtual ();
     115            dprintf(("KERNEL32: initterm: libWin32kSetEnvironment failed with rc=%d\n", rc));
     116        }
     117        else fWin32k = TRUE;
     118    }
     119
     120    char *kernel32Name = OSLibGetDllName(hModule);
     121    if (!kernel32Name)
     122        return -1; // failure
     123
     124    strcpy(kernel32Path, kernel32Name);
     125    char *endofpath = strrchr(kernel32Path, '\\');
     126    *(endofpath+1) = 0;
     127
     128    CheckVersionFromHMOD(PE2LX_VERSION, hModule); /*PLF Wed  98-03-18 05:28:48*/
     129
     130    /* knut: check for high memory support */
     131    rc = DosQuerySysInfo(QSV_VIRTUALADDRESSLIMIT, QSV_VIRTUALADDRESSLIMIT, &ulSysinfo, sizeof(ulSysinfo));
     132    if (rc == 0 && ulSysinfo > 512)   //VirtualAddresslimit is in MB
     133    {
     134        flAllocMem = PAG_ANY;      // high memory support. Let's use it!
     135        ulMaxAddr = ulSysinfo * (1024*1024);
     136    }
     137    else
     138        flAllocMem = 0;        // no high memory support
     139
     140    dprintf(("kernel32 init %s %s (%x) Win32k - %s", __DATE__, __TIME__, inittermKernel32,
     141             libWin32kInstalled() ? "Installed" : "Not Installed"));
     142
     143    OpenPrivateLogFiles();
     144
     145    //SvL: Do it here instead of during the exe object creation
     146    //(std handles can be used in win32 dll initialization routines
     147    if (HMInitialize() != NO_ERROR)
     148        return -1;
     149
     150    // VP: Shared heap should be initialized before call to PROFILE_*
     151    // because they use a critical section which in turn uses smalloc
     152    // in debug build
     153    if (!InitializeSharedHeap())
     154        return -1;
     155
     156    // VP: initialize profile internal data (critical section actually).
     157    // This was done in PROFILE_LoadOdinIni but PROFILE_GetOdinIniInt
     158    // is called earlier and this lead to a handle leak.
     159    PROFILE_Initialize();
     160
     161    if(flAllocMem == PAG_ANY)
     162    {
     163        OSLibInitWSeBFileIO();
     164        if (PROFILE_GetOdinIniInt(ODINSYSTEM_SECTION, HIGHMEM_KEY, 1) == 0)
     165        {
     166            dprintf(("WARNING: OS/2 kernel supports high memory, but support is DISABLED because of HIGHMEM odin.ini key"));
     167            flAllocMem = 0;
     168        }
     169    }
     170
     171    if (!InitializeCodeHeap())
     172        return -1;
     173
     174    InitializeMemMaps();
     175
     176    PROFILE_LoadOdinIni();
     177    dllHandle = RegisterLxDll(hModule, 0, (PVOID)&kernel32_PEResTab);
     178    if (dllHandle == 0)
     179        return -1;
     180
     181    //SvL: Kernel32 is a special case; pe.exe loads it, so increase
     182    //     the reference count here
     183    Win32DllBase *module = Win32DllBase::findModule(dllHandle);
     184    if (module)
     185    {
     186        module->AddRef();
     187        module->DisableUnload();
     188    }
     189
     190    OSLibDosSetInitialMaxFileHandles(ODIN_DEFAULT_MAX_FILEHANDLES);
     191
     192#ifdef DEBUG
     193    {
     194        LPSTR WIN32API GetEnvironmentStringsA();
     195
     196        char *tmpenvnew = GetEnvironmentStringsA();
     197        dprintf(("Environment:"));
     198        while(*tmpenvnew) {
     199            dprintf(("%s", tmpenvnew));
     200            tmpenvnew += strlen(tmpenvnew)+1;
     201        }
     202    }
    119203#endif
    120204
    121             ParseLogStatusKERNEL32();
    122 
    123             /*
    124              * Init the win32k library.
    125              * We will also need to tell win32k where the Odin32 environment is
    126              * located. Currently that is within Open32. I'm quite sure that it's
    127              * not relocated during run, so we're pretty well off.
    128              */
    129             //Note: we do NOT want to use any win32k services with custom builds
    130             if (fCustomBuild == FALSE && !libWin32kInit())
    131             {
    132                 rc = libWin32kSetEnvironment((PSZ)_O32_GetEnvironmentStrings(), 0, 0);
    133                 if (rc)
    134                 {
    135                     dprintf(("KERNEL32: initterm: libWin32kSetEnvironment failed with rc=%d\n", rc));
    136                 }
    137                 else fWin32k = TRUE;
    138             }
    139 
    140             char *kernel32Name = OSLibGetDllName(hModule);
    141             if (!kernel32Name)
    142                 return 0; // failure
    143 
    144             strcpy(kernel32Path, kernel32Name);
    145             char *endofpath = strrchr(kernel32Path, '\\');
    146             *(endofpath+1) = 0;
    147 
    148             CheckVersionFromHMOD(PE2LX_VERSION, hModule); /*PLF Wed  98-03-18 05:28:48*/
    149 
    150             /* knut: check for high memory support */
    151             rc = DosQuerySysInfo(QSV_VIRTUALADDRESSLIMIT, QSV_VIRTUALADDRESSLIMIT, &ulSysinfo, sizeof(ulSysinfo));
    152             if (rc == 0 && ulSysinfo > 512)   //VirtualAddresslimit is in MB
    153             {
    154                 flAllocMem = PAG_ANY;      // high memory support. Let's use it!
    155                 ulMaxAddr = ulSysinfo * (1024*1024);
    156             }
    157             else
    158                 flAllocMem = 0;        // no high memory support
    159 
    160             dprintf(("kernel32 init %s %s (%x) Win32k - %s", __DATE__, __TIME__, inittermKernel32,
    161                      libWin32kInstalled() ? "Installed" : "Not Installed"));
    162 
    163             OpenPrivateLogFiles();
    164 
    165             //SvL: Do it here instead of during the exe object creation
    166             //(std handles can be used in win32 dll initialization routines
    167             if (HMInitialize() != NO_ERROR)
    168                 return 0;
    169 
    170             // VP: Shared heap should be initialized before call to PROFILE_*
    171             // because they use a critical section which in turn uses smalloc
    172             // in debug build
    173             if (!InitializeSharedHeap())
    174                 return 0;
    175 
    176             // VP: initialize profile internal data (critical section actually).
    177             // This was done in PROFILE_LoadOdinIni but PROFILE_GetOdinIniInt
    178             // is called earlier and this lead to a handle leak.
    179             PROFILE_Initialize();
    180 
    181             if(flAllocMem == PAG_ANY) {
    182                 OSLibInitWSeBFileIO();
    183                 if (PROFILE_GetOdinIniInt(ODINSYSTEM_SECTION, HIGHMEM_KEY, 1) == 0) {
    184                     dprintf(("WARNING: OS/2 kernel supports high memory, but support is DISABLED because of HIGHMEM odin.ini key"));
    185                     flAllocMem = 0;
    186                 }
    187             }
    188 
    189             if (!InitializeCodeHeap())
    190                 return 0;
    191 
    192             InitializeMemMaps();
    193 
    194             PROFILE_LoadOdinIni();
    195             dllHandle = RegisterLxDll(hModule, 0, (PVOID)&kernel32_PEResTab);
    196             if (dllHandle == 0)
    197                 return 0;
    198 
    199             //SvL: Kernel32 is a special case; pe.exe loads it, so increase
    200             //     the reference count here
    201             Win32DllBase *module = Win32DllBase::findModule(dllHandle);
    202             if (module)
    203             {
    204                 module->AddRef();
    205                 module->DisableUnload();
    206             }
    207 
    208             OSLibDosSetInitialMaxFileHandles(ODIN_DEFAULT_MAX_FILEHANDLES);
    209 
    210 #ifdef DEBUG
    211             {
    212                 LPSTR WIN32API GetEnvironmentStringsA();
    213 
    214                 char *tmpenvnew = GetEnvironmentStringsA();
    215                 dprintf(("Environment:"));
    216                 while(*tmpenvnew) {
    217                     dprintf(("%s", tmpenvnew));
    218                     tmpenvnew += strlen(tmpenvnew)+1;
    219                 }
    220             }
    221 #endif
    222 
    223             // Must be done before InitializeTIB (which loads NTDLL -> USER32)
    224             InitDirectories();
    225 
    226             // Must be done after HMInitialize!
    227             if (InitializeMainThread() == NULL)
    228                 return 0;
    229 
    230             RegisterDevices();
    231             Win32DllBase::setDefaultRenaming();
    232 
    233             rc = DosQuerySysInfo(QSV_NUMPROCESSORS, QSV_NUMPROCESSORS,
    234                                  &ulSysinfo, sizeof(ulSysinfo));
    235             if (rc != 0)
    236                 ulSysinfo = 1;
    237 
    238             // Setup codepage info
    239             CODEPAGE_Init();
    240 
    241             if (IsDBCSEnv() && DosLoadModule(szModName, sizeof( szModName ),
    242                                              "OS2IM", &imHandle) == 0)
    243                 DosQueryProcAddr(imHandle, 140, NULL, &pfnImSetMsgQueueProperty);
    244 
    245             InitSystemInfo(ulSysinfo);
    246 
    247             // Set up environment as found in NT
    248             InitEnvironment(ulSysinfo);
    249 
    250             // InitDynamicRegistry creates/changes keys that may change (i.e.
    251             // odin.ini keys that affect windows version)
    252             InitDynamicRegistry();
    253 
    254             // Set the process affinity mask to the system affinity mask
    255             DWORD dwProcessAffinityMask, dwSystemAffinityMask;
    256             GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask,
    257                                    &dwSystemAffinityMask);
    258             SetProcessAffinityMask(GetCurrentProcess(), dwSystemAffinityMask);
    259 
    260             // Set default paths for PE & NE loaders
    261             if (!InitLoaders())
    262                 return 0;
    263 
    264             RasEntry(RAS_EVENT_Kernel32InitComplete,
    265                      &dllHandle, sizeof (dllHandle));
    266 
    267             fInit = TRUE;
    268 
    269             break;
    270         }
    271 
    272         case 1:
    273 
    274             if (dllHandle)
    275                 UnregisterLxDll(dllHandle);
    276 
    277             break;
    278 
    279         default:
    280             return 0;
    281     }
    282 
    283     /***********************************************************/
    284     /* A non-zero value must be returned to indicate success.  */
    285     /***********************************************************/
    286     return 1;
    287 }
    288 //******************************************************************************
    289 //******************************************************************************
    290 ULONG APIENTRY inittermKernel32(ULONG hModule, ULONG ulFlag)
    291 {
    292     ULONG rc = inittermKernel32_internal(hModule, ulFlag);
    293 
    294     if (ulFlag == 0 && rc == 0)
     205    // Must be done before InitializeTIB (which loads NTDLL -> USER32)
     206    InitDirectories();
     207
     208    // Must be done after HMInitialize!
     209    if (InitializeMainThread() == NULL)
     210        return -1;
     211
     212    RegisterDevices();
     213    Win32DllBase::setDefaultRenaming();
     214
     215    rc = DosQuerySysInfo(QSV_NUMPROCESSORS, QSV_NUMPROCESSORS,
     216                         &ulSysinfo, sizeof(ulSysinfo));
     217    if (rc != 0)
     218        ulSysinfo = 1;
     219
     220    // Setup codepage info
     221    CODEPAGE_Init();
     222
     223    if (IsDBCSEnv() && DosLoadModule(szModName, sizeof( szModName ),
     224                                     "OS2IM", &imHandle) == 0)
     225        DosQueryProcAddr(imHandle, 140, NULL, &pfnImSetMsgQueueProperty);
     226
     227    InitSystemInfo(ulSysinfo);
     228
     229    // Set up environment as found in NT
     230    InitEnvironment(ulSysinfo);
     231
     232    // InitDynamicRegistry creates/changes keys that may change (i.e.
     233    // odin.ini keys that affect windows version)
     234    InitDynamicRegistry();
     235
     236    // Set the process affinity mask to the system affinity mask
     237    DWORD dwProcessAffinityMask, dwSystemAffinityMask;
     238    GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask,
     239                           &dwSystemAffinityMask);
     240    SetProcessAffinityMask(GetCurrentProcess(), dwSystemAffinityMask);
     241
     242    // Set default paths for PE & NE loaders
     243    if (!InitLoaders())
     244        return -1;
     245
     246    RasEntry(RAS_EVENT_Kernel32InitComplete,
     247             &dllHandle, sizeof (dllHandle));
     248
     249    fInit = TRUE;
     250
     251    return EXITLIST_KERNEL32;
     252}
     253
     254ULONG SYSTEM DLL_InitKernel32(ULONG hModule)
     255{
     256    ULONG code = DLL_InitKernel32_internal(hModule);
     257
     258    if (code == -1)
    295259        ReportFatalDllInitError("KERNEL32");
    296260
    297     return rc;
    298 }
    299 //******************************************************************************
    300 //******************************************************************************
    301 void APIENTRY cleanupKernel32(ULONG ulReason)
     261    return code;
     262}
     263
     264void SYSTEM DLL_TermKernel32(ULONG hModule)
    302265{
    303266    if (!fInit)
     
    309272    }
    310273
    311     dprintf(("kernel32 exit %d", ulReason));
     274    dprintf(("kernel32 exit"));
    312275
    313276    if( IsDBCSEnv() && imHandle )
     
    374337    RasUninitialize ();
    375338
    376     return ;
    377 }
    378 //******************************************************************************
    379 //******************************************************************************
     339    if (dllHandle)
     340        UnregisterLxDll(dllHandle);
     341}
     342
     343ULONG SYSTEM DLL_Init(ULONG hModule)
     344{
     345    if (DLL_InitDefault(hModule) == -1)
     346        return -1;
     347    return DLL_InitKernel32(hModule);
     348}
     349
     350void SYSTEM DLL_Term(ULONG hModule)
     351{
     352    DLL_TermKernel32(hModule);
     353    DLL_TermDefault(hModule);
     354}
     355
     356ULONG APIENTRY _O32__DLL_InitTerm(ULONG handle, ULONG flag);
     357
     358BOOL APIENTRY InitializeKernel32()
     359{
     360    HMODULE hModule;
     361
     362    if (!fInit)
     363        loadNr = globLoadNr++;
     364
     365    BOOL WGSS_OK = FALSE;
     366
     367    if (DosQueryModuleHandleStrict("WGSS50", &hModule) == NO_ERROR)
     368    {
     369        if (_O32__DLL_InitTerm(hModule, 0) != 0)
     370        {
     371            WGSS_OK = TRUE;
     372
     373            if (DosQueryModuleHandleStrict("KERNEL32", &hModule) == NO_ERROR &&
     374                DLL_Init(hModule) != -1)
     375                return TRUE;
     376
     377            ReportFatalDllInitError("KERNEL32");
     378        }
     379    }
     380
     381    if (!WGSS_OK)
     382        ReportFatalDllInitError("WGSS50");
     383
     384    return FALSE; // failure
     385}
     386
     387VOID APIENTRY ReportFatalDllInitError(PCSZ pszModName)
     388{
     389    static const char msg1[] =
     390        "Failed to initialize the ";
     391    static const char msg2[] =
     392        " library while starting \"";
     393    static const char msg3[] =
     394        "\".\n\r"
     395        "\n\r"
     396        "It is possible that there is not enough memory in the system to "
     397        "run this application. Please close other applications and try "
     398        "again. If the problem persists, please report the details by "
     399        "creating a ticket at http://svn.netlabs.org/odin32/.\n\r";
     400
     401    char msg[sizeof(msg1) + 8 + sizeof(msg2) + CCHMAXPATH + sizeof(msg3)];
     402
     403    strcpy(msg, msg1);
     404    strncat(msg, pszModName, 8);
     405    strcat(msg, msg2);
     406
     407    PPIB ppib;
     408    DosGetInfoBlocks(NULL, &ppib);
     409    if (DosQueryModuleName(ppib->pib_hmte, CCHMAXPATH,
     410                           msg + strlen(msg)) != NO_ERROR)
     411        strcat(msg, "<unknown executable>");
     412    strcat(msg, msg3);
     413
     414    BOOL haveHMQ = FALSE;
     415    MQINFO mqinfo;
     416    if (WinQueryQueueInfo(1 /*HMQ_CURRENT*/, &mqinfo, sizeof(mqinfo)) == FALSE)
     417    {
     418        // attempt to initialize PM and try again
     419        HAB hab = WinInitialize(0);
     420        if (hab)
     421        {
     422            HMQ hmq = WinCreateMsgQueue(hab, 0);
     423            if (hmq)
     424                haveHMQ = TRUE;
     425        }
     426    }
     427    else
     428        haveHMQ = TRUE;
     429
     430    WinMessageBox(HWND_DESKTOP, NULL, msg, "Odin: Fatal Error", 0,
     431                  MB_APPLMODAL | MB_MOVEABLE | MB_ERROR | MB_OK);
     432
     433    // duplicate the message to the console just in case (PM may be not
     434    // available)
     435    ULONG dummy;
     436    DosWrite((HFILE)1, (PVOID)&msg, strlen(msg), &dummy);
     437}
     438
Note: See TracChangeset for help on using the changeset viewer.