Changeset 21734 for branches/gcc-kmk/src/kernel32/initterm.cpp
- Timestamp:
- Oct 24, 2011, 8:04:27 PM (14 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
branches/gcc-kmk/src/kernel32/initterm.cpp
r21716 r21734 6 6 * Copyright 1998 Peter Fitzsimmons 7 7 * 8 *9 8 * Project Odin Software License can be found in LICENSE.TXT 10 *11 9 */ 12 10 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 */26 11 #define INCL_DOSMODULEMGR 27 12 #define INCL_DOSMISC … … 68 53 PVOID SYSTEM _O32_GetEnvironmentStrings( VOID ); 69 54 70 extern "C" { 71 //Win32 resource table (produced by wrc) 72 extern DWORD kernel32_PEResTab; 73 } 55 // Win32 resource table (produced by wrc) 56 extern DWORD kernel32_PEResTab; 57 58 static HMODULE dllHandle = 0; 74 59 75 60 extern PFN pfnImSetMsgQueueProperty; 76 61 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) 64 int globLoadNr = 0; 65 #pragma data_seg() 66 67 BOOL fVersionWarp3 = FALSE; 68 BOOL fCustomBuild = FALSE; 69 70 ULONG flAllocMem = 0; /* flag to optimize DosAllocMem to use all the memory on SMP machines */ 71 ULONG ulMaxAddr = 0x20000000; /* end of user address space. */ 72 int loadNr = 0; 73 char kernel32Path[CCHMAXPATH] = ""; 74 BOOL fInit = FALSE; 75 BOOL fWin32k = FALSE; 76 HMODULE imHandle = 0; 77 char szModName[ 256 ] = ""; 78 79 static ULONG DLL_InitKernel32_internal(ULONG hModule) 96 80 { 97 81 size_t i; … … 99 83 ULONG ulSysinfo, version[2]; 100 84 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) 110 114 { 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 } 119 203 #endif 120 204 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 254 ULONG SYSTEM DLL_InitKernel32(ULONG hModule) 255 { 256 ULONG code = DLL_InitKernel32_internal(hModule); 257 258 if (code == -1) 295 259 ReportFatalDllInitError("KERNEL32"); 296 260 297 return rc; 298 } 299 //****************************************************************************** 300 //****************************************************************************** 301 void APIENTRY cleanupKernel32(ULONG ulReason) 261 return code; 262 } 263 264 void SYSTEM DLL_TermKernel32(ULONG hModule) 302 265 { 303 266 if (!fInit) … … 309 272 } 310 273 311 dprintf(("kernel32 exit %d", ulReason));274 dprintf(("kernel32 exit")); 312 275 313 276 if( IsDBCSEnv() && imHandle ) … … 374 337 RasUninitialize (); 375 338 376 return ; 377 } 378 //****************************************************************************** 379 //****************************************************************************** 339 if (dllHandle) 340 UnregisterLxDll(dllHandle); 341 } 342 343 ULONG SYSTEM DLL_Init(ULONG hModule) 344 { 345 if (DLL_InitDefault(hModule) == -1) 346 return -1; 347 return DLL_InitKernel32(hModule); 348 } 349 350 void SYSTEM DLL_Term(ULONG hModule) 351 { 352 DLL_TermKernel32(hModule); 353 DLL_TermDefault(hModule); 354 } 355 356 ULONG APIENTRY _O32__DLL_InitTerm(ULONG handle, ULONG flag); 357 358 BOOL 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 387 VOID 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.