⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 write.cod

📁 怎样在win2000下构造驱动程序znsoft_Serial2000_demo.ZIP
💻 COD
📖 第 1 页 / 共 5 页
字号:
; Listing generated by Microsoft (R) Optimizing Compiler Version 12.00.9044.0 

	TITLE	F:\W2DDK\src\kernel\serial\write.c
	.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
_DATA	SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA	ENDS
CONST	SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST	ENDS
_BSS	SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS	ENDS
$$SYMBOLS	SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS	ENDS
$$TYPES	SEGMENT BYTE USE32 'DEBTYP'
$$TYPES	ENDS
_TLS	SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS	ENDS
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _RtlConvertLongToLargeInteger@4
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _SerialWrite@8
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialStartWrite@4
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialGetNextWrite@20
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialCompleteWrite@16
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _SerialProcessEmptyTransmit@4
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialGiveWriteToIsr@4
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialCancelCurrentWrite@8
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialWriteTimeout@16
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _SerialGrabWriteFromIsr@4
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialGrabXoffFromIsr@4
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialCompleteXoff@16
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _SerialTimeoutXoff@16
_TEXT	SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT	ENDS
;	COMDAT _SerialCancelCurrentXoff@8
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
;	COMDAT _SerialGiveXoffToIsr@4
PAGESER	SEGMENT PARA USE32 PUBLIC ''
PAGESER	ENDS
FLAT	GROUP _DATA, CONST, _BSS
	ASSUME	CS: FLAT, DS: FLAT, SS: FLAT
endif

INCLUDELIB LIBC
INCLUDELIB OLDNAMES

PUBLIC	_SerialWrite@8
PUBLIC	_SerialStartWrite@4
EXTRN	_SerialIRPPrologue@8:NEAR
EXTRN	_SerialIRPEpilogue@4:NEAR
EXTRN	__imp_@IofCompleteRequest@8:NEAR
EXTRN	_SerialStartOrQueue@20:NEAR
EXTRN	_SerialCompleteIfError@8:NEAR
; Function compile flags: /Ogsy
; File f:\w2ddk\src\kernel\serial\write.c
;	COMDAT _SerialWrite@8
PAGESER	SEGMENT
_DeviceObject$ = 8
_Irp$ = 12
_SerialWrite@8 PROC NEAR				; COMDAT

; 100  : {

  00000	53		 push	 ebx

; 101  : 
; 102  :     PSERIAL_DEVICE_EXTENSION Extension = DeviceObject->DeviceExtension;

  00001	8b 5c 24 08	 mov	 ebx, DWORD PTR _DeviceObject$[esp]
  00005	56		 push	 esi

; 103  :     NTSTATUS status;
; 104  : 
; 105  :     SERIAL_LOCKED_PAGED_CODE();
; 106  : 
; 107  :     SerialDump(SERTRACECALLS, ("Entering SerialWrite\n"));
; 108  : 
; 109  :     if ((status = SerialIRPPrologue(Irp, Extension)) != STATUS_SUCCESS) {

  00006	8b 74 24 10	 mov	 esi, DWORD PTR _Irp$[esp+4]
  0000a	57		 push	 edi
  0000b	8b 7b 28	 mov	 edi, DWORD PTR [ebx+40]
  0000e	57		 push	 edi
  0000f	56		 push	 esi
  00010	e8 00 00 00 00	 call	 _SerialIRPPrologue@8
  00015	85 c0		 test	 eax, eax
  00017	74 04		 je	 SHORT $L14802
  00019	8b d8		 mov	 ebx, eax
  0001b	eb 3e		 jmp	 SHORT $L15164
$L14802:

; 110  :       SerialCompleteRequest(Extension, Irp, IO_NO_INCREMENT);
; 111  :       SerialDump(SERTRACECALLS, ("Leaving SerialWrite (1)\n"));
; 112  :       return status;
; 113  :    }
; 114  : 
; 115  :     SerialDump(
; 116  :         SERIRPPATH,
; 117  :         ("SERIAL: Dispatch entry for: %x\n",Irp)
; 118  :         );
; 119  :     if (SerialCompleteIfError(
; 120  :             DeviceObject,
; 121  :             Irp
; 122  :             ) != STATUS_SUCCESS) {

  0001d	56		 push	 esi
  0001e	53		 push	 ebx
  0001f	e8 00 00 00 00	 call	 _SerialCompleteIfError@8
  00024	85 c0		 test	 eax, eax
  00026	74 07		 je	 SHORT $L14806

; 123  : 
; 124  :        SerialDump(SERTRACECALLS, ("Leaving SerialWrite (2)\n"));
; 125  : 
; 126  :         return STATUS_CANCELLED;

  00028	b8 20 01 00 c0	 mov	 eax, -1073741536	; c0000120H
  0002d	eb 3e		 jmp	 SHORT $L14815
$L14806:

; 127  : 
; 128  :     }
; 129  : 
; 130  :     Irp->IoStatus.Information = 0L;
; 131  : 
; 132  :     //
; 133  :     // Quick check for a zero length write.  If it is zero length
; 134  :     // then we are already done!
; 135  :     //
; 136  : 
; 137  :     if (IoGetCurrentIrpStackLocation(Irp)->Parameters.Write.Length) {

  0002f	8b 46 60	 mov	 eax, DWORD PTR [esi+96]
  00032	33 db		 xor	 ebx, ebx
  00034	89 5e 1c	 mov	 DWORD PTR [esi+28], ebx
  00037	39 58 04	 cmp	 DWORD PTR [eax+4], ebx
  0003a	74 1c		 je	 SHORT $L14811

; 138  : 
; 139  :         //
; 140  :         // Well it looks like we actually have to do some
; 141  :         // work.  Put the write on the queue so that we can
; 142  :         // process it when our previous writes are done.
; 143  :         //
; 144  : 
; 145  : 
; 146  :        SerialDump(SERTRACECALLS, ("Leaving SerialWrite (3)\n"));
; 147  : 
; 148  :         return SerialStartOrQueue(
; 149  :                    Extension,
; 150  :                    Irp,
; 151  :                    &Extension->WriteQueue,
; 152  :                    &Extension->CurrentWriteIrp,
; 153  :                    SerialStartWrite
; 154  :                    );

  0003c	8d 87 c8 00 00
	00		 lea	 eax, DWORD PTR [edi+200]
  00042	68 00 00 00 00	 push	 OFFSET FLAT:_SerialStartWrite@4
  00047	50		 push	 eax
  00048	8d 87 ac 00 00
	00		 lea	 eax, DWORD PTR [edi+172]
  0004e	50		 push	 eax
  0004f	56		 push	 esi
  00050	57		 push	 edi
  00051	e8 00 00 00 00	 call	 _SerialStartOrQueue@20
  00056	eb 15		 jmp	 SHORT $L14815
$L14811:

; 155  : 
; 156  :     } else {
; 157  : 
; 158  :         Irp->IoStatus.Status = STATUS_SUCCESS;

  00058	89 5e 18	 mov	 DWORD PTR [esi+24], ebx
$L15164:

; 159  :         SerialDump(
; 160  :             SERIRPPATH,
; 161  :             ("SERIAL: Complete Irp: %x\n",Irp)
; 162  :             );
; 163  :         SerialCompleteRequest(Extension, Irp, 0);

  0005b	32 d2		 xor	 dl, dl
  0005d	8b ce		 mov	 ecx, esi
  0005f	ff 15 00 00 00
	00		 call	 DWORD PTR __imp_@IofCompleteRequest@8
  00065	57		 push	 edi
  00066	e8 00 00 00 00	 call	 _SerialIRPEpilogue@4

; 164  : 
; 165  :         SerialDump(SERTRACECALLS, ("Leaving SerialWrite (4)\n"));
; 166  :         return STATUS_SUCCESS;

  0006b	8b c3		 mov	 eax, ebx
$L14815:
  0006d	5f		 pop	 edi
  0006e	5e		 pop	 esi
  0006f	5b		 pop	 ebx

; 167  : 
; 168  :     }
; 169  : 
; 170  : }

  00070	c2 08 00	 ret	 8
_SerialWrite@8 ENDP
PAGESER	ENDS
PUBLIC	_SerialGiveWriteToIsr@4
PUBLIC	_SerialCancelCurrentWrite@8
PUBLIC	_SerialGrabXoffFromIsr@4
PUBLIC	_SerialGetNextWrite@20
EXTRN	__imp__KeSynchronizeExecution@12:NEAR
EXTRN	__imp_@InterlockedExchange@8:NEAR
EXTRN	__imp_@KfAcquireSpinLock@4:NEAR
EXTRN	__imp_@KfReleaseSpinLock@8:NEAR
EXTRN	__imp__IoAcquireCancelSpinLock@4:NEAR
EXTRN	_SerialSetTimer@20:NEAR
EXTRN	__imp__IoReleaseCancelSpinLock@4:NEAR
EXTRN	_SerialTryToCompleteCurrent@44:NEAR
EXTRN	__allmul:NEAR
; Function compile flags: /Ogsy
;	COMDAT _SerialStartWrite@4
PAGESER	SEGMENT
_Extension$ = 8
_NewIrp$ = -16
_OldIrql$ = -5
_TotalTime$ = -24
_UseATimer$ = 11
_Timeouts$ = -44
_SetFirstStatus$ = -1
_FirstStatus$ = -12
_SerialStartWrite@4 PROC NEAR				; COMDAT

; 196  : {

  00000	55		 push	 ebp
  00001	8b ec		 mov	 ebp, esp
  00003	83 ec 2c	 sub	 esp, 44			; 0000002cH

; 197  : 
; 198  :     PIRP NewIrp;
; 199  :     KIRQL OldIrql;
; 200  :     LARGE_INTEGER TotalTime;
; 201  :     BOOLEAN UseATimer;
; 202  :     SERIAL_TIMEOUTS Timeouts;
; 203  :     BOOLEAN SetFirstStatus = FALSE;

  00006	80 65 ff 00	 and	 BYTE PTR _SetFirstStatus$[ebp], 0
  0000a	53		 push	 ebx
  0000b	8b 5d 08	 mov	 ebx, DWORD PTR _Extension$[ebp]
  0000e	56		 push	 esi
  0000f	57		 push	 edi
$L14837:

; 204  :     NTSTATUS FirstStatus;
; 205  : 
; 206  :     SERIAL_LOCKED_PAGED_CODE();
; 207  : 
; 208  :     SerialDump(SERTRACECALLS, ("SERIAL: SerialStartWrite\n"));
; 209  : 
; 210  :     do {
; 211  : 
; 212  :         //
; 213  :         // If there is an xoff counter then complete it.
; 214  :         //
; 215  : 
; 216  :         IoAcquireCancelSpinLock(&OldIrql);

  00010	8d 45 fb	 lea	 eax, DWORD PTR _OldIrql$[ebp]
  00013	50		 push	 eax
  00014	ff 15 00 00 00
	00		 call	 DWORD PTR __imp__IoAcquireCancelSpinLock@4

; 217  : 
; 218  :         //
; 219  :         // We see if there is a actually an Xoff counter irp.
; 220  :         //
; 221  :         // If there is, we put the write irp back on the head
; 222  :         // of the write list.  We then kill the xoff counter.
; 223  :         // The xoff counter killing code will actually make the
; 224  :         // xoff counter back into the current write irp, and
; 225  :         // in the course of completing the xoff (which is now
; 226  :         // the current write) we will restart this irp.
; 227  :         //
; 228  : 
; 229  :         if (Extension->CurrentXoffIrp) {

  0001a	8d 8b dc 00 00
	00		 lea	 ecx, DWORD PTR [ebx+220]
  00020	33 d2		 xor	 edx, edx
  00022	8b 01		 mov	 eax, DWORD PTR [ecx]
  00024	3b c2		 cmp	 eax, edx
  00026	74 34		 je	 SHORT $L14840

; 230  : 
; 231  :             if (SERIAL_REFERENCE_COUNT(Extension->CurrentXoffIrp)) {

  00028	8b 40 60	 mov	 eax, DWORD PTR [eax+96]
  0002b	39 50 10	 cmp	 DWORD PTR [eax+16], edx
  0002e	74 2c		 je	 SHORT $L14840

; 232  : 
; 233  :                 //
; 234  :                 // The reference count is non-zero.  This implies that
; 235  :                 // the xoff irp has not made it through the completion
; 236  :                 // path yet.  We will increment the reference count
; 237  :                 // and attempt to complete it ourseleves.
; 238  :                 //
; 239  : 
; 240  :                 SERIAL_SET_REFERENCE(
; 241  :                     Extension->CurrentXoffIrp,
; 242  :                     SERIAL_REF_XOFF_REF
; 243  :                     );

  00030	83 48 10 10	 or	 DWORD PTR [eax+16], 16	; 00000010H

; 244  : 
; 245  :                 Extension->CurrentXoffIrp->IoStatus.Information = 0;

  00034	8b 01		 mov	 eax, DWORD PTR [ecx]

; 246  : 
; 247  :                 //
; 248  :                 // The following call will actually release the
; 249  :                 // cancel spin lock.
; 250  :                 //
; 251  : 
; 252  :                 SerialTryToCompleteCurrent(
; 253  :                     Extension,
; 254  :                     SerialGrabXoffFromIsr,
; 255  :                     OldIrql,
; 256  :                     STATUS_SERIAL_MORE_WRITES,
; 257  :                     &Extension->CurrentXoffIrp,
; 258  :                     NULL,
; 259  :                     NULL,
; 260  :                     &Extension->XoffCountTimer,
; 261  :                     NULL,
; 262  :                     NULL,
; 263  :                     SERIAL_REF_XOFF_REF
; 264  :                     );

  00036	6a 10		 push	 16			; 00000010H
  00038	52		 push	 edx
  00039	89 50 1c	 mov	 DWORD PTR [eax+28], edx
  0003c	8d 83 50 04 00
	00		 lea	 eax, DWORD PTR [ebx+1104]
  00042	52		 push	 edx
  00043	50		 push	 eax
  00044	52		 push	 edx
  00045	52		 push	 edx
  00046	51		 push	 ecx
  00047	68 08 00 00 40	 push	 1073741832		; 40000008H
  0004c	ff 75 fb	 push	 DWORD PTR _OldIrql$[ebp]
  0004f	68 00 00 00 00	 push	 OFFSET FLAT:_SerialGrabXoffFromIsr@4
  00054	53		 push	 ebx
  00055	e8 00 00 00 00	 call	 _SerialTryToCompleteCurrent@44

; 265  : 
; 266  :             } else {

  0005a	eb 09		 jmp	 SHORT $L14855
$L14840:

; 267  : 
; 268  :                 //
; 269  :                 // The irp is well on its way to being finished.
; 270  :                 // We can let the regular completion code do the
; 271  :                 // work.  Just release the spin lock.
; 272  :                 //
; 273  : 
; 274  :                 IoReleaseCancelSpinLock(OldIrql);
; 275  : 
; 276  :             }
; 277  : 
; 278  :         } else {
; 279  : 
; 280  :             IoReleaseCancelSpinLock(OldIrql);

  0005c	ff 75 fb	 push	 DWORD PTR _OldIrql$[ebp]
  0005f	ff 15 00 00 00
	00		 call	 DWORD PTR __imp__IoReleaseCancelSpinLock@4
$L14855:

; 281  : 
; 282  :         }
; 283  : 
; 284  :         UseATimer = FALSE;

  00065	80 65 0b 00	 and	 BYTE PTR _UseATimer$[ebp], 0

; 285  : 
; 286  :         //
; 287  :         // Calculate the timeout value needed for the
; 288  :         // request.  Note that the values stored in the
; 289  :         // timeout record are in milliseconds.  Note that
; 290  :         // if the timeout values are zero then we won't start
; 291  :         // the timer.
; 292  :         //
; 293  : 
; 294  :         KeAcquireSpinLock(
; 295  :             &Extension->ControlLock,
; 296  :             &OldIrql
; 297  :             );

  00069	8d 8b e4 01 00

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -