Changeset 2833
- Timestamp:
- Oct 26, 2006, 2:08:09 AM (19 years ago)
- Location:
- trunk/kLdr
- Files:
-
- 3 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/Makefile.kmk
r2827 r2833 70 70 kLdr_CFLAGS = -W3 -Zl 71 71 kLdr_ASFLAGS = -f win 72 kLdr_LDFLAGS = -Entry:DllMain@12 72 73 kLdr_DEFS = __WIN__ 73 74 kLdr_SDKS = WIN32SDK … … 90 91 kLdr_SOURCES = \ 91 92 kLdr.c \ 93 kLdrDy.c \ 94 kLdrDySearch.c \ 92 95 kLdrHlp.c \ 93 96 kLdrHlpHeap.c \ … … 99 102 kLdr-os2.def \ 100 103 kLdrA-os2.asm 104 kLdr_SOURCES.win = \ 105 kLdr-win.def \ 106 kLdr-win.c 107 kLdr_SOURCES.win32 = $(kLdr_SOURCES.win) 108 kLdr_SOURCES.win64 = $(kLdr_SOURCES.win) 101 109 102 110 # -
trunk/kLdr/kLdr.h
r2832 r2833 548 548 549 549 /** The handle to a dynamic loader module. */ 550 typedef struct KLDRDYLD *HKLDRMOD;550 typedef struct KLDRDYLDMOD *HKLDRMOD; 551 551 /** Pointer to the handle to a dynamic loader module. */ 552 552 typedef HKLDRMOD *PHKLDRMOD; 553 /** NIL handle value. */ 554 #define NIL_HKLDRMOD ((HKLDRMOD)0) 553 555 554 556 … … 578 580 /** Emulate the most common UNIX file search method. */ 579 581 KLDRDYLD_SEARCH_UNIX_COMMON, 582 /** End of the valid file search method values. */ 583 KLDRDYLD_SEARCH_END, 584 /** Hack to blow the type up to 32-bit. */ 585 KLDRDYLD_SEARCH_32BIT_HACK = 0x7fffffff 580 586 } KLDRDYLDSEARCH; 581 587 … … 593 599 594 600 595 int kLdrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, unsigned fFlags,596 PHKLDRMOD phMod, char *pszErr, size_t cchErr);601 int kLdrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 602 unsigned fFlags, PHKLDRMOD phMod, char *pszErr, size_t cchErr); 597 603 int kLdrDyldUnload(HKLDRMOD hMod); 598 int kLdrDyldFindByName(const char *pszDll, PHKLDRMOD *phMod);599 int kLdrDyldFindBy PC(uintptr_t PC, PHKLDRMOD *phMod, uint32_t *piSegment, uintptr_t *poffSegment);604 int kLdrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PHKLDRMOD phMod); 605 int kLdrDyldFindByAddress(uintptr_t Address, PHKLDRMOD phMod, uint32_t *piSegment, uintptr_t *poffSegment); 600 606 int kLdrDyldGetName(HKLDRMOD hMod, char *pszName, size_t cchName); 601 int kLdrDyldGetFilename(HKLDRMOD hMod, char *psz Name, size_t cchName);607 int kLdrDyldGetFilename(HKLDRMOD hMod, char *pszFilename, size_t cchFilenamep); 602 608 int kLdrDyldQuerySymbol(HKLDRMOD hMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind); 603 609 … … 694 700 /** The mach-o image format isn't supported by this kLdr build. */ 695 701 #define KLDR_ERR_AOUT_NOT_SUPPORTED (KLDR_ERR_BASE + 8) 696 /** The mach-o image format isn't supported by this kLdr build. */ 697 #define KLDR_ERR_BAD_FIXUP (KLDR_ERR_BASE + 32) 702 703 /** Invalid parameter to a kLdr API. */ 704 #define KLDR_ERR_INVALID_PARAMETER (KLDR_ERR_BASE + 32) 705 /** Invalid handle parameter to a kLdr API. */ 706 #define KLDR_ERR_INVALID_HANDLE (KLDR_ERR_BASE + 33) 707 708 /** Encountered a bad fixup. */ 709 #define KLDR_ERR_BAD_FIXUP (KLDR_ERR_BASE + 48) 698 710 699 711 /** @} */ -
trunk/kLdr/kLdrDy.c
r2828 r2833 39 39 /** Pointer to the head module (the executable). 40 40 * (This is exported, so no prefix.) */ 41 PKLDRDY kLdrDyHead = NULL;41 PKLDRDYLDMOD kLdrDyldHead = NULL; 42 42 /** Pointer to the tail module. 43 43 * (This is exported, so no prefix.) */ 44 PKLDRDY kLdrDyTail = NULL;44 PKLDRDYLDMOD kLdrDyldTail = NULL; 45 45 /** The Library search path. */ 46 char kLdrDy LibraryPath[4096];46 char kLdrDyldLibraryPath[4096]; 47 47 /** The executable flags. */ 48 uint32_t kLdrDyFlags; 49 /** Set if we've initialized the loader. */ 50 static int fInitialized = 0; 48 uint32_t kLdrDyldFlags; 51 49 52 50 … … 54 52 * Internal Functions * 55 53 *******************************************************************************/ 56 static int kldrDyInit(void); 57 static int kldrDyTerm(void); 54 static int kldrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 55 unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr); 56 static int kldrDyldUnload(PKLDRDYLDMOD pMod); 57 static int kldrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PPKLDRDYLDMOD ppMod); 58 static int kldrDyldFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment); 59 static int kldrDyldGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName); 60 static int kldrDyldGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename); 61 static int kldrDyldQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind); 62 63 64 65 /** 66 * Initialize the dynamic loader. 67 */ 68 int kldrDyInit(void) 69 { 70 kLdrDyldHead = NULL; 71 kLdrDyldTail = NULL; 72 kLdrDyldFlags = 0; 73 return 0; 74 } 75 76 77 /** 78 * Terminate the dynamic loader. 79 */ 80 void kldrDyTerm(void) 81 { 82 83 } 84 85 86 /** 87 * Loads a module into the current process. 88 * 89 * @returns 0 on success, non-zero native OS status code or kLdr status code on failure. 90 * @param pszDll The name of the dll to open. 91 * @param pszDefPrefix Prefix to use when searching. 92 * @param pszDefSuffix Suffix to use when searching. 93 * @param enmSearch Method to use when locating the module and any modules it may depend on. 94 * @param fFlags Flags, a combintation of the KLDRYDLD_LOAD_FLAGS_* \#defines. 95 * @param phMod Where to store the handle to the loaded module. 96 * @param pszErr Where to store extended error information. (optional) 97 * @param cchErr The size of the buffer pointed to by pszErr. 98 */ 99 int kLdrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 100 unsigned fFlags, PHKLDRMOD phMod, char *pszErr, size_t cchErr) 101 { 102 int rc; 103 104 /* validate arguments and initialize return values. */ 105 if (pszErr && cchErr) 106 *pszErr = '\0'; 107 *phMod = NIL_HKLDRMOD; 108 KLDRHLP_VALIDATE_STRING(pszDll); 109 KLDRHLP_VALIDATE_OPTIONAL_STRING(pszDefPrefix); 110 KLDRHLP_VALIDATE_OPTIONAL_STRING(pszDefSuffix); 111 KLDRHLP_VALIDATE_ENUM(enmSearch, KLDRDYLD_SEARCH); 112 KLDRHLP_VALIDATE_OPTIONAL_BUFFER(pszErr, cchErr); 113 114 /* get the semaphore and do the job. */ 115 rc = kldrHlpSemRequest(); 116 if (!rc) 117 { 118 PKLDRDYLDMOD pMod = NULL; 119 rc = kldrDyldLoad(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, fFlags, phMod, pszErr, cchErr); 120 kldrHlpSemRelease(); 121 *phMod = pMod; 122 } 123 return rc; 124 } 125 126 127 /** 128 * Unloads a module loaded by kLdrDyldLoad. 129 * 130 * @returns 0 on success, non-zero native OS status code or kLdr status code on failure. 131 * @param hMod Module handle. 132 */ 133 int kLdrDyldUnload(HKLDRMOD hMod) 134 { 135 int rc; 136 137 /* validate */ 138 KLDRDYLD_VALIDATE_HKLDRMOD(hMod); 139 140 /* get sem & do work */ 141 rc = kldrHlpSemRequest(); 142 if (!rc) 143 { 144 rc = kldrDyldUnload(hMod); 145 kldrHlpSemRelease(); 146 } 147 return rc; 148 } 149 150 151 /** 152 * Finds a module by name or filename. 153 * 154 * This call does not increase any reference counters and must not be 155 * paired with kLdrDyldUnload() like kLdrDyldLoad(). 156 * 157 * @returns 0 on success. 158 * @returns KLDR_ERR_MODULE_NOT_FOUND on failure. 159 * @param pszDll The name of the dll to look for. 160 * @param pszDefPrefix Prefix to use when searching. 161 * @param pszDefSuffix Suffix to use when searching. 162 * @param enmSearch Method to use when locating the module. 163 * @param phMod Where to store the handle of the module on success. 164 */ 165 int kLdrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PHKLDRMOD phMod) 166 { 167 int rc; 168 169 /* validate & initialize */ 170 *phMod = NIL_HKLDRMOD; 171 KLDRHLP_VALIDATE_STRING(pszDll); 172 173 /* get sem & do work */ 174 rc = kldrHlpSemRequest(); 175 if (!rc) 176 { 177 PKLDRDYLDMOD pMod = NULL; 178 rc = kldrDyldFindByName(pszDll, pszDefPrefix, pszDefSuffix, enmSearch, phMod); 179 kldrHlpSemRelease(); 180 *phMod = pMod; 181 } 182 return rc; 183 } 184 185 186 /** 187 * Finds a module by address. 188 * 189 * This call does not increase any reference counters and must not be 190 * paired with kLdrDyldUnload() like kLdrDyldLoad(). 191 * 192 * @returns 0 on success. 193 * @returns KLDR_ERR_MODULE_NOT_FOUND on failure. 194 * @param Address The address believed to be within some module. 195 * @param phMod Where to store the module handle on success. 196 * @param piSegment Where to store the segment number. (optional) 197 * @param poffSegment Where to store the offset into the segment. (optional) 198 */ 199 int kLdrDyldFindByAddress(uintptr_t Address, PHKLDRMOD phMod, uint32_t *piSegment, uintptr_t *poffSegment) 200 { 201 int rc; 202 203 /* validate & initialize */ 204 *phMod = NIL_HKLDRMOD; 205 if (piSegment) 206 *piSegment = ~(uint32_t)0; 207 if (poffSegment) 208 *poffSegment = ~(uintptr_t)0; 209 210 /* get sem & do work */ 211 rc = kldrHlpSemRequest(); 212 if (!rc) 213 { 214 PKLDRDYLDMOD pMod = NULL; 215 rc = kldrDyldFindByAddress(Address, &pMod, piSegment, poffSegment); 216 kldrHlpSemRelease(); 217 *phMod = pMod; 218 } 219 return rc; 220 } 221 222 223 /** 224 * Gets the module name. 225 * 226 * @returns 0 on success and pszName filled with the name. 227 * @returns KLDR_ERR_INVALID_HANDLE or KLDR_ERR_BUFFER_OVERFLOW on failure. 228 * @param hMod The module handle. 229 * @param pszName Where to put the name. 230 * @param cchName The size of the name buffer. 231 * @see kLdrDyldGetFilename 232 */ 233 int kLdrDyldGetName(HKLDRMOD hMod, char *pszName, size_t cchName) 234 { 235 int rc; 236 237 /* validate */ 238 if (pszName && cchName) 239 *pszName = '\0'; 240 KLDRDYLD_VALIDATE_HKLDRMOD(hMod); 241 KLDRHLP_VALIDATE_BUFFER(pszName, cchName); 242 243 /* get sem & do work */ 244 rc = kldrHlpSemRequest(); 245 if (!rc) 246 { 247 rc = kldrDyldGetName(hMod, pszName, cchName); 248 kldrHlpSemRelease(); 249 } 250 return rc; 251 } 252 253 254 /** 255 * Gets the module filename. 256 * 257 * @returns 0 on success and pszFilename filled with the name. 258 * @returns KLDR_ERR_INVALID_HANDLE or KLDR_ERR_BUFFER_OVERFLOW on failure. 259 * @param hMod The module handle. 260 * @param pszFilename Where to put the filename. 261 * @param cchFilename The size of the filename buffer. 262 * @see kLdrDyldGetName 263 */ 264 int kLdrDyldGetFilename(HKLDRMOD hMod, char *pszFilename, size_t cchFilename) 265 { 266 int rc; 267 268 /* validate & initialize */ 269 if (pszFilename && cchFilename); 270 *pszFilename = '\0'; 271 KLDRDYLD_VALIDATE_HKLDRMOD(hMod); 272 KLDRHLP_VALIDATE_BUFFER(pszFilename, cchFilename); 273 274 /* get sem & do work */ 275 rc = kldrHlpSemRequest(); 276 if (!rc) 277 { 278 rc = kldrDyldGetFilename(hMod, pszFilename, cchFilename); 279 kldrHlpSemRelease(); 280 } 281 return rc; 282 } 283 284 285 /** 286 * Queries the value and type of a symbol. 287 * 288 * @returns 0 on success and pValue and pfKind set. 289 * @returns KLDR_ERR_INVALID_HANDLE or KLDR_ERR_SYMBOL_NOT_FOUND on failure. 290 * @param hMod The module handle. 291 * @param uSymbolOrdinal The symbol ordinal. This is ignored if pszSymbolName is non-zero. 292 * @param pszSymbolName The symbol name. 293 * @param pValue Where to put the symbol value. Optional if pfKind is non-zero. 294 * @param pfKind Where to put the symbol kind flags. Optional if pValue is non-zero. 295 */ 296 int kLdrDyldQuerySymbol(HKLDRMOD hMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind) 297 { 298 int rc; 299 300 /* validate & initialize */ 301 if (pfKind) 302 *pfKind = 0; 303 if (pValue) 304 *pValue = 0; 305 if (!pfKind && !pValue) 306 return KLDR_ERR_INVALID_PARAMETER; 307 KLDRDYLD_VALIDATE_HKLDRMOD(hMod); 308 KLDRHLP_VALIDATE_OPTIONAL_STRING(pszSymbolName); 309 310 /* get sem & do work */ 311 rc = kldrHlpSemRequest(); 312 if (!rc) 313 { 314 rc = kldrDyldQuerySymbol(hMod, uSymbolOrdinal, pszSymbolName, pValue, pfKind); 315 kldrHlpSemRelease(); 316 } 317 return rc; 318 } 319 320 321 322 323 324 325 /** 326 * Worker for kldrDyldLoad(). 327 * @internal 328 */ 329 static int kldrDyldLoad(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, 330 unsigned fFlags, PPKLDRDYLDMOD ppMod, char *pszErr, size_t cchErr) 331 { 332 /* 333 * Open the module. 334 */ 335 336 337 return -1; 338 } 339 340 341 /** 342 * Worker for kldrDyldUnload(). 343 * @internal 344 */ 345 static int kldrDyldUnload(HKLDRMOD hMod) 346 { 347 return -1; 348 } 349 350 351 /** 352 * Worker for kLdrDyldFindByName(). 353 * @internal 354 */ 355 static int kldrDyldFindByName(const char *pszDll, const char *pszDefPrefix, const char *pszDefSuffix, KLDRDYLDSEARCH enmSearch, PPKLDRDYLDMOD ppMod) 356 { 357 return -1; 358 } 359 360 361 /** 362 * Worker for kLdrDyldFindByAddress(). 363 * @internal 364 */ 365 static int kldrDyldFindByAddress(uintptr_t Address, PPKLDRDYLDMOD ppMod, uint32_t *piSegment, uintptr_t *poffSegment) 366 { 367 return -1; 368 } 369 370 371 /** 372 * Worker for kLdrDyldGetName(). 373 * @internal 374 */ 375 static int kldrDyldGetName(PKLDRDYLDMOD pMod, char *pszName, size_t cchName) 376 { 377 return -1; 378 } 379 380 381 /** 382 * Worker for kLdrDyldGetFilename(). 383 * @internal 384 */ 385 static int kldrDyldGetFilename(PKLDRDYLDMOD pMod, char *pszFilename, size_t cchFilename) 386 { 387 return -1; 388 } 389 390 391 /** 392 * Worker for kLdrDyldQuerySymbol(). 393 * @internal 394 */ 395 static int kldrDyldQuerySymbol(PKLDRDYLDMOD pMod, uint32_t uSymbolOrdinal, const char *pszSymbolName, uintptr_t *pValue, uint32_t *pfKind) 396 { 397 return -1; 398 } 58 399 59 400 60 401 #if 0 61 /**62 * Initialize the loader.63 */64 int kldrDyInit(void)65 {66 if (fInitialized)67 return 0;68 /** @todo */69 return 0;70 }71 72 73 74 402 void kldrLoadExe(PKLDREXEARGS pArgs) 75 403 { … … 146 474 pCur->enmState = KLDRSTATE_LOADED; 147 475 148 kldr SemRelease();476 kldrHlpSemRelease(); 149 477 150 478 /* … … 153 481 kldrOSStartExe(pLdrModuleHead, pvEntry); 154 482 } 155 156 157 int kLdrLoadDll(const char *pszFilename, unsigned fFlags, void *pvmod)158 {159 160 return -1;161 }162 163 164 483 165 484 -
trunk/kLdr/kLdrHlp.h
r2832 r2833 160 160 161 161 162 /** @name Parameter validation macros 163 * @{ */ 164 165 /** Crash validation of a string argument. */ 166 #define KLDRHLP_VALIDATE_STRING(str) \ 167 do { strlen(str); } while (0) 168 169 /** Crash validation of an optional string argument. */ 170 #define KLDRHLP_VALIDATE_OPTIONAL_STRING(str) \ 171 do { if (str) { KLDRHLP_VALIDATE_STRING(str); } } while (0) 172 173 /** Return/Crash validation of an output buffer. */ 174 #define KLDRHLP_VALIDATE_BUFFER(buf, cb) \ 175 do { \ 176 if ((cb)) \ 177 { \ 178 uint8_t __b; \ 179 uint8_t volatile * __pb = (uint8_t volatile *)(buf); \ 180 size_t __cbPage1 = 0x1000 - ((uintptr_t)(__pb) & 0xfff); /* ASSUMES page size! */ \ 181 __b = *__pb; *__pb = 0xff; *__pb = __b; \ 182 if ((cb) > __cbPage1) \ 183 { \ 184 size_t __cb = (cb) - __cbPage1; \ 185 __pb -= __cbPage1; \ 186 for (;;) \ 187 { \ 188 __b = *__pb; *__pb = 0xff; *__pb = __b; \ 189 if (__cb < 0x1000) \ 190 break; \ 191 __pb += 0x1000; \ 192 __cb -= 0x1000; \ 193 } \ 194 } \ 195 } \ 196 else \ 197 return KLDR_ERR_INVALID_PARAMETER; \ 198 } while (0) 199 200 /** Crash validation of an optional output buffer. */ 201 #define KLDRHLP_VALIDATE_OPTIONAL_BUFFER(buf, cb) \ 202 do { \ 203 if ((buf) != NULL && (cb) != 0) \ 204 { \ 205 KLDRHLP_VALIDATE_BUFFER(buf, cb); \ 206 } \ 207 } while (0) 208 209 /** Return validation of an enum argument. */ 210 #define KLDRHLP_VALIDATE_ENUM(arg, enumname) \ 211 do { \ 212 if ((arg) <= enumname##_INVALID || (arg) >= enumname##_END) \ 213 { \ 214 return KLDR_ERR_INVALID_PARAMETER; \ 215 } \ 216 } while (0) 217 162 218 /** @} */ 163 219 164 220 221 /** @} */ 222 165 223 #endif /* __kLdrHlp_h__ */ 166 224 -
trunk/kLdr/kLdrInternal.h
r2832 r2833 53 53 /** @} */ 54 54 55 /** @defgroup grp_kLdrInternal Internals 56 * @internal 57 * @{ 58 */ 59 55 60 56 61 /** Native file provider operations. */ … … 86 91 * Dynamic loader module. 87 92 */ 88 typedef struct KLDRDY MOD93 typedef struct KLDRDYLDMOD 89 94 { 90 /** The next module in the list. */91 struct KLDRDYMOD *pNext;92 /** The prev module in the list. */93 struct KLDRDYMOD *pPrev;95 /** Magic number. */ 96 uint32_t u32MagicHead; 97 /** The module state. */ 98 KLDRSTATE enmState; 94 99 /** The module. */ 95 100 PKLDRMOD pMod; 96 /** The module state. */97 KLDRSTATE enmState;98 101 /** The number of references. */ 99 102 uint32_t cRefs; 100 103 /** The number of dynamic references. */ 101 104 uint32_t cDynRefs; 102 /** Magic number. */103 uint32_t u32Magic;104 105 /** Set if this is the executable module. */ 105 106 uint32_t fExecutable : 1; … … 110 111 /** Reserved for future use. */ 111 112 uint32_t fReserved : 29; 112 } KLDRDYMOD, *PKLDRDYMOD; 113 /** The next module in the list. */ 114 struct KLDRDYMOD *pNext; 115 /** The prev module in the list. */ 116 struct KLDRDYMOD *pPrev; 117 /** Magic number. */ 118 uint32_t u32MagicTail; 119 } KLDRDYLDMOD, *PKLDRDYLDMOD, **PPKLDRDYLDMOD; 120 121 /** KLDRDYMOD magic value. (Fuyumi Soryo) */ 122 #define KLDRDYMOD_MAGIC 0x19590106 123 124 /** Return / crash validation of a module handle argument. */ 125 #define KLDRDYLD_VALIDATE_HKLDRMOD(hMod) \ 126 do { \ 127 if ( (hMod) == NIL_HKLDRMOD \ 128 || (hMod)->u32MagicHead != KLDRDYMOD_MAGIC \ 129 || (hMod)->u32MagicTail != KLDRDYMOD_MAGIC) \ 130 { \ 131 return KLDR_ERR_INVALID_HANDLE; \ 132 } \ 133 } while (0) 113 134 114 135 115 136 /** Pointer to the head module (the executable). */ 116 extern PKLDRDY MOD kLdrModuleHead;137 extern PKLDRDYLDMOD kLdrDyldModuleHead; 117 138 /** Pointer to the tail module. */ 118 extern PKLDRDY MOD kLdrModuleTail;139 extern PKLDRDYLDMOD kLdrDyldModuleTail; 119 140 /** The Library search path. */ 120 extern char kLdr LibraryPath[4096];141 extern char kLdrDyldLibraryPath[4096]; 121 142 122 /** @name The Internal APIs 123 * @internal 124 * @{ */ 143 125 144 #if 0 126 int kldrDyOpenExe(const char *pszFilename, PPKLDRMOD ppMod)127 int kldrDyOpen(const char *pszFilename, unsigned fFlags, PPKLDRMOD ppMod);128 int kldrClose(PKLDRMOD pMod);129 130 145 void kldrFailure(const char *pszFilename, ...); 131 146 #endif 147 132 148 /** @} */ 133 134 149 #ifdef __cplusplus 135 150 }
Note:
See TracChangeset
for help on using the changeset viewer.