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.

452 lines
9.7 KiB

  1. title ATOM - atom package
  2. include kernel.inc
  3. include gpfix.inc
  4. MAXINTATOM = 0C000h
  5. PRIME = 37
  6. ACTION_FIND = 0
  7. ACTION_ADD = 1
  8. ACTION_DEL = 2
  9. ATOMTABLE STRUC
  10. at_prime DW ? ; Hash modulus
  11. at_hashTable DW ? ; variable length array
  12. ATOMTABLE ENDS
  13. ATOM STRUC
  14. a_chain DW ?
  15. a_usage DW ?
  16. a_len DB ?
  17. a_name DB ?
  18. ATOM ENDS
  19. externW <pAtomTable>
  20. externFP <LocalAlloc,LocalFree,GlobalHandle>
  21. externNP <MyUpper>
  22. ifdef FE_SB
  23. externNP MyIsDBCSLeadByte
  24. endif
  25. sBegin MISCCODE
  26. assumes cs, misccode
  27. assumes ds, nothing
  28. assumes es, nothing
  29. ;
  30. ; This procedure should be called once by each new client program. It
  31. ; will initialize the atom table for the caller's DS and store a pointer
  32. ; to the atom table in a reserve location in the caller's DS.
  33. ; We expect return value to be in CX as well as AX. (jcxz!)
  34. ;
  35. cProc InitAtomTable,<PUBLIC,FAR>
  36. parmW tblSize
  37. cBegin
  38. mov ax,ds:[pAtomTable] ; Don't create if already exists
  39. or ax,ax
  40. jnz initdone
  41. mov bx,tblSize
  42. or bx,bx
  43. jnz gotsize
  44. mov bl,PRIME
  45. gotsize:
  46. push bx
  47. inc bx ; space for table size
  48. shl bx,1
  49. mov ax,LA_ZEROINIT
  50. cCall LocalAlloc,<ax,bx>
  51. pop dx
  52. jcxz initDone ; Failure
  53. mov ds:[pAtomTable],ax
  54. mov bx,ax
  55. mov ds:[bx].at_prime,dx ; First word in hash is hash modulus
  56. initDone:
  57. mov cx,ax
  58. cEnd
  59. sEnd MISCCODE
  60. sBegin CODE
  61. assumes CS,CODE
  62. assumes DS,NOTHING
  63. assumes ES,NOTHING
  64. labelFP <PUBLIC,DelAtom>
  65. mov cl,ACTION_DEL
  66. db 0BBh ; mov bx,
  67. labelVDO AddAtom
  68. mov cl,ACTION_ADD
  69. db 0BBh ; mov bx,
  70. labelVDO FindAtom
  71. mov cl,ACTION_FIND
  72. errn$ LookupAtom
  73. ;
  74. ; Common procedure to add, find or delete an atom table entry. Called
  75. ; with a far pointer to the name string and an action code in CL register
  76. ; Works in an SS != DS environment.
  77. ;
  78. cProc LookupAtom,<PUBLIC,FAR>,<ds,si,di>
  79. parmD pName
  80. localW hName
  81. localB action
  82. cBegin
  83. beg_fault_trap la_trap
  84. mov [action],cl
  85. mov cx,SEG_pName ; If segment value is zero
  86. ifdef FE_SB
  87. or cx,cx
  88. jne @F
  89. jmp haveIntAtom
  90. @@:
  91. else
  92. jcxz haveIntAtom ; ...then integer atom
  93. endif
  94. mov hName,cx
  95. les si,pName ; ES:SI = pName
  96. cmp byte ptr es:[si],'#' ; Check for integer atom
  97. je parseIntAtom
  98. xor ax,ax
  99. cmp ds:[pAtomTable],ax ; Make sure we have an atom table
  100. jne tblokay
  101. cCall InitAtomTable,<ax>
  102. jcxz fail1
  103. notIntAtom:
  104. les si,pName ; ES:SI = pName
  105. tblokay:
  106. xor ax,ax ; c = 0
  107. xor cx,cx ; size = 0
  108. xor dx,dx ; hash = 0
  109. cld
  110. loop1: ; while {
  111. lods byte ptr es:[si] ; c = *pName++
  112. or al,al ; if (!c) break;
  113. jz xloop1
  114. inc cl ; size++
  115. jz fail1 ; if (size > 255) fail
  116. ifdef FE_SB
  117. call MyIsDBCSLeadByte ; Is first of 2byte DBCS char ?
  118. jnc loop1ax ; Yes.
  119. endif
  120. call MyUpper
  121. ifdef FE_SB
  122. jmp short loop1a ; go normal
  123. loop1ax:
  124. mov bx, dx ; caluculate hash value
  125. rol bx, 1
  126. add bx, dx
  127. add bx, ax
  128. ror dx, 1
  129. add dx, bx
  130. lods byte ptr es:[si] ; Get Next char
  131. or al, al ; end of strings ?
  132. jz xloop1 ; yes, break;
  133. inc cl ;
  134. jz fail1 ; (size > 255) error
  135. endif
  136. loop1a:
  137. mov bx,dx ; hash =
  138. rol bx,1 ; + hash << 1
  139. add bx,dx ; + hash
  140. add bx,ax ; + c
  141. ror dx,1 ; + hash >> 1
  142. add dx,bx
  143. jmp loop1 ; } end of while loop
  144. ; Here if pName points to string of the form: #nnnn
  145. parseIntAtom:
  146. inc si ; pName++
  147. xor cx,cx ; sum = 0
  148. xor ax,ax
  149. loop3:
  150. lods byte ptr es:[si] ; c = *pName++
  151. or al,al ; if (!c) break;
  152. jz xloop3
  153. sub al,'0' ; if (!isdigit(c))
  154. cmp al,9
  155. ja notIntAtom ;
  156. imul cx, cx, 10 ; sum = (sum * 10) + (c - '0')
  157. add cx, ax
  158. jmp loop3
  159. haveIntAtom:
  160. mov cx,OFF_pName ; Get integer atom
  161. xloop3:
  162. jcxz fail1
  163. cmp cx,MAXINTATOM
  164. jae fail1
  165. mov ax,cx ; return sum
  166. jmp do_exit
  167. fail1:
  168. xor ax,ax ; Fail, return NULL
  169. jmp do_exit
  170. xloop1:
  171. jcxz fail1 ; if (size == 0) fail
  172. xchg ax,dx ; DX:AX = hash
  173. mov bx,ds:[pAtomTable]
  174. div ds:[bx].at_prime
  175. lea bx,ds:[bx].at_hashTable ; pp = &hashTable[ hash % PRIME ]
  176. shl dx,1
  177. add bx,dx
  178. mov dx,cx ; size
  179. mov ax,ss ; Setup for cmpsb
  180. mov es,ax
  181. loop2: ; while {
  182. mov si,[bx] ; p = *pp
  183. or si,si ; if (!p) break
  184. jz xloop2
  185. cmp [si].a_len,dl ; if (p->len != size)
  186. jne loop2a ; continue
  187. les di,pName ; s2 = pName
  188. lea si,[si].a_name ; s1 = &p->name
  189. mov cx,dx ; size
  190. loop4:
  191. jcxz loop4x
  192. dec cx
  193. lodsb ; c1 = *s1++
  194. ifdef FE_SB
  195. call MyIsDBCSLeadByte ; first byte of 2byte ?
  196. jc loop4a ; No, go normal
  197. mov ah, al ; save char
  198. mov al, es:[di] ; get *s2
  199. inc di ; s2++
  200. cmp ah, al ; compare *s1, *s2
  201. jne loop4x ; not same, do next strings
  202. jcxz loop4x ; not necessary but case of bad strings
  203. dec cx
  204. lodsb ; get next char ( this must be second
  205. mov ah, al ; of 2byte )
  206. mov al, es:[di]
  207. inc di
  208. cmp ah, al
  209. je loop4 ; same, go next char
  210. jmp loop4x ; not same, go next strings
  211. loop4a:
  212. endif
  213. call MyUpper
  214. mov ah,al
  215. mov al,es:[di]
  216. call MyUpper
  217. inc di ; c2 = *s2++
  218. cmp ah,al
  219. je loop4
  220. loop4x:
  221. mov si,[bx] ; p = *pp
  222. je xloop2
  223. loop2a:
  224. lea bx,[si].a_chain ; pp = &p->chain
  225. jmp short loop2 ; } end of while loop
  226. xloop2:
  227. ; Dispatch on command.
  228. xor cx,cx
  229. mov cl,[action]
  230. jcxz do_find
  231. errnz ACTION_FIND
  232. loop do_delete
  233. errnz ACTION_ADD-1
  234. do_add:
  235. or si,si ; NULL?
  236. jz do_insert
  237. inc [si].a_usage ; Already in list. Increment reference count.
  238. jmp short do_find
  239. do_delete:
  240. or si,si ; NULL?
  241. jz short do_exit ; Return NULL for internal errors
  242. dec [si].a_usage
  243. jg do_delete1
  244. xor di,di
  245. xchg [si].a_chain,di ; *pp = p->chain, p->chain = 0;
  246. mov [bx],di
  247. cCall LocalFree,<si> ; LocalFree( p )
  248. do_delete1:
  249. xor si,si ; p = NULL
  250. jmp short do_find
  251. do_insert:
  252. mov di,bx ; save pp
  253. push dx ; save size
  254. add dx,size ATOM ; p = LocalAlloc( sizeof( ATOM )+size )
  255. mov bx,LA_ZEROINIT
  256. cCall LocalAlloc,<bx,dx> ; LocalAlloc( ZEROINIT, size )
  257. pop cx ; restore size
  258. mov si,ax
  259. or si,si
  260. jz do_find
  261. mov [di],si ; *pp = p
  262. inc [si].a_usage ; p->usage = 1
  263. mov [si].a_len,cl ; p->len = size
  264. mov bx,si
  265. push ds ; ES = DS
  266. pop es
  267. lea di,[si].a_name ; strcpy( &p->name, pName )
  268. xor cx,cx
  269. mov cl,[si].a_len ; CX = #bytes to move
  270. inc cx ; include terminating null
  271. lds si,pName
  272. cld
  273. rep movsb
  274. push es
  275. pop ds ; Restore DS
  276. mov si,bx
  277. do_find:
  278. mov ax,si ; return p
  279. shr ax,1
  280. shr ax,1
  281. jz do_exit
  282. or ax,MAXINTATOM
  283. end_fault_trap
  284. do_exit:
  285. cEnd
  286. la_trap:
  287. fault_fix_stack
  288. xor ax,ax ; return NULL/FALSE
  289. jmp do_exit
  290. cProc IDeleteAtom,<PUBLIC,FAR>
  291. parmW atom1
  292. regPtr lpName,ds,bx
  293. cBegin
  294. mov bx,atom1
  295. cmp bx,MAXINTATOM
  296. jb freeExit
  297. shl bx,2
  298. lea bx,[bx].a_name
  299. cCall DelAtom,<lpName>
  300. jmp short freeDone
  301. freeExit:
  302. xor ax,ax
  303. freeDone:
  304. cEnd
  305. cProc IGetAtomHandle,<PUBLIC,FAR>
  306. parmW atom2
  307. cBegin
  308. mov ax,atom2
  309. cmp ax,MAXINTATOM
  310. jae @F
  311. xor ax, ax
  312. @@: shl ax,2
  313. cEnd
  314. cProc IGetAtomName,<PUBLIC,FAR>,<si,di>
  315. parmW atom3
  316. parmD pString
  317. parmW maxChars
  318. cBegin
  319. beg_fault_trap getn_trap
  320. cld
  321. les di,pString
  322. cmp maxChars,0
  323. je getnFail
  324. xor cx,cx
  325. mov byte ptr es:[di],cl
  326. mov bx,atom3
  327. cmp bx,MAXINTATOM
  328. jb getIntAtom
  329. shl bx,2
  330. ; Parameter validation - is this a pointer to a valid local allocation
  331. ; block, and is the block in use?
  332. nfd = la_next - la_fixedsize ; given pointer to data, get
  333. mov si, [bx.nfd] ; pointer to 'next' allocation
  334. mov si, [si] ; p = p->prev
  335. and si, not (LA_BUSY + LA_MOVEABLE)
  336. sub si, bx
  337. cmp si, -la_fixedsize
  338. jnz getnFail
  339. test word ptr [bx-la_fixedsize], LA_BUSY
  340. jz getnFail
  341. ; The usage count must be >0
  342. cmp [bx].a_usage,cx
  343. je getnFail
  344. ; Len must be >0
  345. mov cl,[bx].a_len
  346. jcxz getnFail
  347. cmp maxChars,cx
  348. jg getnOkay
  349. mov cx,maxChars
  350. dec cx
  351. getnOkay:
  352. lea si,[bx].a_name
  353. mov ax,cx
  354. rep movsb
  355. mov byte ptr es:[di],0
  356. jmps getnDone
  357. getn_trap:
  358. fault_fix_stack ; Yes, fault handler can be within range
  359. getnFail:
  360. mov ax, atom3
  361. krDebugOut DEB_WARN, "GetAtomName(#AX,...) Can't find atom"
  362. xor ax, ax
  363. jmps getnDone
  364. getIntAtom:
  365. ; When a buffer of length "n" is passed, we must reserve space for
  366. ; the '#' character and a null terminator;
  367. ; Fixed Bug #6143 --SANKAR-- 11-9-89
  368. mov cx, maxChars
  369. cmp cx, 2 ; one '#' and one '\0' are a must!
  370. jl getnFail ; If it is less we fail;
  371. sub cx, 2 ; Allow two char spaces for '#' and '\0'
  372. mov maxChars, cx
  373. or bx,bx
  374. jz getnFail
  375. mov al,'#'
  376. stosb
  377. mov ax,bx
  378. mov bx,10
  379. mov cx, maxChars
  380. jcxz getIntDone
  381. getIntLoop:
  382. xor dx,dx
  383. div bx
  384. push dx
  385. dec cx
  386. or ax,ax
  387. jz gotIntAtom
  388. jcxz gotIntAtom
  389. jmp getIntLoop
  390. gotIntAtom:
  391. sub maxChars,cx
  392. mov cx,maxChars
  393. getIntChar:
  394. pop ax
  395. add al,'0'
  396. stosb
  397. loop getIntChar
  398. getIntDone:
  399. xor al,al
  400. stosb
  401. mov ax,maxChars
  402. inc ax ; For the '#' Character
  403. end_fault_trap
  404. getnDone:
  405. cEnd
  406. sEnd CODE
  407. end