Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

540 lines
11 KiB

  1. TITLE LDSELF - BootStrap procedure for KERNEL.EXE
  2. .xlist
  3. ?NODATA=1
  4. ?TF=1
  5. include kernel.inc
  6. include newexe.inc
  7. include tdb.inc
  8. .list
  9. externFP IGlobalAlloc
  10. externFP IGlobalLock
  11. externFP IGlobalUnlock
  12. DataBegin
  13. externW winVer
  14. ;externW pGlobalHeap
  15. DataEnd
  16. sBegin CODE
  17. assumes CS,CODE
  18. assumes DS,NOTHING
  19. assumes ES,NOTHING
  20. ;externW MyCSDS
  21. externNP SetOwner
  22. externFP set_discarded_sel_owner
  23. ; extra debugging parameter for EntProcAddress to avoid RIPing if all
  24. ; we are doing is a GetProcAddress to something that isn't there.
  25. externNP EntProcAddress
  26. cProc FarEntProcAddress,<PUBLIC,FAR,NODATA>
  27. parmW hExe
  28. parmW entno
  29. cBegin
  30. if KDEBUG
  31. mov cx,1
  32. cCall EntProcAddress,<hExe,entno,cx>
  33. else
  34. cCall EntProcAddress,<hExe,entno>
  35. endif
  36. cEnd
  37. if KDEBUG
  38. ; AppLoaderEntProcAddress
  39. ; This call added for the app loader. The above call (FarEntProcAddress)
  40. ; forces no RIPs. When we're using the app loader, we really want
  41. ; RIPs, so in debug we add this entry point.
  42. ; This call ONLY exists in debug.
  43. cProc AppLoaderEntProcAddress,<PUBLIC,FAR,NODATA>
  44. parmW hExe
  45. parmW entno
  46. cBegin
  47. xor cx,cx ;Force RIPs on this one
  48. cCall EntProcAddress,<hExe,entno,cx>
  49. cEnd
  50. endif ; KDEBUG
  51. externNP FindOrdinal
  52. cProc FarFindOrdinal,<PUBLIC,FAR,NODATA>
  53. parmW hExe
  54. parmD lpname
  55. parmW fh
  56. cBegin
  57. cCall FindOrdinal,<hExe,lpName,fh>
  58. cEnd
  59. externNP LoadSegment
  60. cProc FarLoadSegment,<PUBLIC,FAR,NODATA>
  61. parmW hExe
  62. parmW segno
  63. parmW fh
  64. parmW isfh
  65. cBegin
  66. cCall LoadSegment,<hExe,segno,fh,isfh>
  67. cEnd
  68. externNP AllocSeg
  69. cProc FarAllocSeg,<PUBLIC,FAR,NODATA>
  70. parmD pSegInfo
  71. cBegin
  72. cCall AllocSeg,<pSegInfo>
  73. cEnd
  74. externNP DeleteTask
  75. cProc FarDeleteTask,<PUBLIC,FAR,NODATA,ATOMIC>
  76. parmW taskID
  77. cBegin
  78. cCall DeleteTask,<taskID>
  79. cEnd
  80. externNP UnlinkObject
  81. cProc FarUnlinkObject,<PUBLIC,FAR,NODATA,ATOMIC>
  82. cBegin
  83. cCall UnlinkObject
  84. cEnd
  85. externNP MyLower
  86. cProc FarMyLower,<PUBLIC,FAR,NODATA,ATOMIC>
  87. cBegin
  88. cCall MyLower
  89. cEnd
  90. externNP MyUpper
  91. cProc FarMyUpper,<PUBLIC,FAR,NODATA,ATOMIC>
  92. cBegin
  93. cCall MyUpper
  94. cEnd
  95. externNP MyAlloc
  96. cProc FarMyAlloc,<PUBLIC,FAR,NODATA>
  97. parmW aflags
  98. parmW nsize
  99. parmW nelem
  100. cBegin
  101. cCall MyAlloc,<aflags,nsize,nelem>
  102. cEnd
  103. externNP MyAllocLinear
  104. cProc FarMyAllocLinear,<PUBLIC,FAR,NODATA>
  105. parmW aflags
  106. parmD dwBytes
  107. cBegin
  108. cCall MyAllocLinear,<aflags,dwBytes>
  109. cEnd
  110. externNP MyLock
  111. cProc FarMyLock,<PUBLIC,FAR,NODATA>
  112. parmW h1
  113. cBegin
  114. cCall MyLock,<h1>
  115. cEnd
  116. externNP MyFree
  117. cProc FarMyFree,<PUBLIC,FAR,NODATA>
  118. parmW h2
  119. cBegin
  120. cCall MyFree,<h2>
  121. cEnd
  122. externNP genter
  123. cProc Far_genter,<PUBLIC,FAR,NODATA,ATOMIC>
  124. cBegin
  125. cCall genter
  126. cEnd
  127. externNP gleave
  128. cProc Far_gleave,<PUBLIC,FAR,NODATA,ATOMIC>
  129. cBegin
  130. cCall gleave
  131. cEnd
  132. externNP lalign
  133. cProc Far_lalign,<PUBLIC,FAR,NODATA,ATOMIC>
  134. cBegin
  135. cCall lalign
  136. cEnd
  137. externNP lrepsetup
  138. cProc Far_lrepsetup,<PUBLIC,FAR,NODATA,ATOMIC>
  139. cBegin
  140. cCall lrepsetup
  141. cEnd
  142. if KDEBUG
  143. externNP lfillCC
  144. cProc Far_lfillCC,<PUBLIC,FAR,NODATA,ATOMIC>
  145. cBegin
  146. cCall lfillCC
  147. cEnd
  148. endif
  149. sEnd CODE
  150. sBegin INITCODE
  151. ;-----------------------------------------------------------------------;
  152. ; LKExeHeader ;
  153. ; ;
  154. ; Copy of LoadExeHeader (from LDHEADER.ASM) that has been stripped ;
  155. ; down to the minimum needed to load the new format .EXE header for ;
  156. ; KERNEL.EXE. ;
  157. ; ;
  158. ; Arguments: ;
  159. ; parmW pMem ;
  160. ; parmD pfilename ;
  161. ; ;
  162. ; Returns: ;
  163. ; AX = segment of exe header ;
  164. ; ;
  165. ; Error Returns: ;
  166. ; AX = 0 ;
  167. ; ;
  168. ; Registers Preserved: ;
  169. ; DI,SI,DS ;
  170. ; ;
  171. ; Registers Destroyed: ;
  172. ; AX,BX,CX,DX,ES ;
  173. ; Calls: ;
  174. ; ;
  175. ; History: ;
  176. ; ;
  177. ; Thu Mar 19, 1987 08:35:32p -by- David N. Weise [davidw] ;
  178. ; Added this nifty comment block. ;
  179. ;-----------------------------------------------------------------------;
  180. cProc LKExeHeader,<PUBLIC,NEAR>,<si,di,ds>
  181. parmW pMem
  182. parmD pfilename
  183. localW nchars
  184. cBegin
  185. lds si,pfilename
  186. xor ax,ax
  187. mov al,ds:[si].opLen
  188. inc ax ; include null byte
  189. mov nchars,ax
  190. mov ds,pMem
  191. xor si,si
  192. mov di,ds:[si].ne_enttab ; Compute size of resident new header
  193. add di, 6 ; Room for one block of entries
  194. push si
  195. mov si, ds:[si].ne_enttab ; Scan current entry table
  196. calc_next_block:
  197. lodsw
  198. xor cx, cx
  199. mov cl, al
  200. jcxz calc_ent_sized
  201. cmp ah, ENT_UNUSED ; 6 bytes per unused block
  202. jne calc_used_block
  203. add di, 6
  204. jmps calc_next_block
  205. calc_used_block:
  206. errnz <5-SIZE PENT>
  207. mov bx, cx
  208. shl bx, 1
  209. add di, bx
  210. add di, bx ; 5 bytes per entry
  211. add di, cx
  212. add si, bx
  213. add si, cx ; Skip the block
  214. cmp ah, ENT_MOVEABLE
  215. jne calc_next_block
  216. calc_moveable_block:
  217. add si, bx
  218. add si, cx ; Skip the block
  219. jmps calc_next_block
  220. calc_ent_sized:
  221. pop si
  222. mov cx,ds:[si].ne_cseg ; + 3 * #segments
  223. ; Reserve space for segment reference bytes
  224. add di,cx
  225. shl cx,1
  226. ; Reserve space for ns_handle field in segment table
  227. add di,cx
  228. errnz <10-SIZE NEW_SEG1>
  229. if LDCHKSUM
  230. ; Reserve space for segment chksum table (2 words per segment)
  231. add di,cx
  232. add di,cx
  233. endif
  234. ; Reserve space for file info block at end
  235. add di,16 ; 16 bytes of slop
  236. add di,nchars ; + size of file info block
  237. xor ax,ax ; Allocate a block for header
  238. cCall IGlobalAlloc,<GA_MOVEABLE,ax,di>
  239. push ax
  240. cCall IGlobalLock,<ax>
  241. pop ax
  242. push dx
  243. cCall IGlobalUnlock,<ax>
  244. pop ax
  245. mov es,ax ; ES:DI -> new header location
  246. xor di,di
  247. cld ; DS:SI -> old header
  248. mov cx,SIZE NEW_EXE ; Copy fixed portion of header
  249. cld
  250. rep movsb
  251. mov cx,es:[ne_cseg] ; Copy segment table
  252. mov es:[ne_segtab],di
  253. recopyseg:
  254. movsw ; ns_sector
  255. movsw ; ns_cbseg
  256. lodsw ; ns_flags
  257. errnz <4-ns_flags>
  258. and ax,not NS286DOS ; Clear 286DOS bits
  259. or ax,NENOTP+4000h ; Mark library code segments
  260. stosw
  261. movsw ; ns_minalloc
  262. errnz <8-SIZE NEW_SEG>
  263. xor ax,ax
  264. stosw ; one word for ns_handle field
  265. errnz <10-SIZE NEW_SEG1>
  266. loop recopyseg
  267. recopysegx:
  268. mov cx,es:[ne_restab] ; Copy resource table
  269. sub cx,es:[ne_rsrctab]
  270. mov es:[ne_rsrctab],di
  271. rep movsb
  272. rerestab:
  273. mov cx,es:[ne_modtab] ; Copy resident name table
  274. sub cx,es:[ne_restab]
  275. mov es:[ne_restab],di
  276. rep movsb
  277. mov cx,es:[ne_imptab] ; Copy module xref table
  278. sub cx,es:[ne_modtab]
  279. mov es:[ne_modtab],di
  280. rep movsb
  281. mov es:[ne_psegrefbytes],di ; Insert segment reference byte table
  282. mov cx,es:[ne_cseg]
  283. mov al,0FFh
  284. rep stosb ; initialize to not-loaded condition
  285. mov es:[ne_pretthunks],di ; Setup return thunks
  286. if LDCHKSUM
  287. mov es:[ne_psegcsum],di ; Setup segment chksum table
  288. mov cx,es:[ne_cseg]
  289. jcxz resetsegcsumexit
  290. xor ax,ax
  291. shl cx,1 ; Two words per segment
  292. rep stosw
  293. resetsegcsumexit:
  294. endif
  295. mov cx,es:[ne_enttab] ; Copy imported name table
  296. sub cx,es:[ne_imptab]
  297. mov es:[ne_imptab],di
  298. jcxz reenttab
  299. rep movsb
  300. reenttab:
  301. mov es:[ne_enttab],di
  302. ; Scan current entry table
  303. xor ax, ax ; First entry in block
  304. mov bx, di ; Pointer to info for this block
  305. stosw ; Starts at 0
  306. stosw ; Ends at 0
  307. stosw ; And is not even here!
  308. copy_next_block:
  309. lodsw ; Get # entries and type
  310. xor cx, cx
  311. mov cl, al
  312. jcxz copy_ent_done
  313. mov al, ah
  314. cmp al, ENT_UNUSED
  315. jne copy_used_block
  316. mov ax, es:[bx].PM_EntEnd ; Last entry in current block
  317. cmp ax, es:[bx].PM_EntStart ; No current block?
  318. jne end_used_block
  319. int 3
  320. add es:[bx].PM_EntStart, cx
  321. add es:[bx].PM_EntEnd, cx
  322. jmps copy_next_block
  323. end_used_block:
  324. mov es:[bx].PM_EntNext, di ; Pointer to next block
  325. mov bx, di
  326. add ax, cx ; Skip unused entries
  327. stosw ; First in new block
  328. stosw ; Last in new block
  329. xor ax, ax
  330. stosw ; End of list
  331. jmps copy_next_block
  332. copy_used_block:
  333. add es:[bx].PM_EntEnd, cx ; Add entries in this block
  334. cmp al, ENT_MOVEABLE
  335. je copy_moveable_block
  336. copy_fixed_block:
  337. stosb ; Segno
  338. movsb ; Flag byte
  339. stosb ; segno again to match structure
  340. movsw ; Offset
  341. loop copy_fixed_block
  342. jmps copy_next_block
  343. copy_moveable_block:
  344. stosb ; ENT_MOVEABLE
  345. movsb ; Flag byte
  346. add si, 2 ; Toss int 3Fh
  347. movsb ; Copy segment #
  348. movsw ; and offset
  349. loop copy_moveable_block
  350. jmps copy_next_block
  351. copy_ent_done:
  352. xor bx,bx
  353. mov es:[bx].ne_usage,1
  354. mov es:[bx].ne_pnextexe,bx
  355. mov es:[bx].ne_pautodata,bx
  356. mov cx,nchars
  357. mov es:[bx].ne_pfileinfo,di
  358. lds si,pfilename
  359. rep movsb
  360. SetKernelDS
  361. mov ax,winVer
  362. mov es:[bx].ne_expver,ax
  363. or es:[bx].ne_flags,NENONRES ; Remember that we have
  364. ; discardable code
  365. UnSetKernelDS
  366. cCall SetOwner,<es,es>
  367. mov ax,es
  368. reexit:
  369. cEnd
  370. cProc LKAllocSegs,<PUBLIC,NEAR>,<si,di,ds>
  371. parmW hExe
  372. localW fixed_seg
  373. localW SegCount
  374. cBegin
  375. mov ds,hExe
  376. mov si,ds:[ne_segtab]
  377. mov di,ds:[si].ns_minalloc
  378. xor ax,ax
  379. mov bx,(GA_ALLOC_LOW or GA_CODE_DATA) shl 8
  380. cCall IGlobalAlloc,<bx,ax,di>
  381. or ax,ax
  382. jz lkallocfail
  383. mov fixed_seg,ax
  384. mov ds:[si].ns_handle,ax
  385. and byte ptr ds:[si].ns_flags,not NSLOADED
  386. or byte ptr ds:[si].ns_flags,NSALLOCED
  387. cCall SetOwner,<ax,ds>
  388. add si,SIZE NEW_SEG1 ; NRES segment
  389. mov di,ds:[si].ns_sector
  390. mov SegCount, 0 ; NRES and MISC segments
  391. ;; SetKernelDS es
  392. ;; cmp fWinX,0
  393. ;; UnSetKernelDS es
  394. ;; je lk1
  395. ;; mov di,ds:[si].ns_cbseg
  396. ;; xchg ds:[si].ns_minalloc,di
  397. ;; xchg ds:[si].ns_sector,di
  398. ;;lk1:
  399. SegLoop:
  400. inc SegCount
  401. xor ax,ax
  402. mov bh,GA_DISCARDABLE + GA_SHAREABLE + GA_CODE_DATA
  403. mov bl,GA_MOVEABLE + GA_DISCCODE
  404. cCall IGlobalAlloc,<bx,ax,ax>
  405. or ax,ax
  406. jz lkallocfail
  407. mov ds:[si].ns_handle,ax ; Handle into seg table
  408. and byte ptr ds:[si].ns_flags,not NSLOADED
  409. or byte ptr ds:[si].ns_flags,NSALLOCED
  410. mov bx,ax ; put handle into base register
  411. smov es,ds
  412. call set_discarded_sel_owner
  413. smov es,0
  414. mov bx,ds:[si].ns_sector ; Save MiscCode sector
  415. add si,SIZE NEW_SEG1 ; Next segment
  416. cmp SegCount, 2
  417. jnz SegLoop
  418. ; Allocate fixed block for kernel's data segment
  419. push bx ; Save MisCode sector
  420. mov bx,ds:[si].ns_minalloc
  421. xor ax,ax
  422. cCall IGlobalAlloc,<ax,ax,bx>
  423. pop bx
  424. or ax,ax
  425. jz lkallocfail
  426. mov ds:[ne_pautodata], si
  427. mov ds:[si].ns_handle,ax
  428. and byte ptr ds:[si].ns_flags,not NSLOADED
  429. or byte ptr ds:[si].ns_flags,NSALLOCED
  430. cCall SetOwner,<ax,ds>
  431. mov ax,di ; Return offset to NR segment
  432. lkallocfail:
  433. cEnd
  434. nop ; Stop linker from padding segment
  435. sEnd INITCODE
  436. end