- Fix 2 more callers who don't pass a valid lpErrno pointer
- Check the return value of WSPSocket
- Return WSAEWOULDBLOCK if there are no connections that can be accepted instead of silently returning 0 which is not INVALID_SOCKET so the caller treats it as a valid socket pointer and passes it to other functions which caused wide-spread mayhem since we never checked whether the socket handle the caller passed was valid until my last commit
svn path=/trunk/; revision=47652
- Validate that we found the corresponding socket information in our socket information list
- Fixes a crash in Firefox 2 when it tries to call accept() with a closed socket
svn path=/trunk/; revision=47650
As a result, none of the Hal*Bus HALDISPATCH routines were implemented, which bus drivers expect to find when they're not on ACPI systems (ReactOS today). eVb's new PCI driver was crashing, for example.
Furthermore, legacy systems suffer, because the ACPI HAL Bus routines (that we currently have) expect perfect ACPI-style-compliant systems, not the legacy crap from the early 90ies. This works fine in VMs and new hardware, but old hardware is left behind.
This patch basically corrects the first part of the problem, by making the bus handling support separate between ACPI and non-ACPI HALs. For now, the code remains 100% the same in functionality between both.
However, I have started adding the first few elements:
[HAL]: Implement HalRegisterBusHandler HALDISPATCH routine.
[HAL]: On legacy HALs, register the CMOS, ISA, SYSTEM handlers.
[HAL]: Add cmosbus.c. Stub all bus-specific bus handler routines in the xxxbus.c files.
No real functionality change occurs with this patch, yet.
svn path=/trunk/; revision=47649
- Use a linked list to store the socket information instead of allocating a massive array (1024 elements!) for each process in DllMain to hold all of the pointers
- Fix a massive memory leak (free the socket information which we leaked for every socket we allocated)
- This improves performance because we don't have to look through an array of stale socket information pointers (which we never actually removed from the socket information array in the old code) and the new code queues the socket information at the head of the list which makes newer sockets faster to access
svn path=/trunk/; revision=47646
- Fix many times where we wait for an operation but don't update our status and return if it failed
- Fix the overlapped pending case in writing which was completely broken (callers would detect an error but GetLastError would return 0 because we didn't store the error in the lpErrno variable)
- Fix many times where we pass a pointer to an event that we close without waiting
- Fix a bug in WSPEnumNetworkEvents when we would set WSAEINVAL in the lpErrno variable but not return SOCKET_ERROR so the error got ignored
svn path=/trunk/; revision=47643
- Hold the miniport lock when we work with the timer queue
- Use the return value of KeSetTimer(Ex) to determine whether we need to queue the timer in our queue, otherwise we just use the entry that is already there
- Add more assertions
svn path=/trunk/; revision=47642
- Only dequeue the timer in the DPC if the Period is 0 (which means that it's NOT a periodic timer so we only get called once)
- Attempt to dequeue the timer before inserting it so we don't end up with multiple copies of the same timer on the timer queue if somebody calls NdisMSet(Periodic)Timer twice
svn path=/trunk/; revision=47636
[NTOS]: Re-arrange some of the init code, now that we have access to ARM3 paged pool early-on. Move more code to ARM3::INIT in its right place.
[NTOS]: Enable using the ARM3 PFN Database, getting rid of the old ReactOS PFN database. Should reduce physical memory usage now that we don't have two copies anymore.
[NTOS]: Fix the ARM3 PFN Datbase initialization code.
[NTOS]: Get rid of MiInitializePageList, use MiGetPfnEntryOffset instead of hard-coded pointer math in freelist.c.
This is the last big low-level Mm/ARM3 patch for a long, long time.
svn path=/trunk/; revision=47627
Add the possibility to break on all first chance exceptions, by passing /FIRSTCHANCE on the command line. Enable it temporary to get some more information from the sysreg crash.
svn path=/trunk/; revision=47614
- Fix a overlooked change needed due to mbstowcs fix. Use the number of WCHARs vice number of bytes to calculate end of xmlbuf.
svn path=/trunk/; revision=47613
When a KCB (key stuff) is allocated, the key name associated with it receives an NCB (name stuff). In case this name is already used, a cache exists, and an existing NCB is grabbed, and its reference count is increased. When the KCB goes away, its NCB loses a reference. When all references are gone, the NCB is destroyed. Simple enough.
It turns out that what was currently happening is that an NCB would get dereferenced to 0, deleted, but still remained attached to a valid KCB (shouldn't happen). When that KCB went away, the NCB's reference count was dropped to... -1, and then -2, -3, -4, etc. Remember this is a FREED NCB. In other words, freed pool, that might now belong to someone else, was getting "-1" operations on it. So any value stored in that freed pool would get decremented by one. In ARM3 paged pool, because the allocator keeps a linked list, what would happen is that the FLINK pointer would be 0xE0F01234 instead of 0xE1A01234. What happened is that "0xE1A0" was treated as the reference count of the freed NCB, and it kept getting dereferenced down to 0xE0F0.
Proving this was easy, by adding an ASSERT(Ncb->RefCount >= 1) to the routine that dereferences NCBs. Obviously, we should not try to dereference an NCB that has a reference count of 0, because that NCB is now gone. Adding this ASSERT immediately caught the error, regardless of which pool implementation was being used, so this was a problem in ReactOS today, right now.
My first thought was that we were taking references to NCBs without incrementing the reference count. The NCB gets referenced in two places: when it gets created, and everytime a cached NCB is re-used for a new KCB (all this in CmpGetNameControlBlock).
After adding some tracing code, I discovered that CmpGetNameControlBlock would sometimes return an NCB that was cached, but without referencing it. I did not understand why, since the code says "if (Found) Ncb->RefCount++".
Further analysis showed that what would happen, on this particular instance, is that NCB "Foo" was being Found, but NCB "Bar" was returned instead. Therefore, causing some serious issues: First, NCB Foo was receiving too many references. Secondly, NCB Bar was not being referenced.
Worse though, it turns out this would happen when "Foo" was the CORRECT NCB, and "Bar" was an INCORRECT NCB. What do we mean by correct and incorrect? Well, because NCBs are hashed, it's possible for two NCB hashes to be VERY SIMILAR, but only ONE OF THOSE NCBs will be the right one -- for example, HKLM\Software\Hello vs HKLM\Software\Hell.
In our case, when a KCB for "Hello" was searching for the "Hello" NCB, the "Hello NCB would get a reference, but the "Hell" NCB would be returned. In other words, whenever a HASH COLLISION happened, the incorrect NCB was returned, probably messing up registry code in the process. Subsequently, when the KCB was dereferneced, it was attached to this incorrect, under-referenced NCB.
Since in ANY hash collision with "Hell", in our example, the "Hell" NCB would come first, subsequent searches for "Hellmaster", "Hellboy", "Hello World" would all still return "Hell". Eventually when all these KCBs would go away, the "Hell" NCB would reach even -18 references.
The simple solution? When the CORRECT NCB is found, STOP SEARCHING! By adding a simple "break" statement. Otherwise, even after the correct NCB is found, further, incorrect, collided NCBs are found, and eventually the last one ("Hell", in our example) got returned, and under-referenced, while "Hellmaster" and "Hellboy" were not returned, but LEAKED REFERENCES.
There you have it folks, MEMORY CORRUPTION (USE-AFTER-FREE), INCORRECT REGISTRY NAME PARSHING, REFERENCE LEAKS and REFERENCE UNDERRUNS, all due to ONE missing "break;".
-r
svn path=/trunk/; revision=47605
[NTOS]: Fix up NTAPI location in function definition.
[NTOS]: Implement even more stringent header checks: ExpCheckPoolHeader and ExpCheckPoolBlocks. Normally we would only want this on a DBG build, but I am enabling them for now until I can fix paged pool. If your machine crashes, reverting this commit is NOT the solution (boots for me).
[NTOS]: Add a AllowPagedPool BOOLEAN that will allow us to selectively enable when the ARM3 pool can be used, playing around with the situation that causes the corruption, and perhaps making it easier to find/fix.
svn path=/trunk/; revision=47600
[NTOS]: Enable them.
This boots on my system -- if it doesn't boot on yours, someone is corrupting your nonpaged pool. Reverting this patch is NOT the solution to your woes.
svn path=/trunk/; revision=47598
- Implement basic support for history in line editing
- Reorganize code to reflect that line input is more coupled to history than it is to character input
svn path=/trunk/; revision=47597
[NTOS]: Define POOL_BLOCK_SIZE definition to set the minimum pool block size. In NT, this is equal to a LIST_ENTRY structure, because the Pool Allocator must be able to store a LIST_ENTRY into a freed pool block. This also determines the alignment of pool allocations. So 8 on x86, 16 on x64.
[NTOS]: Don't depend on LIST_ENTRY, but use POOL_BLOCK_SIZE instead (on IA64, if we ever want to support this, the pool block size is different from a LIST_ENTRY/POOL_HEADER).
[NTOS]: The following ASSERTs must hold: the POOL_HEADER must be as big as the the smallest pool block (POOL_BLOCK_SIZE), which must be at least as big as a LIST_ENTRY structure. 8 == 8 == 8 on x86, 16 == 16 == 16 on x64.
svn path=/trunk/; revision=47592
NtDuplicateToken: Fail, if a primary token is to be created from an impersonation token and and the impersonation level of the impersonation token is below SecurityImpersonation.
svn path=/trunk/; revision=47586