|
|
1.1 ! root 1: ; SPY Assembly language utility functions. ! 2: ! 3: ?WIN=1 ; Use Windows prolog/epilog ! 4: ?PLM=1 ; Use PLM calling convention ! 5: DOS5=1 ! 6: .xlist ! 7: include cmacros.inc ! 8: .list ! 9: ! 10: ! 11: ! 12: EXTRN DOSCHGFILEPTR:FAR ! 13: EXTRN DOSREAD:FAR ! 14: ! 15: ! 16: sBegin CODE ! 17: assumes cs,CODE ! 18: assumes ds,DATA ! 19: .286p ! 20: ! 21: ; FValidPointer ! 22: ; ! 23: ; FValidPointer(VOID FAR *pVoid, SHORT cbStruct) ! 24: ; ! 25: cProc FValidPointer,<NEAR,PUBLIC> ! 26: ParmD pVoid ! 27: ParmW cbStruct ! 28: cBegin ! 29: xor ax,ax ; Assume Bad address ! 30: mov bx,SEG_pVoid ; Get the selector of the address ! 31: lar cx,bx ; make sure we have access ! 32: jnz NoAccess ; no access ! 33: ! 34: lsl cx,bx ; get the segment limit ! 35: mov bx,OFF_pVoid ; check range ! 36: add bx,cbStruct ; Add number of bytes on ! 37: jc NoAccess ; overflowed ! 38: cmp cx,bx ! 39: jc NoAccess ; Would overflow, again bad pointer ! 40: inc ax ; Return No zero for TRUE ! 41: ! 42: NoAccess: ! 43: cEnd ! 44: ! 45: ! 46: ! 47: ; FGuessValidPointer ! 48: ; ! 49: ; FGuessValidPointer(VOID FAR *pVoid, SHORT cbStruct) ! 50: ; Since a pointer may have come from a different process, we can not ! 51: ; actually validate the pointer. The Best we can do is simply look ! 52: ; at the selector, and see if it looks reasonable. For now simply check ! 53: ; that the selector is for ring 3. Ie the low order two bits are set. ! 54: ; ! 55: cProc FGuessValidPointer,<NEAR,PUBLIC> ! 56: ParmD pVoid ! 57: ParmW cbStruct ! 58: cBegin ! 59: xor ax,ax ; Assume Bad address ! 60: mov bx,SEG_pVoid ; Get the selector of the address ! 61: and bx,03h ; only look at two low order bits ! 62: cmp bx,03h ; Are they both set ! 63: jnz NoGVAccess ; not ring 3 assume no access ! 64: inc ax ; Return No zero for TRUE ! 65: ! 66: NoGVAccess: ! 67: cEnd ! 68: ! 69: ! 70: ! 71: cProc DebugFileSeek,<PUBLIC,NEAR,PASCAL> ! 72: parmW fh ! 73: parmD amt ! 74: parmW typ ! 75: cBegin ! 76: push ax ! 77: push ax ! 78: mov bx,sp ! 79: push fh ! 80: mov dx,SEG_amt ! 81: mov ax,OFF_amt ! 82: mov cx,typ ! 83: cmp cx,2 ! 84: jle noshift ! 85: shiftamt: ! 86: shl ax,1 ! 87: rcl dx,1 ! 88: loop shiftamt ! 89: noshift: ! 90: push dx ! 91: push ax ! 92: push cx ! 93: push ss ! 94: push bx ! 95: call DOSCHGFILEPTR ! 96: or ax,ax ! 97: pop ax ! 98: pop dx ! 99: jz seek_done ! 100: xor ax,ax ! 101: xor dx,dx ! 102: seek_done: ! 103: cEnd ! 104: ! 105: ! 106: ! 107: cProc DebugFileRead,<PUBLIC,NEAR,PASCAL> ! 108: parmW fh ! 109: parmD lpBuf ! 110: parmW nBytes ! 111: cBegin ! 112: push ax ! 113: mov ax,sp ! 114: push fh ! 115: push SEG_lpBuf ! 116: push OFF_lpBuf ! 117: push nBytes ! 118: push ss ! 119: push ax ! 120: call DOSREAD ! 121: or ax,ax ! 122: pop ax ! 123: jz read_done ! 124: xor ax,ax ! 125: read_done: ! 126: cEnd ! 127: ! 128: cProc lstrcat,<PUBLIC>,<SI,DI,DS> ! 129: parmD szDest ! 130: parmD szSource ! 131: ! 132: cBegin lstrcat ! 133: ! 134: ; first lets get the length of the source string and setup pointer to ! 135: ; source string ! 136: ! 137: les di,szSource ! 138: mov cx,-1 ; count the bytes negatively ! 139: xor ax,ax ; Look for a null ! 140: ! 141: repne scasb ; find null byte & get source length ! 142: inc cx ; cx=-count of bytes in source string ! 143: ; (including null) ! 144: neg cx ; cx=+count ! 145: mov bx,cx ; save the count ! 146: ! 147: lds si,szSource ; now setup Source pointer ! 148: ! 149: ; now find the end of destination string. ! 150: les di,szDest ! 151: xor ax,ax ! 152: mov cx,0ffffH ! 153: repne scasb ! 154: dec di ; di points to dest null terminator ! 155: ! 156: mov cx,bx ; restore count of bytes to copy ! 157: ! 158: rep movsb ; concatenate the strings ! 159: ! 160: cEnd lstrcat ! 161: ! 162: sEnd CODE ! 163: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.