Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Tim

By: a guest on Dec 17th, 2009  |  syntax: None  |  size: 12.65 KB  |  views: 552  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. Files winaoe-0.97g/bin/aoe.exe and winaoe-0.97g.deadlock_fix.1/bin/aoe.exe differ
  2. Files winaoe-0.97g/bin/aoe32.sys and winaoe-0.97g.deadlock_fix.1/bin/aoe32.sys differ
  3. Files winaoe-0.97g/bin/aoe64.sys and winaoe-0.97g.deadlock_fix.1/bin/aoe64.sys differ
  4. diff -ru winaoe-0.97g/src/aoe.c winaoe-0.97g.deadlock_fix.1/src/aoe.c
  5. --- winaoe-0.97g/src/aoe.c      2008-03-12 00:23:04.000000000 -0500
  6. +++ winaoe-0.97g.deadlock_fix.1/src/aoe.c       2008-12-09 14:29:05.112016000 -0600
  7.  -111,14 +111,20 @@
  8.  } DISKSEARCH, *PDISKSEARCH;
  9.  
  10.  BOOLEAN Stop = FALSE;
  11. -KSPIN_LOCK SpinLock;
  12. +static KSPIN_LOCK SpinLock;
  13. +static KSPIN_LOCK ReplySpinLock;
  14.  KEVENT ThreadSignalEvent;
  15.  PTAG TagList = NULL;
  16.  PTAG TagListLast = NULL;
  17.  PTAG ProbeTag = NULL;
  18. +PTAG ReplyTagListLast = NULL;
  19. +PTAG ReplyTagListHead = NULL;
  20.  PDISKSEARCH DiskSearchList = NULL;
  21.  LONG OutstandingTags = 0;
  22.  HANDLE ThreadHandle;
  23. +UCHAR GlobalSourceMac[6];
  24. +
  25. +
  26.  
  27.  NTSTATUS STDCALL AoEStart() {
  28.    NTSTATUS Status;
  29.  -145,6 +151,7 @@
  30.    ProbeTag->PacketData->Count = 1;
  31.  
  32.    KeInitializeSpinLock(&SpinLock);
  33. +  KeInitializeSpinLock(&ReplySpinLock);
  34.    KeInitializeEvent(&ThreadSignalEvent, SynchronizationEvent, FALSE);
  35.  
  36.    InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
  37.  -240,7 +247,7 @@
  38.      Timeout.QuadPart = -500000LL;               // 500.000 * 100ns = 50.000.000 ns = 50ms
  39.      KeWaitForSingleObject(&DeviceExtension->Disk.SearchEvent, Executive, KernelMode, FALSE, &Timeout);
  40.      if (Stop) {
  41. -      DbgPrint("AoESearchBootDrive cancled\n");
  42. +      DbgPrint("AoESearchBootDrive canceled\n");
  43.        return FALSE;
  44.      }
  45.  
  46.  -513,27 +520,81 @@
  47.    return STATUS_PENDING;
  48.  }
  49.  
  50. -NTSTATUS STDCALL AoEReply(IN PUCHAR SourceMac, IN PUCHAR DestinationMac, IN PUCHAR Data, IN UINT DataSize) {
  51. +
  52. +
  53. +
  54. +// Call from protocolReceive/NDIS to add packets to receive queue
  55. +NTSTATUS STDCALL AoEReplyQueue(IN PUCHAR SourceMac, IN PUCHAR DestinationMac, IN PUCHAR Data, IN UINT DataSize) {
  56.    PAOE Reply = (PAOE)Data;
  57.    LONGLONG LBASize;
  58. -  PTAG Tag;
  59. +  PTAG ReplyTag;
  60.    KIRQL Irql;
  61. -  BOOLEAN Found = FALSE;
  62. -  LARGE_INTEGER CurrentTime;
  63.  
  64.    if (!Reply->ResponseFlag) return STATUS_SUCCESS;
  65.  
  66. +
  67. +  // Special case for AoE probe response
  68.    if (ProbeTag->Id == Reply->Tag) {
  69.      RtlCopyMemory(&LBASize, &Reply->Data[200], sizeof(LONGLONG));
  70.      BusAddTarget(DestinationMac, SourceMac, ntohs(Reply->Major), Reply->Minor, LBASize);
  71.      return STATUS_SUCCESS;
  72.    }
  73.  
  74. +
  75. +  // allocate storage
  76. +    if ((ReplyTag = (PTAG)ExAllocatePool(NonPagedPool, sizeof(TAG))) == NULL) {
  77. +      DbgPrint("AoERequest ExAllocatePool ReplyTag\n");
  78. +      return STATUS_INSUFFICIENT_RESOURCES;
  79. +    }
  80. +    RtlZeroMemory(ReplyTag, sizeof(TAG));
  81. +    // - not using all the TAG fields, just PacketData, PacketSize, Next, and Previous
  82. +    ReplyTag->PacketSize = DataSize;
  83. +    if ((ReplyTag->PacketData = (PAOE)ExAllocatePool(NonPagedPool, ReplyTag->PacketSize)) == NULL) {
  84. +      DbgPrint("AoERequest ExAllocatePool ReplyTag->PacketData\n");
  85. +      ExFreePool(ReplyTag);
  86. +      return STATUS_INSUFFICIENT_RESOURCES;
  87. +    }
  88. +
  89. +    // copy packet data to list item
  90. +    RtlCopyMemory(ReplyTag->PacketData, Reply, ReplyTag->PacketSize);
  91. +
  92. +   // AoEProcessReply needs the SourceMac, so save it
  93. +    RtlCopyMemory(GlobalSourceMac, SourceMac, 6);
  94. +
  95. +  // add to the end of the reply list
  96. +  KeAcquireSpinLock(&ReplySpinLock, &Irql);
  97. +  if (ReplyTagListLast == NULL) {
  98. +    ReplyTagListHead = ReplyTag;
  99. +  } else {
  100. +    ReplyTagListLast->Next = ReplyTag;
  101. +    ReplyTag->Previous = ReplyTagListLast;
  102. +    ReplyTag->Next = NULL;
  103. +  }
  104. +  ReplyTagListLast = ReplyTag;
  105. +  KeReleaseSpinLock(&ReplySpinLock, Irql);
  106. +
  107. +  // tell Thread we have a reply
  108. +  KeSetEvent(&ThreadSignalEvent, 0, FALSE);
  109. +  return STATUS_SUCCESS;
  110. +}
  111. +
  112. +
  113. +// changed this to process receive list; call from Thread before processing sends
  114. +NTSTATUS STDCALL AoEProcessReply(IN PUCHAR Data, IN UINT DataSize) {
  115. +  PAOE Reply = (PAOE) Data;
  116. +  LONGLONG LBASize;
  117. +  PTAG Tag;
  118. +  KIRQL Irql;
  119. +  BOOLEAN Found = FALSE;
  120. +  LARGE_INTEGER CurrentTime;
  121. +
  122. +
  123.    KeAcquireSpinLock(&SpinLock, &Irql);
  124.    if (TagList == NULL) {
  125.      KeReleaseSpinLock(&SpinLock, Irql);
  126.      return STATUS_SUCCESS;
  127.    }
  128. +  // see if we need this packet
  129.    Tag = TagList;
  130.    while (Tag != NULL) {
  131.      if ((Tag->Id == Reply->Tag) && (Tag->PacketData->Major == Reply->Major) && (Tag->PacketData->Minor == Reply->Minor)) {
  132.  -546,24 +607,29 @@
  133.      KeReleaseSpinLock(&SpinLock, Irql);
  134.      return STATUS_SUCCESS;
  135.    } else {
  136. +       // we need this packet, remove from TagList, and decrement count
  137.      if (Tag->Previous == NULL) TagList = Tag->Next;
  138.      else Tag->Previous->Next = Tag->Next;
  139.      if (Tag->Next == NULL) TagListLast = Tag->Previous;
  140.      else Tag->Next->Previous = Tag->Previous;
  141.      OutstandingTags--;
  142.      if (OutstandingTags < 0) DbgPrint("!!OutstandingTags < 0 (AoEReply)!!\n");
  143. -    KeSetEvent(&ThreadSignalEvent, 0, FALSE);
  144.    }
  145.    KeReleaseSpinLock(&SpinLock, Irql);
  146.  
  147. +  // get MAC from a global
  148.    if (RtlCompareMemory(Tag->DeviceExtension->Disk.ServerMac, "\xff\xff\xff\xff\xff\xff", 6) == 6) {
  149. -    RtlCopyMemory(Tag->DeviceExtension->Disk.ServerMac, SourceMac, 6);
  150. -    DbgPrint("Major: %d minor: %d found on server %02x:%02x:%02x:%02x:%02x:%02x\n", Tag->DeviceExtension->Disk.Major, Tag->DeviceExtension->Disk.Minor, SourceMac[0], SourceMac[1], SourceMac[2], SourceMac[3], SourceMac[4], SourceMac[5]);
  151. +    RtlCopyMemory(Tag->DeviceExtension->Disk.ServerMac, GlobalSourceMac, 6);
  152. +    DbgPrint("Major: %d minor: %d found on server %02x:%02x:%02x:%02x:%02x:%02x\n", Tag->DeviceExtension->Disk.Major, Tag->DeviceExtension->Disk.Minor,
  153. +      GlobalSourceMac[0], GlobalSourceMac[1], GlobalSourceMac[2], GlobalSourceMac[3], GlobalSourceMac[4], GlobalSourceMac[5]);
  154.    }
  155.  
  156.    KeQuerySystemTime(&CurrentTime);
  157. +  // timeout -= (timeout - delta time) / 1024
  158.    Tag->DeviceExtension->Disk.Timeout -= (ULONG)((Tag->DeviceExtension->Disk.Timeout - (CurrentTime.QuadPart - Tag->FirstSendTime.QuadPart)) / 1024);
  159.    if (Tag->DeviceExtension->Disk.Timeout > 100000000) Tag->DeviceExtension->Disk.Timeout = 100000000;
  160. +  // min timeout = 7 msec
  161. +  //if (Tag->DeviceExtension->Disk.Timeout < 70000) Tag->DeviceExtension->Disk.Timeout = 70000;
  162.  
  163.    switch (Tag->Type) {
  164.      case SearchDriveType:
  165.  -615,7 +681,6 @@
  166.        break;
  167.    }
  168.  
  169. -  KeSetEvent(&ThreadSignalEvent, 0, FALSE);
  170.    ExFreePool(Tag->PacketData);
  171.    ExFreePool(Tag);
  172.    return STATUS_SUCCESS;
  173.  -629,14 +694,15 @@
  174.    LARGE_INTEGER Timeout, CurrentTime, ProbeTime, ReportTime;
  175.    ULONG NextTagId = 1;
  176.    PTAG Tag;
  177. -  KIRQL Irql;
  178. +  PTAG Next=NULL;
  179. +  KIRQL Irql, Irq2;
  180.    ULONG Sends = 0;
  181.    ULONG Resends = 0;
  182.    ULONG ResendFails = 0;
  183.    ULONG Fails = 0;
  184.    ULONG RequestTimeout = 0;
  185.  
  186. -  DbgPrint("Thread\n");
  187. +  DbgPrint("Thread - entry\n");
  188.    ReportTime.QuadPart = 0LL;
  189.    ProbeTime.QuadPart = 0LL;
  190.  
  191.  -652,7 +718,7 @@
  192.  
  193.      KeQuerySystemTime(&CurrentTime);
  194.      if (CurrentTime.QuadPart > (ReportTime.QuadPart + 10000000LL)) {
  195. -//      DbgPrint("Sends: %d  Resends: %d  ResendFails: %d  Fails: %d  OutstandingTags: %d  RequestTimeout: %d\n", Sends, Resends, ResendFails, Fails, OutstandingTags, RequestTimeout);
  196. +      DbgPrint("Sends: %d  Resends: %d  ResendFails: %d  Fails: %d  OutstandingTags: %d  RequestTimeout: %d\n", Sends, Resends, ResendFails, Fails, OutstandingTags, RequestTimeout);
  197.        Sends = 0;
  198.        Resends = 0;
  199.        ResendFails = 0;
  200.  -660,6 +726,7 @@
  201.        KeQuerySystemTime(&ReportTime);
  202.      }
  203.  
  204. +    // send the probe every 100 seconds
  205.      if (CurrentTime.QuadPart > (ProbeTag->SendTime.QuadPart + 100000000LL)) {
  206.        ProbeTag->Id = NextTagId++;
  207.        if (NextTagId == 0) NextTagId++;
  208.  -668,6 +735,21 @@
  209.        KeQuerySystemTime(&ProbeTag->SendTime);
  210.      }
  211.  
  212. +
  213. +    // process the reply list, deleting each item after processing
  214. +    KeAcquireSpinLock(&ReplySpinLock, &Irq2);
  215. +    for (Tag = ReplyTagListHead; Tag != NULL; Tag=Next) {
  216. +          AoEProcessReply ((PUCHAR) Tag->PacketData, Tag->PacketSize);
  217. +          Next= Tag->Next;
  218. +          ExFreePool (Tag->PacketData);
  219. +       ExFreePool(Tag);
  220. +       }
  221. +       ReplyTagListHead = NULL;
  222. +       ReplyTagListLast = NULL;
  223. +    KeReleaseSpinLock(&ReplySpinLock, Irq2);
  224. +
  225. +
  226. +    // process the Tag list
  227.      KeAcquireSpinLock(&SpinLock, &Irql);
  228.      if (TagList == NULL) {
  229.        KeReleaseSpinLock(&SpinLock, Irql);
  230.  -676,6 +758,7 @@
  231.      Tag = TagList;
  232.      while (Tag != NULL) {
  233.        RequestTimeout = Tag->DeviceExtension->Disk.Timeout;
  234. +      // if this is a new packet to send
  235.        if (Tag->Id == 0) {
  236.          if (OutstandingTags <= 64) {
  237.          //if (OutstandingTags <= 102400) {
  238.  -687,20 +770,25 @@
  239.              KeQuerySystemTime(&Tag->FirstSendTime);
  240.              KeQuerySystemTime(&Tag->SendTime);
  241.              OutstandingTags++;
  242. -           Sends++;
  243. +               Sends++;
  244.            } else {
  245.              Fails++;
  246.              Tag->Id = 0;
  247.              break;
  248.            }
  249.          }
  250. +      // else this is a previously sent packet; see if we need to re-send it
  251.        } else {
  252.          KeQuerySystemTime(&CurrentTime);
  253. +        // if we've waited longer than the 2*timeout, resend packet, and raise the timeout value a little
  254.          if (CurrentTime.QuadPart > (Tag->SendTime.QuadPart + (LONGLONG)(Tag->DeviceExtension->Disk.Timeout * 2))) {
  255.            if (ProtocolSend(Tag->DeviceExtension->Disk.ClientMac, Tag->DeviceExtension->Disk.ServerMac, (PUCHAR)Tag->PacketData, Tag->PacketSize, Tag)) {
  256.              KeQuerySystemTime(&Tag->SendTime);
  257. +            // timeout += timeout/1000
  258.              Tag->DeviceExtension->Disk.Timeout += Tag->DeviceExtension->Disk.Timeout / 1000;
  259.              if (Tag->DeviceExtension->Disk.Timeout > 100000000) Tag->DeviceExtension->Disk.Timeout = 100000000;
  260. +            // min timeout = 7 msec
  261. +            //if (Tag->DeviceExtension->Disk.Timeout < 70000) Tag->DeviceExtension->Disk.Timeout = 70000;
  262.              Resends++;
  263.            } else {
  264.              ResendFails++;
  265. diff -ru winaoe-0.97g/src/aoe.h winaoe-0.97g.deadlock_fix.1/src/aoe.h
  266. --- winaoe-0.97g/src/aoe.h      2008-02-19 08:46:08.000000000 -0600
  267. +++ winaoe-0.97g.deadlock_fix.1/src/aoe.h       2008-12-04 17:50:30.376059800 -0600
  268.  -23,6 +23,7 @@
  269.  #include "portable.h"
  270.  #include "driver.h"
  271.  
  272. +
  273.  #define htons(x) (USHORT)((((x) << 8) & 0xff00) | (((x) >> 8) & 0xff))
  274.  #define ntohs(x) (USHORT)((((x) << 8) & 0xff00) | (((x) >> 8) & 0xff))
  275.  
  276.  -30,7 +31,8 @@
  277.  
  278.  BOOLEAN STDCALL AoESearchDrive(IN PDEVICEEXTENSION DeviceExtension);
  279.  NTSTATUS STDCALL AoERequest(IN PDEVICEEXTENSION DeviceExtension, IN REQUESTMODE Mode, IN LONGLONG StartSector, IN ULONG SectorCount, IN PUCHAR Buffer, IN PIRP Irp);
  280. -NTSTATUS STDCALL AoEReply(IN PUCHAR SourceMac, IN PUCHAR DestinationMac, IN PUCHAR Data, IN UINT DataSize);
  281. +NTSTATUS STDCALL AoEReplyQueue(IN PUCHAR SourceMac, IN PUCHAR DestinationMac, IN PUCHAR Data, IN UINT DataSize);
  282. +NTSTATUS STDCALL AoEProcessReply(IN PUCHAR Data, IN UINT DataSize);
  283.  VOID STDCALL AoEResetProbe();
  284.  
  285.  #endif
  286. diff -ru winaoe-0.97g/src/debug.c winaoe-0.97g.deadlock_fix.1/src/debug.c
  287. --- winaoe-0.97g/src/debug.c    2008-02-19 08:46:08.000000000 -0600
  288. +++ winaoe-0.97g.deadlock_fix.1/src/debug.c     2008-12-03 12:51:37.992681100 -0600
  289.  -38,7 +38,7 @@
  290.  } IRPLIST, *PIRPLIST;
  291.  
  292.  PIRPLIST IrpList = NULL;
  293. -KSPIN_LOCK SpinLock;
  294. +static KSPIN_LOCK SpinLock;
  295.  ULONG Number = 0;
  296.  
  297.  extern int sprintf(char*, const char *, ...);
  298. diff -ru winaoe-0.97g/src/protocol.c winaoe-0.97g.deadlock_fix.1/src/protocol.c
  299. --- winaoe-0.97g/src/protocol.c 2008-02-19 08:46:08.000000000 -0600
  300. +++ winaoe-0.97g.deadlock_fix.1/src/protocol.c  2008-12-04 17:55:02.874315800 -0600
  301.  -71,7 +71,7 @@
  302.  } BINDINGCONTEXT, *PBINDINGCONTEXT;
  303.  
  304.  KEVENT ProtocolStopEvent;
  305. -KSPIN_LOCK SpinLock;
  306. +static KSPIN_LOCK SpinLock;
  307.  PBINDINGCONTEXT BindingContextList = NULL;
  308.  NDIS_HANDLE ProtocolHandle = NULL;
  309.  
  310.  -259,7 +259,7 @@
  311.    } else {
  312.      DbgPrint("ProtocolTransferDataComplete Header (back) Buffer == NULL\n");
  313.    }
  314. -  if (Header != NULL && Data != NULL) AoEReply(Header->SourceMac, Header->DestinationMac, Data, DataSize);
  315. +  if (Header != NULL && Data != NULL) AoEReplyQueue(Header->SourceMac, Header->DestinationMac, Data, DataSize);
  316.    if (Header != NULL) ExFreePool(Header);
  317.    if (Data != NULL) ExFreePool(Data);
  318.    NdisFreePacket(Packet);
  319.  -303,7 +303,7 @@
  320.    if (ntohs(Header->Protocol) != AOEPROTOCOLID) return NDIS_STATUS_NOT_ACCEPTED;
  321.  
  322.    if (LookaheadBufferSize == PacketSize) {
  323. -    AoEReply(Header->SourceMac, Header->DestinationMac, LookAheadBuffer, PacketSize);
  324. +    AoEReplyQueue(Header->SourceMac, Header->DestinationMac, LookAheadBuffer, PacketSize);
  325.      return NDIS_STATUS_SUCCESS;
  326.    }