From 177dae079697ad00b6f8199e4fe713769a1a9617 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Sun, 28 Apr 2013 20:53:57 +0000 Subject: [PATCH 01/67] [win32k] - Initialize SM_CXSCREEN and SM_CYSCREEN metrics in co_IntInitializeDesktopGraphics - Also move some code from IntCreatePrimarySurface to co_IntInitializeDesktopGraphics svn path=/trunk/; revision=58887 --- reactos/win32ss/gdi/ntgdi/device.c | 21 --------------------- reactos/win32ss/user/ntuser/winsta.c | 23 +++++++++++++++++++---- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/reactos/win32ss/gdi/ntgdi/device.c b/reactos/win32ss/gdi/ntgdi/device.c index 3740bea2108..a6d6c73cb1c 100644 --- a/reactos/win32ss/gdi/ntgdi/device.c +++ b/reactos/win32ss/gdi/ntgdi/device.c @@ -30,35 +30,14 @@ IntCreatePrimarySurface(VOID) { SIZEL SurfSize; SURFOBJ *pso; - PDESKTOP rpDesk; /* Create surface */ pso = &PDEVOBJ_pSurface(gppdevPrimary)->SurfObj; SurfSize = pso->sizlBitmap; - /* Attach monitor */ - UserAttachMonitor((HDEV)gppdevPrimary); - DPRINT("IntCreatePrimarySurface, gppdevPrimary=%p, gppdevPrimary->pSurface = %p\n", gppdevPrimary, gppdevPrimary->pSurface); - /* Put the pointer in the center of the screen */ - gpsi->ptCursor.x = pso->sizlBitmap.cx / 2; - gpsi->ptCursor.y = pso->sizlBitmap.cy / 2; - - rpDesk = IntGetActiveDesktop(); - if (!rpDesk) - { /* First time going in from winlogon and starting up application desktop and - haven't switch to winlogon desktop. Also still in WM_CREATE. */ - PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); - rpDesk = pti->rpdesk; - if (!rpDesk) - { - DPRINT1("No DESKTOP Window!!!!!\n"); - } - } - co_IntShowDesktop(rpDesk, SurfSize.cx, SurfSize.cy, TRUE); - // Init Primary Displays Device Capabilities. PDEVOBJ_vGetDeviceCaps(gppdevPrimary, &GdiHandleTable->DevCaps); diff --git a/reactos/win32ss/user/ntuser/winsta.c b/reactos/win32ss/user/ntuser/winsta.c index 290b575ca27..3dbda1e73ab 100644 --- a/reactos/win32ss/user/ntuser/winsta.c +++ b/reactos/win32ss/user/ntuser/winsta.c @@ -235,6 +235,7 @@ co_IntInitializeDesktopGraphics(VOID) { TEXTMETRICW tmw; UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY"); + PDESKTOP pdesk; ScreenDeviceContext = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE); if (NULL == ScreenDeviceContext) @@ -249,15 +250,14 @@ co_IntInitializeDesktopGraphics(VOID) return FALSE; } - /* Setup the cursor */ - co_IntLoadDefaultCursors(); - hSystemBM = NtGdiCreateCompatibleDC(ScreenDeviceContext); NtGdiSelectFont(hSystemBM, NtGdiGetStockObject(SYSTEM_FONT)); GreSetDCOwner(hSystemBM, GDI_OBJ_HMGR_PUBLIC); - // FIXME: Move these to a update routine. + /* Update the SERVERINFO */ + gpsi->aiSysMet[SM_CXSCREEN] = gppdevPrimary->gdiinfo.ulHorzRes; + gpsi->aiSysMet[SM_CYSCREEN] = gppdevPrimary->gdiinfo.ulVertRes; gpsi->Planes = NtGdiGetDeviceCaps(ScreenDeviceContext, PLANES); gpsi->BitsPixel = NtGdiGetDeviceCaps(ScreenDeviceContext, BITSPIXEL); gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel; @@ -272,6 +272,21 @@ co_IntInitializeDesktopGraphics(VOID) gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar); gpsi->tmSysFont = tmw; + /* Put the pointer in the center of the screen */ + gpsi->ptCursor.x = gpsi->aiSysMet[SM_CXSCREEN] / 2; + gpsi->ptCursor.y = gpsi->aiSysMet[SM_CYSCREEN] / 2; + + /* Attach monitor */ + UserAttachMonitor((HDEV)gppdevPrimary); + + /* Setup the cursor */ + co_IntLoadDefaultCursors(); + + /* Show the desktop */ + pdesk = IntGetActiveDesktop(); + ASSERT(pdesk); + co_IntShowDesktop(pdesk, gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN], TRUE); + return TRUE; } From c715a8270e4a157e37b83f463473b5c89763ef3a Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 29 Apr 2013 10:01:39 +0000 Subject: [PATCH 02/67] [NDIS] - Queue the miniport worker only after a previous operation has completed CORE-5734 #resolve #comment Fixed in r58888 svn path=/trunk/; revision=58888 --- .../drivers/network/ndis/include/miniport.h | 5 ++ reactos/drivers/network/ndis/ndis/miniport.c | 55 +++++++++++++------ reactos/drivers/network/ndis/ndis/protocol.c | 8 +++ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/reactos/drivers/network/ndis/include/miniport.h b/reactos/drivers/network/ndis/include/miniport.h index f10abc4628d..8555ed83336 100644 --- a/reactos/drivers/network/ndis/include/miniport.h +++ b/reactos/drivers/network/ndis/include/miniport.h @@ -197,4 +197,9 @@ VOID MiniDoAddressingReset( PLOGICAL_ADAPTER Adapter); +VOID +MiniWorkItemComplete( + PLOGICAL_ADAPTER Adapter, + NDIS_WORK_ITEM_TYPE WorkItemType); + /* EOF */ diff --git a/reactos/drivers/network/ndis/ndis/miniport.c b/reactos/drivers/network/ndis/ndis/miniport.c index 130b9299776..846da655b5f 100644 --- a/reactos/drivers/network/ndis/ndis/miniport.c +++ b/reactos/drivers/network/ndis/ndis/miniport.c @@ -127,7 +127,7 @@ MiniGetFirstWorkItem( while (CurrentEntry) { - if (CurrentEntry->WorkItemType == Type) + if (CurrentEntry->WorkItemType == Type || Type == NdisMaxWorkItems) return CurrentEntry; CurrentEntry = (PNDIS_MINIPORT_WORK_ITEM)CurrentEntry->Link.Next; @@ -146,18 +146,20 @@ MiniIsBusy( KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - if (Type == NdisWorkItemRequest && - (Adapter->NdisMiniportBlock.PendingRequest || MiniGetFirstWorkItem(Adapter, NdisWorkItemRequest))) + if (MiniGetFirstWorkItem(Adapter, Type)) + { + Busy = TRUE; + } + else if (Type == NdisWorkItemRequest && Adapter->NdisMiniportBlock.PendingRequest) { Busy = TRUE; } - else if (Type == NdisWorkItemSend && - (Adapter->NdisMiniportBlock.FirstPendingPacket || MiniGetFirstWorkItem(Adapter, NdisWorkItemSend))) + else if (Type == NdisWorkItemSend && Adapter->NdisMiniportBlock.FirstPendingPacket) { Busy = TRUE; } - else if (Type == NdisWorkItemResetRequested && - (Adapter->NdisMiniportBlock.ResetStatus == NDIS_STATUS_PENDING || MiniGetFirstWorkItem(Adapter, NdisWorkItemResetRequested))) + else if (Type == NdisWorkItemResetRequested && + Adapter->NdisMiniportBlock.ResetStatus == NDIS_STATUS_PENDING) { Busy = TRUE; } @@ -501,8 +503,9 @@ MiniRequestComplete( KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); Adapter->NdisMiniportBlock.PendingRequest = NULL; KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); - KeLowerIrql(OldIrql); + + MiniWorkItemComplete(Adapter, NdisWorkItemRequest); } VOID NTAPI @@ -553,6 +556,8 @@ MiniSendComplete( Status); KeLowerIrql(OldIrql); + + MiniWorkItemComplete(Adapter, NdisWorkItemSend); } @@ -560,9 +565,8 @@ VOID NTAPI MiniSendResourcesAvailable( IN NDIS_HANDLE MiniportAdapterHandle) { -/* - UNIMPLEMENTED -*/ + /* Run the work if anything is waiting */ + MiniWorkItemComplete((PLOGICAL_ADAPTER)MiniportAdapterHandle, NdisWorkItemSend); } @@ -896,6 +900,8 @@ MiniReset( NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0); NdisMIndicateStatusComplete(Adapter); + + MiniWorkItemComplete(Adapter, NdisWorkItemResetRequested); } return Status; @@ -916,6 +922,23 @@ MiniportHangDpc( } } +VOID +MiniWorkItemComplete( + PLOGICAL_ADAPTER Adapter, + NDIS_WORK_ITEM_TYPE WorkItemType) +{ + PIO_WORKITEM IoWorkItem; + + /* Check if there's anything queued to run after this work item */ + if (!MiniIsBusy(Adapter, WorkItemType)) + return; + + /* There is, so fire the worker */ + IoWorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject); + if (IoWorkItem) + IoQueueWorkItem(IoWorkItem, MiniportWorker, DelayedWorkQueue, IoWorkItem); +} + VOID FASTCALL MiniQueueWorkItem( @@ -934,7 +957,6 @@ MiniQueueWorkItem( */ { PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem; - PIO_WORKITEM IoWorkItem; KIRQL OldIrql; NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); @@ -982,10 +1004,6 @@ MiniQueueWorkItem( } } - IoWorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject); - if (IoWorkItem) - IoQueueWorkItem(IoWorkItem, MiniportWorker, DelayedWorkQueue, IoWorkItem); - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); } @@ -1114,6 +1132,11 @@ MiniDoRequest( } KeLowerIrql(OldIrql); + + if (Status != NDIS_STATUS_PENDING) { + MiniWorkItemComplete(Adapter, NdisWorkItemRequest); + } + return Status; } diff --git a/reactos/drivers/network/ndis/ndis/protocol.c b/reactos/drivers/network/ndis/ndis/protocol.c index 15a5a0fef87..6417da6c067 100644 --- a/reactos/drivers/network/ndis/ndis/protocol.c +++ b/reactos/drivers/network/ndis/ndis/protocol.c @@ -424,6 +424,10 @@ proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet) NdisStatus = NDIS_STATUS_PENDING; } } + + if (NdisStatus != NDIS_STATUS_PENDING) { + MiniWorkItemComplete(Adapter, NdisWorkItemSend); + } return NdisStatus; } else { @@ -447,6 +451,10 @@ proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet) NdisStatus = NDIS_STATUS_PENDING; } } + + if (NdisStatus != NDIS_STATUS_PENDING) { + MiniWorkItemComplete(Adapter, NdisWorkItemSend); + } return NdisStatus; } From 9dfddd39d28a374df354a4e94a44fd1dd47a7bfa Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 29 Apr 2013 10:10:44 +0000 Subject: [PATCH 03/67] [FSRTL] - Start bringing sanity to FSRTL Large MCB implementation: * Get rid of the GET_LIST_HEAD macro and define a proper private struct to access its members. That's much more flexible,and that's how it's usually done in hundreds of other places in the kernel. Otherwise we might just forget about structs and invent macros to access individual virtual fields in a byte array :) * Going through the code (first, preliminary pass) and putting helper debug prints, especially when the code does not work as expected. * Move variables definitions to the beginning of the function (thus get rid of up to local vars being redifined up to 3x times within a single function). svn path=/trunk/; revision=58889 --- reactos/ntoskrnl/fsrtl/largemcb.c | 169 +++++++++++++++++------------- 1 file changed, 94 insertions(+), 75 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/largemcb.c b/reactos/ntoskrnl/fsrtl/largemcb.c index ff6825b9c1f..d94120e14d3 100644 --- a/reactos/ntoskrnl/fsrtl/largemcb.c +++ b/reactos/ntoskrnl/fsrtl/largemcb.c @@ -16,8 +16,6 @@ /* GLOBALS *******************************************************************/ -#define GET_LIST_HEAD(x) ((PLIST_ENTRY)(&((PRTL_GENERIC_TABLE)x)[1])) - PAGED_LOOKASIDE_LIST FsRtlFirstMappingLookasideList; NPAGED_LOOKASIDE_LIST FsRtlFastMutexLookasideList; @@ -29,6 +27,21 @@ typedef struct _LARGE_MCB_MAPPING_ENTRY LIST_ENTRY Sequence; } LARGE_MCB_MAPPING_ENTRY, *PLARGE_MCB_MAPPING_ENTRY; +typedef struct _LARGE_MCB_MAPPING +{ + RTL_GENERIC_TABLE Table; + LIST_ENTRY SequenceList; +} LARGE_MCB_MAPPING, *PLARGE_MCB_MAPPING; + +typedef struct _BASE_MCB_INTERNAL { + ULONG MaximumPairCount; + ULONG PairCount; + USHORT PoolType; + USHORT Flags; + PLARGE_MCB_MAPPING Mapping; +} BASE_MCB_INTERNAL, *PBASE_MCB_INTERNAL; + + static PVOID NTAPI McbMappingAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes) { PVOID Result; @@ -63,11 +76,12 @@ static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingCompare */ BOOLEAN NTAPI -FsRtlAddBaseMcbEntry(IN PBASE_MCB Mcb, +FsRtlAddBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; LARGE_MCB_MAPPING_ENTRY Node; PLARGE_MCB_MAPPING_ENTRY Existing = NULL; BOOLEAN NewElement = FALSE; @@ -79,8 +93,7 @@ FsRtlAddBaseMcbEntry(IN PBASE_MCB Mcb, while (!NewElement) { DPRINT("Inserting %x:%x\n", Node.RunStartVbn.LowPart, Node.SectorCount.LowPart); - Existing = RtlInsertElementGenericTable - (Mcb->Mapping, &Node, sizeof(Node), &NewElement); + Existing = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Node, sizeof(Node), &NewElement); DPRINT("Existing %x\n", Existing); if (!Existing) break; @@ -89,8 +102,7 @@ FsRtlAddBaseMcbEntry(IN PBASE_MCB Mcb, { // We merge the existing runs LARGE_INTEGER StartVbn, FinalVbn; - DPRINT("Existing: %x:%x\n", - Existing->RunStartVbn.LowPart, Node.SectorCount.LowPart); + DPRINT("Existing: %x:%x\n", Existing->RunStartVbn.LowPart, Node.SectorCount.LowPart); if (Existing->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart) { StartVbn = Existing->RunStartVbn; @@ -116,7 +128,7 @@ FsRtlAddBaseMcbEntry(IN PBASE_MCB Mcb, Node.RunStartVbn.QuadPart = StartVbn.QuadPart; Node.SectorCount.QuadPart = FinalVbn.QuadPart - StartVbn.QuadPart; RemoveHeadList(&Existing->Sequence); - RtlDeleteElementGenericTable(Mcb->Mapping, Existing); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Existing); Mcb->PairCount--; } else @@ -124,7 +136,7 @@ FsRtlAddBaseMcbEntry(IN PBASE_MCB Mcb, DPRINT("Mapping added %x\n", Existing); Mcb->MaximumPairCount++; Mcb->PairCount++; - InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Existing->Sequence); + InsertHeadList(&Mcb->Mapping->SequenceList, &Existing->Sequence); } } @@ -163,20 +175,21 @@ FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, */ BOOLEAN NTAPI -FsRtlGetNextBaseMcbEntry(IN PBASE_MCB Mcb, +FsRtlGetNextBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN ULONG RunIndex, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; ULONG i = 0; BOOLEAN Result = FALSE; PLARGE_MCB_MAPPING_ENTRY Entry; for (Entry = (PLARGE_MCB_MAPPING_ENTRY) - RtlEnumerateGenericTable(Mcb->Mapping, TRUE); + RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); Entry && i < RunIndex; Entry = (PLARGE_MCB_MAPPING_ENTRY) - RtlEnumerateGenericTable(Mcb->Mapping, FALSE), i++); + RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE), i++); if (Entry) { Result = TRUE; @@ -224,9 +237,10 @@ FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, */ VOID NTAPI -FsRtlInitializeBaseMcb(IN PBASE_MCB Mcb, +FsRtlInitializeBaseMcb(IN PBASE_MCB OpaqueMcb, IN POOL_TYPE PoolType) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; Mcb->PairCount = 0; if (PoolType == PagedPool) @@ -236,19 +250,19 @@ FsRtlInitializeBaseMcb(IN PBASE_MCB Mcb, else { Mcb->Mapping = ExAllocatePoolWithTag(PoolType | POOL_RAISE_IF_ALLOCATION_FAILURE, - sizeof(RTL_GENERIC_TABLE) + sizeof(LIST_ENTRY), + sizeof(LARGE_MCB_MAPPING), 'FSBC'); } Mcb->PoolType = PoolType; Mcb->MaximumPairCount = MAXIMUM_PAIR_COUNT; RtlInitializeGenericTable - (Mcb->Mapping, + (&Mcb->Mapping->Table, (PRTL_GENERIC_COMPARE_ROUTINE)McbMappingCompare, McbMappingAllocate, McbMappingFree, Mcb); - InitializeListHead(GET_LIST_HEAD(Mcb->Mapping)); + InitializeListHead(&Mcb->Mapping->SequenceList); } /* @@ -288,7 +302,7 @@ FsRtlInitializeLargeMcbs(VOID) NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, - sizeof(RTL_GENERIC_TABLE) + sizeof(LIST_ENTRY), + sizeof(LARGE_MCB_MAPPING), IFS_POOL_TAG, 0); /* FIXME: Should be 4 */ @@ -307,7 +321,7 @@ FsRtlInitializeLargeMcbs(VOID) */ BOOLEAN NTAPI -FsRtlLookupBaseMcbEntry(IN PBASE_MCB Mcb, +FsRtlLookupBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn OPTIONAL, OUT PLONGLONG SectorCountFromLbn OPTIONAL, @@ -315,6 +329,7 @@ FsRtlLookupBaseMcbEntry(IN PBASE_MCB Mcb, OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, OUT PULONG Index OPTIONAL) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; BOOLEAN Result = FALSE; LARGE_MCB_MAPPING_ENTRY ToLookup; PLARGE_MCB_MAPPING_ENTRY Entry; @@ -322,13 +337,15 @@ FsRtlLookupBaseMcbEntry(IN PBASE_MCB Mcb, ToLookup.RunStartVbn.QuadPart = Vbn; ToLookup.SectorCount.QuadPart = 1; - Entry = RtlLookupElementGenericTable(Mcb->Mapping, &ToLookup); + Entry = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &ToLookup); + DPRINT("Entry %p\n", Entry); if (!Entry) { // Find out if we have a following entry. The spec says we should return // found with Lbn == -1 when we're beneath the largest map. ToLookup.SectorCount.QuadPart = (1ull<<62) - ToLookup.RunStartVbn.QuadPart; - Entry = RtlLookupElementGenericTable(Mcb->Mapping, &ToLookup); + Entry = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &ToLookup); + DPRINT("Entry %p\n", Entry); if (Entry) { Result = TRUE; @@ -349,7 +366,7 @@ FsRtlLookupBaseMcbEntry(IN PBASE_MCB Mcb, if (StartingLbn) *StartingLbn = Entry->StartingLbn.QuadPart; if (SectorCountFromStartingLbn) *SectorCountFromStartingLbn = Entry->SectorCount.QuadPart; } - + DPRINT("Done\n"); return Result; } @@ -395,13 +412,14 @@ FsRtlLookupLastBaseMcbEntryAndIndex(IN PBASE_MCB OpaqueMcb, IN OUT PLONGLONG LargeLbn, IN OUT PULONG Index) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; ULONG i = 0; BOOLEAN Result = FALSE; PLIST_ENTRY ListEntry; PLARGE_MCB_MAPPING_ENTRY Entry; PLARGE_MCB_MAPPING_ENTRY CountEntry; - ListEntry = GET_LIST_HEAD(OpaqueMcb->Mapping); + ListEntry = &Mcb->Mapping->SequenceList; if (!IsListEmpty(ListEntry)) { Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence); @@ -409,10 +427,10 @@ FsRtlLookupLastBaseMcbEntryAndIndex(IN PBASE_MCB OpaqueMcb, *LargeVbn = Entry->RunStartVbn.QuadPart; *LargeLbn = Entry->StartingLbn.QuadPart; - for (i = 0, CountEntry = RtlEnumerateGenericTable(OpaqueMcb->Mapping, TRUE); + for (i = 0, CountEntry = RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); CountEntry != Entry; - CountEntry = RtlEnumerateGenericTable(OpaqueMcb->Mapping, FALSE)); - + CountEntry = RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE)); + DPRINT1("Most probably we are returning shit now\n"); *Index = i; } @@ -450,15 +468,16 @@ FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb, */ BOOLEAN NTAPI -FsRtlLookupLastBaseMcbEntry(IN PBASE_MCB Mcb, +FsRtlLookupLastBaseMcbEntry(IN PBASE_MCB OpaqueMcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; BOOLEAN Result = FALSE; PLIST_ENTRY ListEntry; PLARGE_MCB_MAPPING_ENTRY Entry; - ListEntry = GET_LIST_HEAD(Mcb->Mapping); + ListEntry = &Mcb->Mapping->SequenceList; if (!IsListEmpty(ListEntry)) { Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence); @@ -532,27 +551,32 @@ FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb) */ BOOLEAN NTAPI -FsRtlRemoveBaseMcbEntry(IN PBASE_MCB Mcb, +FsRtlRemoveBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn, IN LONGLONG SectorCount) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; LARGE_MCB_MAPPING_ENTRY Node; + LARGE_MCB_MAPPING_ENTRY NewElement; PLARGE_MCB_MAPPING_ENTRY Element; + PLARGE_MCB_MAPPING_ENTRY Reinserted, Inserted; + LARGE_INTEGER StartHole, EndHole, EndRun; Node.RunStartVbn.QuadPart = Vbn; Node.SectorCount.QuadPart = SectorCount; - while ((Element = RtlLookupElementGenericTable(Mcb->Mapping, &Node))) + while ((Element = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Node))) { + DPRINT1("Node.RunStartVbn %I64d, Node.SectorCount %I64d\n", Node.RunStartVbn.QuadPart, Node.SectorCount.QuadPart); + DPRINT1("Element %p, .RunStartVbn %I64d, .SectorCount %I64d\n", Element, Element->RunStartVbn.QuadPart, Element->SectorCount.QuadPart); // Must split if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart && Element->SectorCount.QuadPart > Node.SectorCount.QuadPart) { LARGE_MCB_MAPPING_ENTRY Upper, Reinsert; - PLARGE_MCB_MAPPING_ENTRY Reinserted, Inserted; - LARGE_INTEGER StartHole = Node.RunStartVbn; - LARGE_INTEGER EndHole; + StartHole = Node.RunStartVbn; EndHole.QuadPart = Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart; + Upper.RunStartVbn.QuadPart = EndHole.QuadPart; Upper.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + @@ -565,57 +589,50 @@ FsRtlRemoveBaseMcbEntry(IN PBASE_MCB Mcb, Reinsert.SectorCount.QuadPart = Element->RunStartVbn.QuadPart - StartHole.QuadPart; RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(Mcb->Mapping, Element); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); Mcb->PairCount--; - Reinserted = RtlInsertElementGenericTable - (Mcb->Mapping, &Reinsert, sizeof(Reinsert), NULL); - InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence); + Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Reinsert, sizeof(Reinsert), NULL); + InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); Mcb->PairCount++; - Inserted = RtlInsertElementGenericTable - (Mcb->Mapping, &Upper, sizeof(Upper), NULL); - InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Inserted->Sequence); + Inserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Upper, sizeof(Upper), NULL); + InsertHeadList(&Mcb->Mapping->SequenceList, &Inserted->Sequence); Mcb->PairCount++; } else if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart) { - LARGE_MCB_MAPPING_ENTRY NewElement; - PLARGE_MCB_MAPPING_ENTRY Reinserted; - LARGE_INTEGER StartHole = Node.RunStartVbn; + StartHole = Node.RunStartVbn; NewElement.RunStartVbn = Element->RunStartVbn; NewElement.StartingLbn = Element->StartingLbn; NewElement.SectorCount.QuadPart = StartHole.QuadPart - Element->StartingLbn.QuadPart; RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(Mcb->Mapping, Element); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); Mcb->PairCount--; - Reinserted = RtlInsertElementGenericTable - (Mcb->Mapping, &NewElement, sizeof(NewElement), NULL); - InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence); - Mcb->PairCount++; + Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &NewElement, sizeof(NewElement), NULL); + InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); + Mcb->PairCount++; } else { - LARGE_MCB_MAPPING_ENTRY NewElement; - PLARGE_MCB_MAPPING_ENTRY Reinserted; - LARGE_INTEGER EndHole = Element->RunStartVbn; - LARGE_INTEGER EndRun; + EndHole = Element->RunStartVbn; EndRun.QuadPart = Element->RunStartVbn.QuadPart + Element->SectorCount.QuadPart; NewElement.RunStartVbn = EndHole; - NewElement.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + - (EndHole.QuadPart - Element->RunStartVbn.QuadPart); + NewElement.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + (EndHole.QuadPart - Element->RunStartVbn.QuadPart); NewElement.SectorCount.QuadPart = EndRun.QuadPart - EndHole.QuadPart; RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(Mcb->Mapping, Element); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); Mcb->PairCount--; - Reinserted = RtlInsertElementGenericTable - (Mcb->Mapping, &NewElement, sizeof(NewElement), NULL); - InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &Reinserted->Sequence); - Mcb->PairCount++; + Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &NewElement, sizeof(NewElement), NULL); + InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); + Mcb->PairCount++; + + DPRINT1("Reinserted %p, .RunStartVbn %I64d, .SectorCount %I64d\n", Reinserted, Reinserted->RunStartVbn.QuadPart, Reinserted->SectorCount.QuadPart); + DPRINT1("NewElement .RunStartVbn %I64d, .SectorCount %I64d\n", NewElement.RunStartVbn.QuadPart, NewElement.SectorCount.QuadPart); } } @@ -631,7 +648,7 @@ FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount) { - DPRINT("FsRtlRemoveLargeMcbEntry Mcb %x, Vbn %x, SectorCount %x\n", Mcb, (ULONG)Vbn, (ULONG)SectorCount); + DPRINT("FsRtlRemoveLargeMcbEntry Mcb %x, Vbn %I64d, SectorCount %I64d\n", Mcb, (ULONG)Vbn, (ULONG)SectorCount); KeAcquireGuardedMutex(Mcb->GuardedMutex); FsRtlRemoveBaseMcbEntry(&(Mcb->BaseMcb), @@ -647,14 +664,15 @@ FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, */ VOID NTAPI -FsRtlResetBaseMcb(IN PBASE_MCB Mcb) +FsRtlResetBaseMcb(IN PBASE_MCB OpaqueMcb) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; PLARGE_MCB_MAPPING_ENTRY Element; - while (RtlNumberGenericTableElements(Mcb->Mapping) && - (Element = (PLARGE_MCB_MAPPING_ENTRY)RtlGetElementGenericTable(Mcb->Mapping, 0))) + while (RtlNumberGenericTableElements(&Mcb->Mapping->Table) && + (Element = (PLARGE_MCB_MAPPING_ENTRY)RtlGetElementGenericTable(&Mcb->Mapping->Table, 0))) { - RtlDeleteElementGenericTable(Mcb->Mapping, Element); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); } Mcb->PairCount = 0; @@ -686,7 +704,7 @@ FsRtlResetLargeMcb(IN PLARGE_MCB Mcb, #define MCB_BUMP_NO_MORE 0 #define MCB_BUMP_AGAIN 1 -static ULONG NTAPI McbBump(PBASE_MCB Mcb, PLARGE_MCB_MAPPING_ENTRY FixedPart) +static ULONG NTAPI McbBump(PBASE_MCB_INTERNAL Mcb, PLARGE_MCB_MAPPING_ENTRY FixedPart) { LARGE_MCB_MAPPING_ENTRY Reimagined; PLARGE_MCB_MAPPING_ENTRY Found = NULL; @@ -694,7 +712,7 @@ static ULONG NTAPI McbBump(PBASE_MCB Mcb, PLARGE_MCB_MAPPING_ENTRY FixedPart) DPRINT("McbBump %x (%x:%x)\n", Mcb, FixedPart->RunStartVbn.LowPart, FixedPart->SectorCount.LowPart); Reimagined = *FixedPart; - while ((Found = RtlLookupElementGenericTable(Mcb->Mapping, &Reimagined))) + while ((Found = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Reimagined))) { Reimagined = *Found; Reimagined.RunStartVbn.QuadPart = @@ -723,10 +741,11 @@ static ULONG NTAPI McbBump(PBASE_MCB Mcb, PLARGE_MCB_MAPPING_ENTRY FixedPart) */ BOOLEAN NTAPI -FsRtlSplitBaseMcb(IN PBASE_MCB Mcb, +FsRtlSplitBaseMcb(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn, IN LONGLONG Amount) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; ULONG Result; LARGE_MCB_MAPPING_ENTRY Node; PLARGE_MCB_MAPPING_ENTRY Existing = NULL; @@ -734,7 +753,7 @@ FsRtlSplitBaseMcb(IN PBASE_MCB Mcb, Node.RunStartVbn.QuadPart = Vbn; Node.SectorCount.QuadPart = 0; - Existing = RtlLookupElementGenericTable(Mcb->Mapping, &Node); + Existing = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Node); if (Existing) { @@ -765,21 +784,20 @@ FsRtlSplitBaseMcb(IN PBASE_MCB Mcb, { Node = *Existing; RemoveHeadList(&Existing->Sequence); - RtlDeleteElementGenericTable(Mcb->Mapping, Existing); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Existing); Mcb->PairCount--; // Adjust the element we found. Existing->SectorCount = LowerPart.SectorCount; - InsertedUpper = RtlInsertElementGenericTable - (Mcb->Mapping, &UpperPart, sizeof(UpperPart), NULL); + InsertedUpper = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &UpperPart, sizeof(UpperPart), NULL); if (!InsertedUpper) { // Just make it like it was Existing->SectorCount = Node.SectorCount; return FALSE; } - InsertHeadList(GET_LIST_HEAD(Mcb->Mapping), &InsertedUpper->Sequence); + InsertHeadList(&Mcb->Mapping->SequenceList, &InsertedUpper->Sequence); Mcb->PairCount++; } else @@ -825,12 +843,13 @@ FsRtlSplitLargeMcb(IN PLARGE_MCB Mcb, */ VOID NTAPI -FsRtlTruncateBaseMcb(IN PBASE_MCB Mcb, +FsRtlTruncateBaseMcb(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn) { + PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; if (!Vbn) { - FsRtlResetBaseMcb(Mcb); + FsRtlResetBaseMcb(OpaqueMcb); } else { @@ -838,10 +857,10 @@ FsRtlTruncateBaseMcb(IN PBASE_MCB Mcb, PLARGE_MCB_MAPPING_ENTRY Found; Truncate.RunStartVbn.QuadPart = Vbn; Truncate.SectorCount.QuadPart = (1ull<<62) - Truncate.RunStartVbn.QuadPart; - while ((Found = RtlLookupElementGenericTable(Mcb->Mapping, &Truncate))) + while ((Found = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Truncate))) { RemoveEntryList(&Found->Sequence); - RtlDeleteElementGenericTable(Mcb->Mapping, Found); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Found); Mcb->PairCount--; } } From 463cb697201164d3a9b95d2e50457be549939488 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 29 Apr 2013 10:28:58 +0000 Subject: [PATCH 04/67] [FSRTL] - Reformat the code for better readability. Sacrifice 80 chars max line width in favor of a readable code (sorry, but when the indentation eats 12 chars, formulas for calculating sizes are hard to fit into less than 70 chars, and they become totally unreadable). svn path=/trunk/; revision=58890 --- reactos/ntoskrnl/fsrtl/largemcb.c | 732 +++++++++++++++--------------- 1 file changed, 357 insertions(+), 375 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/largemcb.c b/reactos/ntoskrnl/fsrtl/largemcb.c index d94120e14d3..0246b682a02 100644 --- a/reactos/ntoskrnl/fsrtl/largemcb.c +++ b/reactos/ntoskrnl/fsrtl/largemcb.c @@ -21,10 +21,10 @@ NPAGED_LOOKASIDE_LIST FsRtlFastMutexLookasideList; typedef struct _LARGE_MCB_MAPPING_ENTRY { - LARGE_INTEGER RunStartVbn; - LARGE_INTEGER SectorCount; - LARGE_INTEGER StartingLbn; - LIST_ENTRY Sequence; + LARGE_INTEGER RunStartVbn; + LARGE_INTEGER SectorCount; + LARGE_INTEGER StartingLbn; + LIST_ENTRY Sequence; } LARGE_MCB_MAPPING_ENTRY, *PLARGE_MCB_MAPPING_ENTRY; typedef struct _LARGE_MCB_MAPPING @@ -44,29 +44,27 @@ typedef struct _BASE_MCB_INTERNAL { static PVOID NTAPI McbMappingAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes) { - PVOID Result; - PBASE_MCB Mcb = (PBASE_MCB)Table->TableContext; - Result = ExAllocatePoolWithTag(Mcb->PoolType, Bytes, 'LMCB'); - DPRINT("McbMappingAllocate(%d) => %p\n", Bytes, Result); - return Result; + PVOID Result; + PBASE_MCB Mcb = (PBASE_MCB)Table->TableContext; + Result = ExAllocatePoolWithTag(Mcb->PoolType, Bytes, 'LMCB'); + DPRINT("McbMappingAllocate(%d) => %p\n", Bytes, Result); + return Result; } static VOID NTAPI McbMappingFree(PRTL_GENERIC_TABLE Table, PVOID Buffer) { - DPRINT("McbMappingFree(%p)\n", Buffer); - ExFreePoolWithTag(Buffer, 'LMCB'); + DPRINT("McbMappingFree(%p)\n", Buffer); + ExFreePoolWithTag(Buffer, 'LMCB'); } static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingCompare (RTL_GENERIC_TABLE Table, PVOID PtrA, PVOID PtrB) { - PLARGE_MCB_MAPPING_ENTRY A = PtrA, B = PtrB; - return - (A->RunStartVbn.QuadPart + A->SectorCount.QuadPart < - B->RunStartVbn.QuadPart) ? GenericLessThan : - (A->RunStartVbn.QuadPart > - B->RunStartVbn.QuadPart + B->SectorCount.QuadPart) ? - GenericGreaterThan : GenericEqual; + PLARGE_MCB_MAPPING_ENTRY A = PtrA, B = PtrB; + + return + (A->RunStartVbn.QuadPart + A->SectorCount.QuadPart < B->RunStartVbn.QuadPart) ? GenericLessThan : + (A->RunStartVbn.QuadPart > B->RunStartVbn.QuadPart + B->SectorCount.QuadPart) ? GenericGreaterThan : GenericEqual; } /* PUBLIC FUNCTIONS **********************************************************/ @@ -82,66 +80,64 @@ FsRtlAddBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG SectorCount) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - LARGE_MCB_MAPPING_ENTRY Node; - PLARGE_MCB_MAPPING_ENTRY Existing = NULL; - BOOLEAN NewElement = FALSE; + LARGE_MCB_MAPPING_ENTRY Node; + PLARGE_MCB_MAPPING_ENTRY Existing = NULL; + BOOLEAN NewElement = FALSE; - Node.RunStartVbn.QuadPart = Vbn; - Node.StartingLbn.QuadPart = Lbn; - Node.SectorCount.QuadPart = SectorCount; + Node.RunStartVbn.QuadPart = Vbn; + Node.StartingLbn.QuadPart = Lbn; + Node.SectorCount.QuadPart = SectorCount; - while (!NewElement) - { - DPRINT("Inserting %x:%x\n", Node.RunStartVbn.LowPart, Node.SectorCount.LowPart); - Existing = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Node, sizeof(Node), &NewElement); - DPRINT("Existing %x\n", Existing); - if (!Existing) break; + while (!NewElement) + { + DPRINT("Inserting %x:%x\n", Node.RunStartVbn.LowPart, Node.SectorCount.LowPart); + Existing = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Node, sizeof(Node), &NewElement); + DPRINT("Existing %x\n", Existing); + if (!Existing) break; - DPRINT("NewElement %d\n", NewElement); - if (!NewElement) - { - // We merge the existing runs - LARGE_INTEGER StartVbn, FinalVbn; - DPRINT("Existing: %x:%x\n", Existing->RunStartVbn.LowPart, Node.SectorCount.LowPart); - if (Existing->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart) - { - StartVbn = Existing->RunStartVbn; - Node.StartingLbn = Existing->StartingLbn; - } - else - { - StartVbn = Node.RunStartVbn; - } - DPRINT("StartVbn %x\n", StartVbn.LowPart); - if (Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart > - Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart) - { - FinalVbn.QuadPart = - Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart; - } - else - { - FinalVbn.QuadPart = - Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart; - } - DPRINT("FinalVbn %x\n", FinalVbn.LowPart); - Node.RunStartVbn.QuadPart = StartVbn.QuadPart; - Node.SectorCount.QuadPart = FinalVbn.QuadPart - StartVbn.QuadPart; - RemoveHeadList(&Existing->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Existing); - Mcb->PairCount--; - } - else - { - DPRINT("Mapping added %x\n", Existing); - Mcb->MaximumPairCount++; - Mcb->PairCount++; - InsertHeadList(&Mcb->Mapping->SequenceList, &Existing->Sequence); - } - } + DPRINT("NewElement %d\n", NewElement); + if (!NewElement) + { + // We merge the existing runs + LARGE_INTEGER StartVbn, FinalVbn; + DPRINT("Existing: %x:%x\n", Existing->RunStartVbn.LowPart, Node.SectorCount.LowPart); + if (Existing->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart) + { + StartVbn = Existing->RunStartVbn; + Node.StartingLbn = Existing->StartingLbn; + } + else + { + StartVbn = Node.RunStartVbn; + } + DPRINT("StartVbn %x\n", StartVbn.LowPart); + if (Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart > + Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart) + { + FinalVbn.QuadPart = Existing->RunStartVbn.QuadPart + Existing->SectorCount.QuadPart; + } + else + { + FinalVbn.QuadPart = Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart; + } + DPRINT("FinalVbn %x\n", FinalVbn.LowPart); + Node.RunStartVbn.QuadPart = StartVbn.QuadPart; + Node.SectorCount.QuadPart = FinalVbn.QuadPart - StartVbn.QuadPart; + RemoveHeadList(&Existing->Sequence); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Existing); + Mcb->PairCount--; + } + else + { + DPRINT("Mapping added %x\n", Existing); + Mcb->MaximumPairCount++; + Mcb->PairCount++; + InsertHeadList(&Mcb->Mapping->SequenceList, &Existing->Sequence); + } + } - DPRINT("!!Existing %d\n", !!Existing); - return !!Existing; + DPRINT("!!Existing %d\n", !!Existing); + return !!Existing; } /* @@ -156,7 +152,7 @@ FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, { BOOLEAN Result; - DPRINT("Mcb %x Vbn %x Lbn %x SectorCount %x\n", Mcb, Vbn, Lbn, SectorCount); + DPRINT("Mcb %x Vbn %x Lbn %x SectorCount %x\n", Mcb, Vbn, Lbn, SectorCount); KeAcquireGuardedMutex(Mcb->GuardedMutex); Result = FsRtlAddBaseMcbEntry(&(Mcb->BaseMcb), @@ -165,7 +161,7 @@ FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, SectorCount); KeReleaseGuardedMutex(Mcb->GuardedMutex); - DPRINT("Done %d\n", Result); + DPRINT("Done %d\n", Result); return Result; } @@ -182,26 +178,26 @@ FsRtlGetNextBaseMcbEntry(IN PBASE_MCB OpaqueMcb, OUT PLONGLONG SectorCount) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - ULONG i = 0; - BOOLEAN Result = FALSE; - PLARGE_MCB_MAPPING_ENTRY Entry; - for (Entry = (PLARGE_MCB_MAPPING_ENTRY) - RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); - Entry && i < RunIndex; - Entry = (PLARGE_MCB_MAPPING_ENTRY) - RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE), i++); - if (Entry) - { - Result = TRUE; - if (Vbn) - *Vbn = Entry->RunStartVbn.QuadPart; - if (Lbn) - *Lbn = Entry->StartingLbn.QuadPart; - if (SectorCount) - *SectorCount = Entry->SectorCount.QuadPart; - } + ULONG i = 0; + BOOLEAN Result = FALSE; + PLARGE_MCB_MAPPING_ENTRY Entry; - return Result; + for (Entry = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); + Entry && (i < RunIndex); + Entry = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE), i++); + + if (Entry) + { + Result = TRUE; + if (Vbn) + *Vbn = Entry->RunStartVbn.QuadPart; + if (Lbn) + *Lbn = Entry->StartingLbn.QuadPart; + if (SectorCount) + *SectorCount = Entry->SectorCount.QuadPart; + } + + return Result; } /* @@ -217,7 +213,7 @@ FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, { BOOLEAN Result; - DPRINT("FsRtlGetNextLargeMcbEntry Mcb %x RunIndex %x\n", Mcb, RunIndex); + DPRINT("FsRtlGetNextLargeMcbEntry Mcb %x RunIndex %x\n", Mcb, RunIndex); KeAcquireGuardedMutex(Mcb->GuardedMutex); Result = FsRtlGetNextBaseMcbEntry(&(Mcb->BaseMcb), @@ -227,7 +223,7 @@ FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, SectorCount); KeReleaseGuardedMutex(Mcb->GuardedMutex); - DPRINT("Done %d\n", Result); + DPRINT("Done %d\n", Result); return Result; } @@ -250,19 +246,18 @@ FsRtlInitializeBaseMcb(IN PBASE_MCB OpaqueMcb, else { Mcb->Mapping = ExAllocatePoolWithTag(PoolType | POOL_RAISE_IF_ALLOCATION_FAILURE, - sizeof(LARGE_MCB_MAPPING), + sizeof(LARGE_MCB_MAPPING), 'FSBC'); } Mcb->PoolType = PoolType; Mcb->MaximumPairCount = MAXIMUM_PAIR_COUNT; - RtlInitializeGenericTable - (&Mcb->Mapping->Table, - (PRTL_GENERIC_COMPARE_ROUTINE)McbMappingCompare, - McbMappingAllocate, - McbMappingFree, - Mcb); - InitializeListHead(&Mcb->Mapping->SequenceList); + RtlInitializeGenericTable(&Mcb->Mapping->Table, + (PRTL_GENERIC_COMPARE_ROUTINE)McbMappingCompare, + McbMappingAllocate, + McbMappingFree, + Mcb); + InitializeListHead(&Mcb->Mapping->SequenceList); } /* @@ -302,7 +297,7 @@ FsRtlInitializeLargeMcbs(VOID) NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, - sizeof(LARGE_MCB_MAPPING), + sizeof(LARGE_MCB_MAPPING), IFS_POOL_TAG, 0); /* FIXME: Should be 4 */ @@ -330,43 +325,43 @@ FsRtlLookupBaseMcbEntry(IN PBASE_MCB OpaqueMcb, OUT PULONG Index OPTIONAL) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - BOOLEAN Result = FALSE; - LARGE_MCB_MAPPING_ENTRY ToLookup; - PLARGE_MCB_MAPPING_ENTRY Entry; + BOOLEAN Result = FALSE; + LARGE_MCB_MAPPING_ENTRY ToLookup; + PLARGE_MCB_MAPPING_ENTRY Entry; - ToLookup.RunStartVbn.QuadPart = Vbn; - ToLookup.SectorCount.QuadPart = 1; + ToLookup.RunStartVbn.QuadPart = Vbn; + ToLookup.SectorCount.QuadPart = 1; - Entry = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &ToLookup); + Entry = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &ToLookup); DPRINT("Entry %p\n", Entry); - if (!Entry) - { - // Find out if we have a following entry. The spec says we should return - // found with Lbn == -1 when we're beneath the largest map. - ToLookup.SectorCount.QuadPart = (1ull<<62) - ToLookup.RunStartVbn.QuadPart; - Entry = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &ToLookup); + if (!Entry) + { + // Find out if we have a following entry. The spec says we should return + // found with Lbn == -1 when we're beneath the largest map. + ToLookup.SectorCount.QuadPart = (1ull<<62) - ToLookup.RunStartVbn.QuadPart; + Entry = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &ToLookup); DPRINT("Entry %p\n", Entry); - if (Entry) - { - Result = TRUE; - if (Lbn) *Lbn = ~0ull; - } - else - { - Result = FALSE; - } - } - else - { - LARGE_INTEGER Offset; - Offset.QuadPart = Vbn - Entry->RunStartVbn.QuadPart; - Result = TRUE; - if (Lbn) *Lbn = Entry->StartingLbn.QuadPart + Offset.QuadPart; - if (SectorCountFromLbn) *SectorCountFromLbn = Entry->SectorCount.QuadPart - Offset.QuadPart; - if (StartingLbn) *StartingLbn = Entry->StartingLbn.QuadPart; - if (SectorCountFromStartingLbn) *SectorCountFromStartingLbn = Entry->SectorCount.QuadPart; - } - DPRINT("Done\n"); + if (Entry) + { + Result = TRUE; + if (Lbn) *Lbn = ~0ull; + } + else + { + Result = FALSE; + } + } + else + { + LARGE_INTEGER Offset; + Offset.QuadPart = Vbn - Entry->RunStartVbn.QuadPart; + Result = TRUE; + if (Lbn) *Lbn = Entry->StartingLbn.QuadPart + Offset.QuadPart; + if (SectorCountFromLbn) *SectorCountFromLbn = Entry->SectorCount.QuadPart - Offset.QuadPart; + if (StartingLbn) *StartingLbn = Entry->StartingLbn.QuadPart; + if (SectorCountFromStartingLbn) *SectorCountFromStartingLbn = Entry->SectorCount.QuadPart; + } + DPRINT("Done\n"); return Result; } @@ -385,7 +380,7 @@ FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, { BOOLEAN Result; - DPRINT("FsRtlLookupLargeMcbEntry Mcb %x Vbn %x\n", Mcb, (ULONG)Vbn); + DPRINT("FsRtlLookupLargeMcbEntry Mcb %x Vbn %x\n", Mcb, (ULONG)Vbn); KeAcquireGuardedMutex(Mcb->GuardedMutex); Result = FsRtlLookupBaseMcbEntry(&(Mcb->BaseMcb), @@ -397,7 +392,7 @@ FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, Index); KeReleaseGuardedMutex(Mcb->GuardedMutex); - DPRINT("Done %d\n", Result); + DPRINT("Done %d\n", Result); return Result; } @@ -413,28 +408,28 @@ FsRtlLookupLastBaseMcbEntryAndIndex(IN PBASE_MCB OpaqueMcb, IN OUT PULONG Index) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - ULONG i = 0; - BOOLEAN Result = FALSE; - PLIST_ENTRY ListEntry; - PLARGE_MCB_MAPPING_ENTRY Entry; - PLARGE_MCB_MAPPING_ENTRY CountEntry; + ULONG i = 0; + BOOLEAN Result = FALSE; + PLIST_ENTRY ListEntry; + PLARGE_MCB_MAPPING_ENTRY Entry; + PLARGE_MCB_MAPPING_ENTRY CountEntry; - ListEntry = &Mcb->Mapping->SequenceList; - if (!IsListEmpty(ListEntry)) - { - Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence); - Result = TRUE; - *LargeVbn = Entry->RunStartVbn.QuadPart; - *LargeLbn = Entry->StartingLbn.QuadPart; + ListEntry = &Mcb->Mapping->SequenceList; + if (!IsListEmpty(ListEntry)) + { + Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence); + Result = TRUE; + *LargeVbn = Entry->RunStartVbn.QuadPart; + *LargeLbn = Entry->StartingLbn.QuadPart; - for (i = 0, CountEntry = RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); - CountEntry != Entry; - CountEntry = RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE)); + for (i = 0, CountEntry = RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE); + CountEntry != Entry; + CountEntry = RtlEnumerateGenericTable(&Mcb->Mapping->Table, FALSE)); DPRINT1("Most probably we are returning shit now\n"); - *Index = i; - } + *Index = i; + } - return Result; + return Result; } /* @@ -449,7 +444,7 @@ FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb, { BOOLEAN Result; - DPRINT("FsRtlLookupLastLargeMcbEntryAndIndex %x\n", OpaqueMcb); + DPRINT("FsRtlLookupLastLargeMcbEntryAndIndex %x\n", OpaqueMcb); KeAcquireGuardedMutex(OpaqueMcb->GuardedMutex); Result = FsRtlLookupLastBaseMcbEntryAndIndex(&(OpaqueMcb->BaseMcb), @@ -458,7 +453,7 @@ FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb, Index); KeReleaseGuardedMutex(OpaqueMcb->GuardedMutex); - DPRINT("Done %d\n", Result); + DPRINT("Done %d\n", Result); return Result; } @@ -473,20 +468,20 @@ FsRtlLookupLastBaseMcbEntry(IN PBASE_MCB OpaqueMcb, OUT PLONGLONG Lbn) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - BOOLEAN Result = FALSE; - PLIST_ENTRY ListEntry; - PLARGE_MCB_MAPPING_ENTRY Entry; + BOOLEAN Result = FALSE; + PLIST_ENTRY ListEntry; + PLARGE_MCB_MAPPING_ENTRY Entry; - ListEntry = &Mcb->Mapping->SequenceList; - if (!IsListEmpty(ListEntry)) - { - Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence); - Result = TRUE; - *Vbn = Entry->RunStartVbn.QuadPart; - *Lbn = Entry->StartingLbn.QuadPart; - } - - return Result; + ListEntry = &Mcb->Mapping->SequenceList; + if (!IsListEmpty(ListEntry)) + { + Entry = CONTAINING_RECORD(ListEntry->Flink, LARGE_MCB_MAPPING_ENTRY, Sequence); + Result = TRUE; + *Vbn = Entry->RunStartVbn.QuadPart; + *Lbn = Entry->StartingLbn.QuadPart; + } + + return Result; } /* @@ -500,7 +495,7 @@ FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, { BOOLEAN Result; - DPRINT("FsRtlLookupLastLargeMcbEntry Mcb %x\n", Mcb); + DPRINT("FsRtlLookupLastLargeMcbEntry Mcb %x\n", Mcb); KeAcquireGuardedMutex(Mcb->GuardedMutex); Result = FsRtlLookupLastBaseMcbEntry(&(Mcb->BaseMcb), @@ -508,7 +503,7 @@ FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, Lbn); KeReleaseGuardedMutex(Mcb->GuardedMutex); - DPRINT("Done %d\n", Result); + DPRINT("Done %d\n", Result); return Result; } @@ -533,14 +528,14 @@ FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb) { ULONG NumberOfRuns; - DPRINT("FsRtlNumberOfRunsInLargeMcb Mcb %x\n", Mcb); + DPRINT("FsRtlNumberOfRunsInLargeMcb Mcb %x\n", Mcb); /* Read the number of runs while holding the MCB lock */ KeAcquireGuardedMutex(Mcb->GuardedMutex); NumberOfRuns = Mcb->BaseMcb.PairCount; KeReleaseGuardedMutex(Mcb->GuardedMutex); - DPRINT("Done %d\n", NumberOfRuns); + DPRINT("Done %d\n", NumberOfRuns); /* Return the count */ return NumberOfRuns; @@ -556,87 +551,81 @@ FsRtlRemoveBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG SectorCount) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - LARGE_MCB_MAPPING_ENTRY Node; - LARGE_MCB_MAPPING_ENTRY NewElement; - PLARGE_MCB_MAPPING_ENTRY Element; - PLARGE_MCB_MAPPING_ENTRY Reinserted, Inserted; - LARGE_INTEGER StartHole, EndHole, EndRun; + LARGE_MCB_MAPPING_ENTRY Node; + LARGE_MCB_MAPPING_ENTRY NewElement; + PLARGE_MCB_MAPPING_ENTRY Element; + PLARGE_MCB_MAPPING_ENTRY Reinserted, Inserted; + LARGE_INTEGER StartHole, EndHole, EndRun; - Node.RunStartVbn.QuadPart = Vbn; - Node.SectorCount.QuadPart = SectorCount; + Node.RunStartVbn.QuadPart = Vbn; + Node.SectorCount.QuadPart = SectorCount; - while ((Element = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Node))) - { + while ((Element = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Node))) + { DPRINT1("Node.RunStartVbn %I64d, Node.SectorCount %I64d\n", Node.RunStartVbn.QuadPart, Node.SectorCount.QuadPart); DPRINT1("Element %p, .RunStartVbn %I64d, .SectorCount %I64d\n", Element, Element->RunStartVbn.QuadPart, Element->SectorCount.QuadPart); - // Must split - if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart && - Element->SectorCount.QuadPart > Node.SectorCount.QuadPart) - { - LARGE_MCB_MAPPING_ENTRY Upper, Reinsert; - StartHole = Node.RunStartVbn; - EndHole.QuadPart = Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart; + // Must split + if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart && + Element->SectorCount.QuadPart > Node.SectorCount.QuadPart) + { + LARGE_MCB_MAPPING_ENTRY Upper, Reinsert; + StartHole = Node.RunStartVbn; + EndHole.QuadPart = Node.RunStartVbn.QuadPart + Node.SectorCount.QuadPart; - Upper.RunStartVbn.QuadPart = EndHole.QuadPart; - Upper.StartingLbn.QuadPart = - Element->StartingLbn.QuadPart + - EndHole.QuadPart - - Element->RunStartVbn.QuadPart; - Upper.SectorCount.QuadPart = - Element->SectorCount.QuadPart - - (EndHole.QuadPart - Element->RunStartVbn.QuadPart); - Reinsert = *Element; - Reinsert.SectorCount.QuadPart = - Element->RunStartVbn.QuadPart - StartHole.QuadPart; - RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); - Mcb->PairCount--; + Upper.RunStartVbn.QuadPart = EndHole.QuadPart; + Upper.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + EndHole.QuadPart - Element->RunStartVbn.QuadPart; + Upper.SectorCount.QuadPart = Element->SectorCount.QuadPart - (EndHole.QuadPart - Element->RunStartVbn.QuadPart); + Reinsert = *Element; + Reinsert.SectorCount.QuadPart = Element->RunStartVbn.QuadPart - StartHole.QuadPart; + RemoveEntryList(&Element->Sequence); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); + Mcb->PairCount--; - Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Reinsert, sizeof(Reinsert), NULL); - InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); - Mcb->PairCount++; - - Inserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Upper, sizeof(Upper), NULL); - InsertHeadList(&Mcb->Mapping->SequenceList, &Inserted->Sequence); - Mcb->PairCount++; - } - else if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart) - { - StartHole = Node.RunStartVbn; - NewElement.RunStartVbn = Element->RunStartVbn; - NewElement.StartingLbn = Element->StartingLbn; - NewElement.SectorCount.QuadPart = StartHole.QuadPart - Element->StartingLbn.QuadPart; + Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Reinsert, sizeof(Reinsert), NULL); + InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); + Mcb->PairCount++; - RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); - Mcb->PairCount--; - - Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &NewElement, sizeof(NewElement), NULL); - InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); - Mcb->PairCount++; - } - else - { - EndHole = Element->RunStartVbn; - EndRun.QuadPart = Element->RunStartVbn.QuadPart + Element->SectorCount.QuadPart; - NewElement.RunStartVbn = EndHole; - NewElement.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + (EndHole.QuadPart - Element->RunStartVbn.QuadPart); - NewElement.SectorCount.QuadPart = EndRun.QuadPart - EndHole.QuadPart; + Inserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Upper, sizeof(Upper), NULL); + InsertHeadList(&Mcb->Mapping->SequenceList, &Inserted->Sequence); + Mcb->PairCount++; + } + else if (Element->RunStartVbn.QuadPart < Node.RunStartVbn.QuadPart) + { + StartHole = Node.RunStartVbn; + NewElement.RunStartVbn = Element->RunStartVbn; + NewElement.StartingLbn = Element->StartingLbn; + NewElement.SectorCount.QuadPart = StartHole.QuadPart - Element->StartingLbn.QuadPart; - RemoveEntryList(&Element->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); - Mcb->PairCount--; - - Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &NewElement, sizeof(NewElement), NULL); - InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); - Mcb->PairCount++; + RemoveEntryList(&Element->Sequence); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); + Mcb->PairCount--; + + Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &NewElement, sizeof(NewElement), NULL); + InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); + Mcb->PairCount++; + } + else + { + EndHole = Element->RunStartVbn; + EndRun.QuadPart = Element->RunStartVbn.QuadPart + Element->SectorCount.QuadPart; + NewElement.RunStartVbn = EndHole; + NewElement.StartingLbn.QuadPart = Element->StartingLbn.QuadPart + (EndHole.QuadPart - Element->RunStartVbn.QuadPart); + NewElement.SectorCount.QuadPart = EndRun.QuadPart - EndHole.QuadPart; + + RemoveEntryList(&Element->Sequence); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); + Mcb->PairCount--; + + Reinserted = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &NewElement, sizeof(NewElement), NULL); + InsertHeadList(&Mcb->Mapping->SequenceList, &Reinserted->Sequence); + Mcb->PairCount++; DPRINT1("Reinserted %p, .RunStartVbn %I64d, .SectorCount %I64d\n", Reinserted, Reinserted->RunStartVbn.QuadPart, Reinserted->SectorCount.QuadPart); DPRINT1("NewElement .RunStartVbn %I64d, .SectorCount %I64d\n", NewElement.RunStartVbn.QuadPart, NewElement.SectorCount.QuadPart); - } - } + } + } - return TRUE; + return TRUE; } /* @@ -648,15 +637,13 @@ FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount) { - DPRINT("FsRtlRemoveLargeMcbEntry Mcb %x, Vbn %I64d, SectorCount %I64d\n", Mcb, (ULONG)Vbn, (ULONG)SectorCount); + DPRINT("FsRtlRemoveLargeMcbEntry Mcb %x, Vbn %I64d, SectorCount %I64d\n", Mcb, (ULONG)Vbn, (ULONG)SectorCount); KeAcquireGuardedMutex(Mcb->GuardedMutex); - FsRtlRemoveBaseMcbEntry(&(Mcb->BaseMcb), - Vbn, - SectorCount); + FsRtlRemoveBaseMcbEntry(&(Mcb->BaseMcb), Vbn, SectorCount); KeReleaseGuardedMutex(Mcb->GuardedMutex); - DPRINT("Done\n"); + DPRINT("Done\n"); } /* @@ -667,16 +654,16 @@ NTAPI FsRtlResetBaseMcb(IN PBASE_MCB OpaqueMcb) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - PLARGE_MCB_MAPPING_ENTRY Element; + PLARGE_MCB_MAPPING_ENTRY Element; - while (RtlNumberGenericTableElements(&Mcb->Mapping->Table) && - (Element = (PLARGE_MCB_MAPPING_ENTRY)RtlGetElementGenericTable(&Mcb->Mapping->Table, 0))) - { - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); - } + while (RtlNumberGenericTableElements(&Mcb->Mapping->Table) && + (Element = (PLARGE_MCB_MAPPING_ENTRY)RtlGetElementGenericTable(&Mcb->Mapping->Table, 0))) + { + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element); + } - Mcb->PairCount = 0; - Mcb->MaximumPairCount = 0; + Mcb->PairCount = 0; + Mcb->MaximumPairCount = 0; } /* @@ -688,17 +675,12 @@ FsRtlResetLargeMcb(IN PLARGE_MCB Mcb, IN BOOLEAN SelfSynchronized) { if (!SelfSynchronized) - { KeAcquireGuardedMutex(Mcb->GuardedMutex); - } - - FsRtlResetBaseMcb(&Mcb->BaseMcb); + FsRtlResetBaseMcb(&Mcb->BaseMcb); if (!SelfSynchronized) - { - KeReleaseGuardedMutex(Mcb->GuardedMutex); - } + KeReleaseGuardedMutex(Mcb->GuardedMutex); } #define MCB_BUMP_NO_MORE 0 @@ -706,34 +688,36 @@ FsRtlResetLargeMcb(IN PLARGE_MCB Mcb, static ULONG NTAPI McbBump(PBASE_MCB_INTERNAL Mcb, PLARGE_MCB_MAPPING_ENTRY FixedPart) { - LARGE_MCB_MAPPING_ENTRY Reimagined; - PLARGE_MCB_MAPPING_ENTRY Found = NULL; + LARGE_MCB_MAPPING_ENTRY Reimagined; + PLARGE_MCB_MAPPING_ENTRY Found = NULL; - DPRINT("McbBump %x (%x:%x)\n", Mcb, FixedPart->RunStartVbn.LowPart, FixedPart->SectorCount.LowPart); + DPRINT("McbBump %x (%x:%x)\n", Mcb, FixedPart->RunStartVbn.LowPart, FixedPart->SectorCount.LowPart); - Reimagined = *FixedPart; - while ((Found = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Reimagined))) - { - Reimagined = *Found; - Reimagined.RunStartVbn.QuadPart = - FixedPart->RunStartVbn.QuadPart + FixedPart->SectorCount.QuadPart; - DPRINT("Reimagined %x\n", Reimagined.RunStartVbn.LowPart); - } + Reimagined = *FixedPart; + while ((Found = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Reimagined))) + { + Reimagined = *Found; + Reimagined.RunStartVbn.QuadPart = + FixedPart->RunStartVbn.QuadPart + FixedPart->SectorCount.QuadPart; + DPRINT("Reimagined %x\n", Reimagined.RunStartVbn.LowPart); + } - DPRINT("Found %x\n", Found); - if (!Found) return MCB_BUMP_NO_MORE; - DPRINT1 - ("Moving %x-%x to %x because %x-%x overlaps\n", - Found->RunStartVbn.LowPart, - Found->RunStartVbn.LowPart + Found->SectorCount.QuadPart, - Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart, - Reimagined.RunStartVbn.LowPart, - Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart); - Found->RunStartVbn.QuadPart = Reimagined.RunStartVbn.QuadPart + Reimagined.SectorCount.QuadPart; - Found->StartingLbn.QuadPart = Reimagined.StartingLbn.QuadPart + Reimagined.SectorCount.QuadPart; + DPRINT("Found %x\n", Found); + if (!Found) return MCB_BUMP_NO_MORE; - DPRINT("Again\n"); - return MCB_BUMP_AGAIN; + DPRINT1 + ("Moving %x-%x to %x because %x-%x overlaps\n", + Found->RunStartVbn.LowPart, + Found->RunStartVbn.LowPart + Found->SectorCount.QuadPart, + Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart, + Reimagined.RunStartVbn.LowPart, + Reimagined.RunStartVbn.LowPart + Reimagined.SectorCount.LowPart); + + Found->RunStartVbn.QuadPart = Reimagined.RunStartVbn.QuadPart + Reimagined.SectorCount.QuadPart; + Found->StartingLbn.QuadPart = Reimagined.StartingLbn.QuadPart + Reimagined.SectorCount.QuadPart; + + DPRINT("Again\n"); + return MCB_BUMP_AGAIN; } /* @@ -746,72 +730,72 @@ FsRtlSplitBaseMcb(IN PBASE_MCB OpaqueMcb, IN LONGLONG Amount) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - ULONG Result; - LARGE_MCB_MAPPING_ENTRY Node; - PLARGE_MCB_MAPPING_ENTRY Existing = NULL; + ULONG Result; + LARGE_MCB_MAPPING_ENTRY Node; + PLARGE_MCB_MAPPING_ENTRY Existing = NULL; - Node.RunStartVbn.QuadPart = Vbn; - Node.SectorCount.QuadPart = 0; - - Existing = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Node); + Node.RunStartVbn.QuadPart = Vbn; + Node.SectorCount.QuadPart = 0; - if (Existing) - { - // We're in the middle of a run - LARGE_MCB_MAPPING_ENTRY UpperPart; - LARGE_MCB_MAPPING_ENTRY LowerPart; - PLARGE_MCB_MAPPING_ENTRY InsertedUpper; + Existing = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Node); - UpperPart.RunStartVbn.QuadPart = Node.RunStartVbn.QuadPart + Amount; - UpperPart.SectorCount.QuadPart = Existing->RunStartVbn.QuadPart + - (Existing->SectorCount.QuadPart - Node.RunStartVbn.QuadPart); - UpperPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart + - (Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart); - LowerPart.RunStartVbn.QuadPart = Existing->RunStartVbn.QuadPart; - LowerPart.SectorCount.QuadPart = Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart; - LowerPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart; - - Node = UpperPart; + if (Existing) + { + // We're in the middle of a run + LARGE_MCB_MAPPING_ENTRY UpperPart; + LARGE_MCB_MAPPING_ENTRY LowerPart; + PLARGE_MCB_MAPPING_ENTRY InsertedUpper; - DPRINT("Loop: %x\n", Node.RunStartVbn.LowPart); - while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN) - { - DPRINT("Node: %x\n", Node.RunStartVbn.LowPart); - } - DPRINT("Done\n"); + UpperPart.RunStartVbn.QuadPart = Node.RunStartVbn.QuadPart + Amount; + UpperPart.SectorCount.QuadPart = Existing->RunStartVbn.QuadPart + + (Existing->SectorCount.QuadPart - Node.RunStartVbn.QuadPart); + UpperPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart + + (Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart); + LowerPart.RunStartVbn.QuadPart = Existing->RunStartVbn.QuadPart; + LowerPart.SectorCount.QuadPart = Node.RunStartVbn.QuadPart - Existing->RunStartVbn.QuadPart; + LowerPart.StartingLbn.QuadPart = Existing->StartingLbn.QuadPart; - if (Result == MCB_BUMP_NO_MORE) - { - Node = *Existing; - RemoveHeadList(&Existing->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Existing); - Mcb->PairCount--; - - // Adjust the element we found. - Existing->SectorCount = LowerPart.SectorCount; + Node = UpperPart; - InsertedUpper = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &UpperPart, sizeof(UpperPart), NULL); - if (!InsertedUpper) - { - // Just make it like it was - Existing->SectorCount = Node.SectorCount; - return FALSE; - } - InsertHeadList(&Mcb->Mapping->SequenceList, &InsertedUpper->Sequence); - Mcb->PairCount++; - } - else - { - Node.RunStartVbn.QuadPart = Vbn; - Node.SectorCount.QuadPart = Amount; - while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN); - return Result == MCB_BUMP_NO_MORE; - } - } + DPRINT("Loop: %x\n", Node.RunStartVbn.LowPart); + while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN) + { + DPRINT("Node: %x\n", Node.RunStartVbn.LowPart); + } + DPRINT("Done\n"); - DPRINT("Done\n"); - - return TRUE; + if (Result == MCB_BUMP_NO_MORE) + { + Node = *Existing; + RemoveHeadList(&Existing->Sequence); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Existing); + Mcb->PairCount--; + + // Adjust the element we found. + Existing->SectorCount = LowerPart.SectorCount; + + InsertedUpper = RtlInsertElementGenericTable(&Mcb->Mapping->Table, &UpperPart, sizeof(UpperPart), NULL); + if (!InsertedUpper) + { + // Just make it like it was + Existing->SectorCount = Node.SectorCount; + return FALSE; + } + InsertHeadList(&Mcb->Mapping->SequenceList, &InsertedUpper->Sequence); + Mcb->PairCount++; + } + else + { + Node.RunStartVbn.QuadPart = Vbn; + Node.SectorCount.QuadPart = Amount; + while ((Result = McbBump(Mcb, &Node)) == MCB_BUMP_AGAIN); + return Result == MCB_BUMP_NO_MORE; + } + } + + DPRINT("Done\n"); + + return TRUE; } /* @@ -825,7 +809,7 @@ FsRtlSplitLargeMcb(IN PLARGE_MCB Mcb, { BOOLEAN Result; - DPRINT("FsRtlSplitLargeMcb %x, Vbn %x, Amount %x\n", Mcb, (ULONG)Vbn, (ULONG)Amount); + DPRINT("FsRtlSplitLargeMcb %x, Vbn %x, Amount %x\n", Mcb, (ULONG)Vbn, (ULONG)Amount); KeAcquireGuardedMutex(Mcb->GuardedMutex); Result = FsRtlSplitBaseMcb(&(Mcb->BaseMcb), @@ -833,7 +817,7 @@ FsRtlSplitLargeMcb(IN PLARGE_MCB Mcb, Amount); KeReleaseGuardedMutex(Mcb->GuardedMutex); - DPRINT("Done %d\n", Result); + DPRINT("Done %d\n", Result); return Result; } @@ -847,23 +831,23 @@ FsRtlTruncateBaseMcb(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn) { PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb; - if (!Vbn) - { - FsRtlResetBaseMcb(OpaqueMcb); - } - else - { - LARGE_MCB_MAPPING_ENTRY Truncate; - PLARGE_MCB_MAPPING_ENTRY Found; - Truncate.RunStartVbn.QuadPart = Vbn; - Truncate.SectorCount.QuadPart = (1ull<<62) - Truncate.RunStartVbn.QuadPart; - while ((Found = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Truncate))) - { - RemoveEntryList(&Found->Sequence); - RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Found); - Mcb->PairCount--; - } - } + if (!Vbn) + { + FsRtlResetBaseMcb(OpaqueMcb); + } + else + { + LARGE_MCB_MAPPING_ENTRY Truncate; + PLARGE_MCB_MAPPING_ENTRY Found; + Truncate.RunStartVbn.QuadPart = Vbn; + Truncate.SectorCount.QuadPart = (1ull<<62) - Truncate.RunStartVbn.QuadPart; + while ((Found = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &Truncate))) + { + RemoveEntryList(&Found->Sequence); + RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Found); + Mcb->PairCount--; + } + } } /* @@ -874,12 +858,11 @@ NTAPI FsRtlTruncateLargeMcb(IN PLARGE_MCB Mcb, IN LONGLONG Vbn) { - DPRINT("FsRtlTruncateLargeMcb %x Vbn %x\n", Mcb, (ULONG)Vbn); + DPRINT("FsRtlTruncateLargeMcb %x Vbn %x\n", Mcb, (ULONG)Vbn); KeAcquireGuardedMutex(Mcb->GuardedMutex); - FsRtlTruncateBaseMcb(&(Mcb->BaseMcb), - Vbn); + FsRtlTruncateBaseMcb(&(Mcb->BaseMcb), Vbn); KeReleaseGuardedMutex(Mcb->GuardedMutex); - DPRINT("Done\n"); + DPRINT("Done\n"); } /* @@ -889,7 +872,7 @@ VOID NTAPI FsRtlUninitializeBaseMcb(IN PBASE_MCB Mcb) { - FsRtlResetBaseMcb(Mcb); + FsRtlResetBaseMcb(Mcb); if ((Mcb->PoolType == PagedPool) && (Mcb->MaximumPairCount == MAXIMUM_PAIR_COUNT)) { @@ -916,4 +899,3 @@ FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb) FsRtlUninitializeBaseMcb(&(Mcb->BaseMcb)); } } - From bd3b0e8ef4219d2b203d883faf65c527b055efe7 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 29 Apr 2013 12:24:39 +0000 Subject: [PATCH 05/67] [LWIP] * Update to 1.4.1. Brought to you by Samuel Serapion. CORE-7140 svn path=/trunk/; revision=58891 --- reactos/lib/drivers/lwip/CHANGELOG | 346 +++++++++++ reactos/lib/drivers/lwip/doc/contrib.txt | 1 + reactos/lib/drivers/lwip/doc/rawapi.txt | 42 +- reactos/lib/drivers/lwip/doc/savannah.txt | 2 +- reactos/lib/drivers/lwip/doc/sys_arch.txt | 77 ++- reactos/lib/drivers/lwip/src/api/api_lib.c | 52 +- reactos/lib/drivers/lwip/src/api/api_msg.c | 140 +++-- reactos/lib/drivers/lwip/src/api/netdb.c | 17 +- reactos/lib/drivers/lwip/src/api/sockets.c | 75 ++- reactos/lib/drivers/lwip/src/api/tcpip.c | 93 ++- reactos/lib/drivers/lwip/src/core/dhcp.c | 179 +++--- reactos/lib/drivers/lwip/src/core/init.c | 146 +++-- .../lib/drivers/lwip/src/core/ipv4/autoip.c | 32 +- reactos/lib/drivers/lwip/src/core/ipv4/icmp.c | 4 + reactos/lib/drivers/lwip/src/core/ipv4/igmp.c | 12 - reactos/lib/drivers/lwip/src/core/ipv4/ip.c | 87 ++- reactos/lib/drivers/lwip/src/core/ipv6/ip6.c | 4 +- reactos/lib/drivers/lwip/src/core/mem.c | 41 +- reactos/lib/drivers/lwip/src/core/memp.c | 15 +- reactos/lib/drivers/lwip/src/core/netif.c | 34 +- reactos/lib/drivers/lwip/src/core/pbuf.c | 111 ++-- reactos/lib/drivers/lwip/src/core/raw.c | 12 +- reactos/lib/drivers/lwip/src/core/snmp/mib2.c | 2 +- .../lib/drivers/lwip/src/core/snmp/msg_in.c | 34 +- .../lib/drivers/lwip/src/core/snmp/msg_out.c | 17 +- reactos/lib/drivers/lwip/src/core/stats.c | 4 +- reactos/lib/drivers/lwip/src/core/sys.c | 2 + reactos/lib/drivers/lwip/src/core/tcp.c | 309 ++++++---- reactos/lib/drivers/lwip/src/core/tcp_in.c | 168 ++++-- reactos/lib/drivers/lwip/src/core/tcp_out.c | 52 +- reactos/lib/drivers/lwip/src/core/timers.c | 25 +- reactos/lib/drivers/lwip/src/core/udp.c | 143 +++-- .../lwip/src/include/ipv4/lwip/autoip.h | 3 +- .../drivers/lwip/src/include/ipv4/lwip/ip.h | 42 +- .../lib/drivers/lwip/src/include/lwip/api.h | 17 +- .../drivers/lwip/src/include/lwip/api_msg.h | 3 + .../lib/drivers/lwip/src/include/lwip/arch.h | 21 - .../lib/drivers/lwip/src/include/lwip/debug.h | 1 + .../lib/drivers/lwip/src/include/lwip/def.h | 4 - .../lib/drivers/lwip/src/include/lwip/init.h | 2 +- .../lib/drivers/lwip/src/include/lwip/mem.h | 1 + .../drivers/lwip/src/include/lwip/memp_std.h | 4 +- .../lib/drivers/lwip/src/include/lwip/netif.h | 13 + .../lib/drivers/lwip/src/include/lwip/opt.h | 114 +++- .../lib/drivers/lwip/src/include/lwip/pbuf.h | 24 + .../drivers/lwip/src/include/lwip/sockets.h | 7 +- .../lib/drivers/lwip/src/include/lwip/stats.h | 4 +- .../lib/drivers/lwip/src/include/lwip/sys.h | 6 + .../lib/drivers/lwip/src/include/lwip/tcp.h | 34 +- .../drivers/lwip/src/include/lwip/tcp_impl.h | 41 +- .../lib/drivers/lwip/src/include/lwip/tcpip.h | 10 +- .../drivers/lwip/src/include/lwip/timers.h | 2 + .../lib/drivers/lwip/src/include/lwip/udp.h | 2 +- .../drivers/lwip/src/include/netif/etharp.h | 1 + .../drivers/lwip/src/include/netif/slipif.h | 30 + reactos/lib/drivers/lwip/src/netif/etharp.c | 239 +++++--- .../lib/drivers/lwip/src/netif/ethernetif.c | 1 - reactos/lib/drivers/lwip/src/netif/loopif.c | 66 -- reactos/lib/drivers/lwip/src/netif/ppp/auth.c | 2 +- reactos/lib/drivers/lwip/src/netif/ppp/chap.c | 2 +- .../lib/drivers/lwip/src/netif/ppp/chpms.c | 2 +- reactos/lib/drivers/lwip/src/netif/ppp/fsm.c | 2 +- reactos/lib/drivers/lwip/src/netif/ppp/ipcp.c | 2 +- reactos/lib/drivers/lwip/src/netif/ppp/lcp.c | 2 +- .../lib/drivers/lwip/src/netif/ppp/magic.c | 2 +- reactos/lib/drivers/lwip/src/netif/ppp/md5.c | 2 +- reactos/lib/drivers/lwip/src/netif/ppp/pap.c | 4 +- reactos/lib/drivers/lwip/src/netif/ppp/ppp.c | 51 +- reactos/lib/drivers/lwip/src/netif/ppp/ppp.h | 316 +--------- .../lib/drivers/lwip/src/netif/ppp/ppp_oe.c | 2 +- .../lib/drivers/lwip/src/netif/ppp/randm.c | 2 +- reactos/lib/drivers/lwip/src/netif/ppp/vj.c | 12 +- .../lib/drivers/lwip/src/netif/ppp/vjbsdhdr.h | 75 --- reactos/lib/drivers/lwip/src/netif/slipif.c | 397 ++++++++---- reactos/lib/drivers/lwip/src/rosip.c | 1 + reactos/lib/drivers/lwip/src/rostcp.c | 1 + .../drivers/lwip/test/unit/lwip_unittests.c | 5 +- .../drivers/lwip/test/unit/tcp/tcp_helper.c | 154 ++++- .../drivers/lwip/test/unit/tcp/tcp_helper.h | 14 + .../lib/drivers/lwip/test/unit/tcp/test_tcp.c | 569 +++++++++++++++++- .../drivers/lwip/test/unit/tcp/test_tcp_oos.c | 432 ++++++++++++- 81 files changed, 3542 insertions(+), 1479 deletions(-) delete mode 100644 reactos/lib/drivers/lwip/src/netif/loopif.c delete mode 100644 reactos/lib/drivers/lwip/src/netif/ppp/vjbsdhdr.h diff --git a/reactos/lib/drivers/lwip/CHANGELOG b/reactos/lib/drivers/lwip/CHANGELOG index 6e27a66b8f0..d7fb2f85662 100644 --- a/reactos/lib/drivers/lwip/CHANGELOG +++ b/reactos/lib/drivers/lwip/CHANGELOG @@ -6,9 +6,355 @@ HISTORY ++ New features: + 2012-03-25: Simon Goldschmidt (idea by Mason) + * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h + which are a simple wrapper to the correct lwIP include files. + + 2012-01-16: Simon Goldschmidt + * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP + + 2011-12-17: Simon Goldschmidt + * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) + (fixes bug #35061) + + 2011-09-27: Simon Goldschmidt + * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) + (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) + + 2011-09-21: Simon Goldschmidt + * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on + send (TCP only, bug #33820) + + 2011-09-21: Simon Goldschmidt + * init.c: Converted runtime-sanity-checks into compile-time checks that can + be disabled (since runtime checks can often not be seen on embedded targets) + + 2011-09-11: Simon Goldschmidt + * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file + to get a clear separation of which functions an application or port may use + (task #11281) + + 2011-09-11: Simon Goldschmidt + * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize + initial local TCP/UDP ports (so that different port ranges are used after + a reboot; bug #33818; this one added tcp_init/udp_init functions again) + + 2011-09-03: Simon Goldschmidt + * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302) + + 2011-08-24: Simon Goldschmidt + * opt.h, netif.h/.c: added netif remove callback (bug #32397) + + 2011-07-26: Simon Goldschmidt + * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter + function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN) + + 2011-07-21: Simon Goldschmidt (patch by hanhui) + * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour: + Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. + Also added code to allow ip_forward() to forward non-broadcast packets to + the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1). + + 2011-07-21: Simon Goldschmidt + * sockets.c, opt.h: (bug #30185): added LWIP_FIONREAD_LINUXMODE that makes + ioctl/FIONREAD return the size of the next pending datagram. + + 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) + * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that + pcb->state != LISTEN + + 2011-05-25: Simon Goldschmidt + * again nearly the whole stack, renamed ip.c to ip4.c, ip_addr.c to ip4_addr.c, + combined ipv4/ipv6 inet_chksum.c, added ip.h, ip_addr.h: Combined IPv4 + and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP + code so that the code is more readable. + + 2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt) + * nearly the whole stack: Finally, we got decent IPv6 support, big thanks to + Ivan! (this is work in progress: we're just post release anyway :-) + + 2011-05-14: Simon Goldschmidt (patch by St?phane Lesage) + * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static + memory message + ++ Bugfixes: + 2013-01-15: Simon Goldschmidt + * ip4.c: fixed bug #37665 ip_canforward operates on address in wrong byte order + + 2013-01-15: Simon Goldschmidt + * pbuf.h: fixed bug #38097 pbuf_free_ooseq() warning + + 2013-01-14: Simon Goldschmidt + * dns.c: fixed bug #37705 Possible memory corruption in DNS query + + 2013-01-11: Simon Goldschmidt + * raw.c: fixed bug #38066 Raw pcbs can alter packet without eating it + + 2012-09-26: Simon Goldschmidt + * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7843 Fix corner case with dhcp timeouts + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet + + 2012-08-22: Simon Goldschmidt + * memp.c: fixed bug #37166: memp_sanity check loops itself + + 2012-08-13: Simon Goldschmidt + * dhcp.c: fixed bug #36645: Calling dhcp_release before dhcp_start + dereferences NULL + + 2012-08-13: Simon Goldschmidt + * msg_out.c: fixed bug #36840 snmp_send_trap() NULL de-reference if traps + configured but no interfaces available + + 2012-08-13: Simon Goldschmidt + * dns.c: fixed bug #36899 DNS TTL 0 is cached for a long time + + 2012-05-11: Simon Goldschmidt (patch by Marty) + * memp.c: fixed bug #36412: memp.c does not compile when + MEMP_OVERFLOW_CHECK > zero and MEMP_SEPARATE_POOLS == 1 + + 2012-05-08: Simon Goldschmidt + * tcp_out.c: fixed bug #36380: unsent_oversize mismatch in 1.4.1RC1 (this was + a debug-check issue only) + + 2012-05-03: Simon Goldschmidt (patch by Sylvain Rochet) + * ppp.c: fixed bug #36283 (PPP struct used on header size computation and + not packed) + + 2012-05-03: Simon Goldschmidt (patch by David Empson) + * ppp.c: fixed bug #36388 (PPP: checksum-only in last pbuf leads to pbuf with + zero length) + + 2012-03-27: Simon Goldschmidt + * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c + + 2012-03-27: Simon Goldschmidt (patch by Mason) + * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the + send MSS + + 2012-03-25: Simon Goldschmidt + * api_msg.c: Fixed bug #35817: do_connect() invalidly signals op_completed + for UDP/RAW with LWIP_TCPIP_CORE_LOCKING==1 + + 2012-03-25: Simon Goldschmidt + * api_msg.h, api_lib.c, api_msg.c, netifapi.c: fixed bug #35931: Name space + pollution in api_msg.c and netifapi.c + + 2012-03-22: Simon Goldschmidt + * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward + + 2012-03-20: Simon Goldschmidt (patch by Mason) + * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list + + 2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic) + * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian, + possible bug on little endian system + + 2012-02-23: Simon Goldschmidt + * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt + * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP() + (bug #35541: PPP Memory Leak) + + 2012-02-16: Simon Goldschmidt + * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt (patch by St?phane Lesage) + * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed + + 2012-02-15: Simon Goldschmidt + * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with + MEMP_MEM_MALLOC==1 + + 2012-02-12: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on + MSS > pcb->snd_wnd (by not creating segments bigger than half the window) + + 2012-02-11: Simon Goldschmidt + * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait + queue while closing + + 2012-01-22: Simon Goldschmidt + * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR) + + 2012-01-21: Simon Goldschmidt + * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb + + 2012-01-20: Simon Goldschmidt + * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths + + 2012-01-20: Simon Goldschmidt + * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy + + 2011-11-25: Simon Goldschmidt + * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt + tcp_active_pcbs in some cases + + 2011-11-23: Simon Goldschmidt + * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with + '#ifndef sys_msleep' + + 2011-11-22: Simon Goldschmidt + * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when + netif is brought down + + 2011-10-28: Simon Goldschmidt + * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks + + 2011-10-23: Simon Goldschmidt + * mem.c: fixed bug #34429: possible memory corruption with + LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1 + + 2011-10-18: Simon Goldschmidt + * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard + error value + + 2011-10-18: Simon Goldschmidt + * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small + windows (bug #34176 select after non-blocking send times out) + + 2011-10-18: Simon Goldschmidt + * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't + consider netif->mtu, causes slow network + + 2011-10-18: Simon Goldschmidt + * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code + + 2011-10-18: Simon Goldschmidt + * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS + + 2011-10-17: Simon Goldschmidt + * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api + + 2011-10-13: Simon Goldschmidt + * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no + zero window is received) by starting the persist timer when a zero window is + received, not when we have more data queued for sending than fits into the + window + + 2011-10-13: Simon Goldschmidt + * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex + + 2011-10-13: Simon Goldschmidt + * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is + used and not all protocols are enabled + + 2011-10-12: Simon Goldschmidt + * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4 + + 2011-10-09: Simon Goldschmidt + * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect + byte value when pcb->unacked != NULL + + 2011-10-09: Simon Goldschmidt + * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong + + 2011-09-27: Simon Goldschmidt + * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places... + + 2011-09-27: Simon Goldschmidt + * tcp_in.c: fixed bug #28288: Data after FIN in oos queue + + 2011-09-27: Simon Goldschmidt + * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf + + 2011-09-24: Simon Goldschmidt + * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1 + + 2011-09-23: Simon Goldschmidt + * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for + the last packet including FIN can lose data + + 2011-09-22: Simon Goldschmidt + * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into + account + + 2011-09-21: Simon Goldschmidt + * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks + in init.c + + 2011-09-20: Simon Goldschmidt + * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts) + + 2011-09-11: Simon Goldschmidt + * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs + (bug #34019) + + 2011-09-09: Simon Goldschmidt + * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if + udp port matches + + 2011-09-03: Simon Goldschmidt + * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet + is aggregated and sent to application + + 2011-09-01: Simon Goldschmidt + * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared + to other options + + 2011-09-01: Simon Goldschmidt + * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno + + 2011-08-24: Simon Goldschmidt + * inet6.h: fixed bug #34124 struct in6_addr does not conform to the standard + + 2011-08-24: Simon Goldschmidt + * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling + accept() on UDP connections + + 2011-08-24: Simon Goldschmidt + * sockets.h: fixed bug #34057 socklen_t should be a typedef + + 2011-08-24: Simon Goldschmidt + * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo) + + 2011-08-24: Simon Goldschmidt + * dhcp.c: fixed bug #34122 dhcp: hostname can overflow + + 2011-08-24: Simon Goldschmidt + * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr + + 2011-08-22: Simon Goldschmidt + * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This + merely prevents nagle from not transmitting fast after closing.) + + 2011-07-22: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns + always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now + lwip_send() sends as much as possible for non-blocking sockets + + 2011-07-22: Simon Goldschmidt + * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented + for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level. + + 2011-07-21: Simon Goldschmidt + * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by + sending an ARP request when an ARP entry is used in the last minute before + it would time out. + + 2011-07-04: Simon Goldschmidt + * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0. + + 2011-06-26: Simon Goldschmidt + * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by + updating its documentation only. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an + unaligned pointer. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1" diff --git a/reactos/lib/drivers/lwip/doc/contrib.txt b/reactos/lib/drivers/lwip/doc/contrib.txt index df57004b30d..39596fca335 100644 --- a/reactos/lib/drivers/lwip/doc/contrib.txt +++ b/reactos/lib/drivers/lwip/doc/contrib.txt @@ -60,3 +60,4 @@ features of Savannah help us not lose users' input. 1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and you think it could benefit others[1] you might want discuss this on the mailing list. You can also ask for CVS access to submit and maintain your port in the contrib CVS module. + \ No newline at end of file diff --git a/reactos/lib/drivers/lwip/doc/rawapi.txt b/reactos/lib/drivers/lwip/doc/rawapi.txt index bd452cf9344..8c190305edc 100644 --- a/reactos/lib/drivers/lwip/doc/rawapi.txt +++ b/reactos/lib/drivers/lwip/doc/rawapi.txt @@ -107,7 +107,7 @@ incoming connections or be explicitly connected to another host. Creates a new connection identifier (PCB). If memory is not available for creating the new pcb, NULL is returned. -- err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, +- err_t tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) Binds the pcb to a local IP address and port number. The IP address @@ -147,6 +147,8 @@ incoming connections or be explicitly connected to another host. usually be called from the accept callback. This allows lwIP to perform housekeeping tasks, such as allowing further incoming connections to be queued in the listen backlog. + ATTENTION: the PCB passed in must be the listening pcb, not the pcb passed + into the accept callback! - void tcp_accept(struct tcp_pcb *pcb, err_t (* accept)(void *arg, struct tcp_pcb *newpcb, @@ -154,8 +156,8 @@ incoming connections or be explicitly connected to another host. Specified the callback function that should be called when a new connection arrives on a listening connection. - -- err_t tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, + +- err_t tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err)); @@ -176,7 +178,7 @@ incoming connections or be explicitly connected to another host. available for enqueueing the SYN segment. If the SYN indeed was enqueued successfully, the tcp_connect() function returns ERR_OK. - + --- Sending TCP data TCP data is sent by enqueueing the data with a call to @@ -184,15 +186,19 @@ tcp_write(). When the data is successfully transmitted to the remote host, the application will be notified with a call to a specified callback function. -- err_t tcp_write(struct tcp_pcb *pcb, void *dataptr, u16_t len, - u8_t copy) +- err_t tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags) Enqueues the data pointed to by the argument dataptr. The length of - the data is passed as the len parameter. The copy argument is either - 0 or 1 and indicates whether the new memory should be allocated for - the data to be copied into. If the argument is 0, no new memory - should be allocated and the data should only be referenced by - pointer. + the data is passed as the len parameter. The apiflags can be one or more of: + - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated + for the data to be copied into. If this flag is not given, no new memory + should be allocated and the data should only be referenced by pointer. This + also means that the memory behind dataptr must not change until the data is + ACKed by the remote host + - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is given, + the PSH flag is set in the last segment created by this call to tcp_write. + If this flag is given, the PSH flag is not set. The tcp_write() function will fail and return ERR_MEM if the length of the data exceeds the current send buffer size or if the length of @@ -238,7 +244,7 @@ window. Must be called when the application has received the data. The len argument indicates the length of the received data. - + --- Application polling @@ -253,7 +259,7 @@ again when the connection has been idle for a while. - void tcp_poll(struct tcp_pcb *pcb, err_t (* poll)(void *arg, struct tcp_pcb *tpcb), - u8_t interval) + u8_t interval) Specifies the polling interval and the callback function that should be called to poll the application. The interval is specified in @@ -322,14 +328,14 @@ level of complexity of UDP, the interface is significantly simpler. Removes and deallocates the pcb. -- err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, +- err_t udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) Binds the pcb to a local address. The IP-address argument "ipaddr" can be IP_ADDR_ANY to indicate that it should listen to any local IP address. The function currently always return ERR_OK. -- err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, +- err_t udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) Sets the remote end of the pcb. This function does not generate any @@ -347,7 +353,7 @@ level of complexity of UDP, the interface is significantly simpler. - void udp_recv(struct udp_pcb *pcb, void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p, - struct ip_addr *addr, + ip_addr_t *addr, u16_t port), void *recv_arg) @@ -408,8 +414,8 @@ Call these functions in the order of appearance: Note: you must call tcp_fasttmr() and tcp_slowtmr() at the predefined regular intervals after this initialization. -- netif_add(struct netif *netif, struct ip_addr *ipaddr, - struct ip_addr *netmask, struct ip_addr *gw, +- netif_add(struct netif *netif, ip_addr_t *ipaddr, + ip_addr_t *netmask, ip_addr_t *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) diff --git a/reactos/lib/drivers/lwip/doc/savannah.txt b/reactos/lib/drivers/lwip/doc/savannah.txt index e3178997dec..409905b10c6 100644 --- a/reactos/lib/drivers/lwip/doc/savannah.txt +++ b/reactos/lib/drivers/lwip/doc/savannah.txt @@ -132,4 +132,4 @@ A new 0.6.3 release is now available here: http://savannah.nongnu.org/files/?group=lwip&highlight=0.6.3 You will have to submit this via the user News interface, then approve -this via the Administrator News interface. +this via the Administrator News interface. \ No newline at end of file diff --git a/reactos/lib/drivers/lwip/doc/sys_arch.txt b/reactos/lib/drivers/lwip/doc/sys_arch.txt index 38377b66551..847cd7777da 100644 --- a/reactos/lib/drivers/lwip/doc/sys_arch.txt +++ b/reactos/lib/drivers/lwip/doc/sys_arch.txt @@ -34,26 +34,36 @@ in the sys_arch.h file. Mailboxes are equivalently represented by the type "sys_mbox_t". lwIP does not place any restrictions on how sys_sem_t or sys_mbox_t are represented internally. +Since lwIP 1.4.0, semaphore and mailbox functions are prototyped in a way that +allows both using pointers or actual OS structures to be used. This way, memory +required for such types can be either allocated in place (globally or on the +stack) or on the heap (allocated internally in the "*_new()" functions). + The following functions must be implemented by the sys_arch: - void sys_init(void) Is called to initialize the sys_arch layer. -- sys_sem_t sys_sem_new(u8_t count) +- err_t sys_sem_new(sys_sem_t *sem, u8_t count) - Creates and returns a new semaphore. The "count" argument specifies - the initial state of the semaphore. + Creates a new semaphore. The semaphore is allocated to the memory that 'sem' + points to (which can be both a pointer or the actual OS structure). + The "count" argument specifies the initial state of the semaphore (which is + either 0 or 1). + If the semaphore has been created, ERR_OK should be returned. Returning any + other error will provide a hint what went wrong, but except for assertions, + no real error handling is implemented. -- void sys_sem_free(sys_sem_t sem) +- void sys_sem_free(sys_sem_t *sem) Deallocates a semaphore. -- void sys_sem_signal(sys_sem_t sem) +- void sys_sem_signal(sys_sem_t *sem) Signals a semaphore. -- u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) +- u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) Blocks the thread while waiting for the semaphore to be signaled. If the "timeout" argument is non-zero, the thread should @@ -70,30 +80,47 @@ The following functions must be implemented by the sys_arch: Notice that lwIP implements a function with a similar name, sys_sem_wait(), that uses the sys_arch_sem_wait() function. -- sys_mbox_t sys_mbox_new(int size) +- int sys_sem_valid(sys_sem_t *sem) + + Returns 1 if the semaphore is valid, 0 if it is not valid. + When using pointers, a simple way is to check the pointer for != NULL. + When directly using OS structures, implementing this may be more complex. + This may also be a define, in which case the function is not prototyped. + +- void sys_sem_set_invalid(sys_sem_t *sem) + + Invalidate a semaphore so that sys_sem_valid() returns 0. + ATTENTION: This does NOT mean that the semaphore shall be deallocated: + sys_sem_free() is always called before calling this function! + This may also be a define, in which case the function is not prototyped. + +- err_t sys_mbox_new(sys_mbox_t *mbox, int size) Creates an empty mailbox for maximum "size" elements. Elements stored in mailboxes are pointers. You have to define macros "_MBOX_SIZE" in your lwipopts.h, or ignore this parameter in your implementation and use a default size. + If the mailbox has been created, ERR_OK should be returned. Returning any + other error will provide a hint what went wrong, but except for assertions, + no real error handling is implemented. -- void sys_mbox_free(sys_mbox_t mbox) +- void sys_mbox_free(sys_mbox_t *mbox) Deallocates a mailbox. If there are messages still present in the mailbox when the mailbox is deallocated, it is an indication of a programming error in lwIP and the developer should be notified. -- void sys_mbox_post(sys_mbox_t mbox, void *msg) +- void sys_mbox_post(sys_mbox_t *mbox, void *msg) Posts the "msg" to the mailbox. This function have to block until the "msg" is really posted. -- err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) +- err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) Try to post the "msg" to the mailbox. Returns ERR_MEM if this one is full, else, ERR_OK if the "msg" is posted. -- u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) +- u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) Blocks the thread until a message arrives in the mailbox, but does not block the thread longer than "timeout" milliseconds (similar to @@ -110,7 +137,7 @@ The following functions must be implemented by the sys_arch: Note that a function with a similar name, sys_mbox_fetch(), is implemented by lwIP. -- u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) +- u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) This is similar to sys_arch_mbox_fetch, however if a message is not present in the mailbox, it immediately returns with the code @@ -122,7 +149,21 @@ The following functions must be implemented by the sys_arch: #define sys_arch_mbox_tryfetch(mbox,msg) \ sys_arch_mbox_fetch(mbox,msg,1) although this would introduce unnecessary delays. - + +- int sys_mbox_valid(sys_mbox_t *mbox) + + Returns 1 if the mailbox is valid, 0 if it is not valid. + When using pointers, a simple way is to check the pointer for != NULL. + When directly using OS structures, implementing this may be more complex. + This may also be a define, in which case the function is not prototyped. + +- void sys_mbox_set_invalid(sys_mbox_t *mbox) + + Invalidate a mailbox so that sys_mbox_valid() returns 0. + ATTENTION: This does NOT mean that the mailbox shall be deallocated: + sys_mbox_free() is always called before calling this function! + This may also be a define, in which case the function is not prototyped. + If threads are supported by the underlying operating system and if such functionality is needed in lwIP, the following function will have to be implemented as well: @@ -156,6 +197,16 @@ to be implemented as well: more information. This function is only required if your port is supporting an operating system. +For some configurations, you also need: + +- u32_t sys_now(void) + + This optional function returns the current time in milliseconds (don't care + for wraparound, this is only used for time diffs). + Not implementing this function means you cannot use some modules (e.g. TCP + timestamps, internal timeouts for NO_SYS==1). + + Note: Be carefull with using mem_malloc() in sys_arch. When malloc() refers to diff --git a/reactos/lib/drivers/lwip/src/api/api_lib.c b/reactos/lib/drivers/lwip/src/api/api_lib.c index b1a9e5253d8..4bdf08edfcc 100644 --- a/reactos/lib/drivers/lwip/src/api/api_lib.c +++ b/reactos/lib/drivers/lwip/src/api/api_lib.c @@ -372,7 +372,10 @@ netconn_recv_data(struct netconn *conn, void **new_buf) #endif /* LWIP_SO_RCVTIMEO*/ #if LWIP_TCP - if (conn->type == NETCONN_TCP) { +#if (LWIP_UDP || LWIP_RAW) + if (conn->type == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { if (!netconn_get_noautorecved(conn) || (buf == NULL)) { /* Let the stack know that we have taken the data. */ /* TODO: Speedup: Don't block and wait for the answer here @@ -461,7 +464,10 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf) LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); #if LWIP_TCP - if (conn->type == NETCONN_TCP) { +#if (LWIP_UDP || LWIP_RAW) + if (conn->type == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { struct pbuf *p = NULL; /* This is not a listening netconn, since recvmbox is set */ @@ -485,8 +491,11 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf) *new_buf = buf; /* don't set conn->last_err: it's only ERR_OK, anyway */ return ERR_OK; - } else + } #endif /* LWIP_TCP */ +#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) + else +#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ { #if (LWIP_UDP || LWIP_RAW) return netconn_recv_data(conn, (void **)new_buf); @@ -582,31 +591,62 @@ netconn_send(struct netconn *conn, struct netbuf *buf) * - NETCONN_COPY: data will be copied into memory belonging to the stack * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent * - NETCONN_DONTBLOCK: only write the data if all dat can be written at once + * @param bytes_written pointer to a location that receives the number of written bytes * @return ERR_OK if data was sent, any other err_t on error */ err_t -netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags) +netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written) { struct api_msg msg; err_t err; + u8_t dontblock; LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;); if (size == 0) { return ERR_OK; } + dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); + if (dontblock && !bytes_written) { + /* This implies netconn_write() cannot be used for non-blocking send, since + it has no way to return the number of bytes written. */ + return ERR_VAL; + } - /* @todo: for non-blocking write, check if 'size' would ever fit into - snd_queue or snd_buf */ + /* non-blocking write sends as much */ msg.function = do_write; msg.msg.conn = conn; msg.msg.msg.w.dataptr = dataptr; msg.msg.msg.w.apiflags = apiflags; msg.msg.msg.w.len = size; +#if LWIP_SO_SNDTIMEO + if (conn->send_timeout != 0) { + /* get the time we started, which is later compared to + sys_now() + conn->send_timeout */ + msg.msg.msg.w.time_started = sys_now(); + } else { + msg.msg.msg.w.time_started = 0; + } +#endif /* LWIP_SO_SNDTIMEO */ + /* For locking the core: this _can_ be delayed on low memory/low send buffer, but if it is, this is done inside api_msg.c:do_write(), so we can use the non-blocking version here. */ err = TCPIP_APIMSG(&msg); + if ((err == ERR_OK) && (bytes_written != NULL)) { + if (dontblock +#if LWIP_SO_SNDTIMEO + || (conn->send_timeout != 0) +#endif /* LWIP_SO_SNDTIMEO */ + ) { + /* nonblocking write: maybe the data has been sent partly */ + *bytes_written = msg.msg.msg.w.len; + } else { + /* blocking call succeeded: all data has been sent if it */ + *bytes_written = size; + } + } NETCONN_SET_SAFE_ERR(conn, err); return err; diff --git a/reactos/lib/drivers/lwip/src/api/api_msg.c b/reactos/lib/drivers/lwip/src/api/api_msg.c index 448f96dda0a..d4e44b9ad20 100644 --- a/reactos/lib/drivers/lwip/src/api/api_msg.c +++ b/reactos/lib/drivers/lwip/src/api/api_msg.c @@ -456,6 +456,14 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) { /* When returning != ERR_OK, the pcb is aborted in tcp_process(), so do nothing here! */ + /* remove all references to this netconn from the pcb */ + struct tcp_pcb* pcb = newconn->pcb.tcp; + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_sent(pcb, NULL); + tcp_poll(pcb, NULL, 4); + tcp_err(pcb, NULL); + /* remove reference from to the pcb from this netconn */ newconn->pcb.tcp = NULL; /* no need to drain since we know the recvmbox is empty. */ sys_mbox_free(&newconn->recvmbox); @@ -597,18 +605,16 @@ netconn_alloc(enum netconn_type t, netconn_callback callback) #endif /* LWIP_TCP */ default: LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); - break; + goto free_and_return; } #endif if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) { - memp_free(MEMP_NETCONN, conn); - return NULL; + goto free_and_return; } if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) { sys_sem_free(&conn->op_completed); - memp_free(MEMP_NETCONN, conn); - return NULL; + goto free_and_return; } #if LWIP_TCP @@ -624,6 +630,9 @@ netconn_alloc(enum netconn_type t, netconn_callback callback) conn->current_msg = NULL; conn->write_offset = 0; #endif /* LWIP_TCP */ +#if LWIP_SO_SNDTIMEO + conn->send_timeout = 0; +#endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO conn->recv_timeout = 0; #endif /* LWIP_SO_RCVTIMEO */ @@ -633,6 +642,9 @@ netconn_alloc(enum netconn_type t, netconn_callback callback) #endif /* LWIP_SO_RCVBUF */ conn->flags = 0; return conn; +free_and_return: + memp_free(MEMP_NETCONN, conn); + return NULL; } /** @@ -770,21 +782,21 @@ do_close_internal(struct netconn *conn) } } /* Try to close the connection */ - if (shut == NETCONN_SHUT_RDWR) { + if (close) { err = tcp_close(conn->pcb.tcp); } else { - err = tcp_shutdown(conn->pcb.tcp, shut & NETCONN_SHUT_RD, shut & NETCONN_SHUT_WR); + err = tcp_shutdown(conn->pcb.tcp, shut_rx, shut_tx); } if (err == ERR_OK) { /* Closing succeeded */ conn->current_msg->err = ERR_OK; conn->current_msg = NULL; conn->state = NETCONN_NONE; - /* Set back some callback pointers as conn is going away */ - conn->pcb.tcp = NULL; - /* Trigger select() in socket layer. Make sure everybody notices activity - on the connection, error first! */ if (close) { + /* Set back some callback pointers as conn is going away */ + conn->pcb.tcp = NULL; + /* Trigger select() in socket layer. Make sure everybody notices activity + on the connection, error first! */ API_EVENT(conn, NETCONN_EVT_ERROR, 0); } if (shut_rx) { @@ -1089,6 +1101,8 @@ do_listen(struct api_msg_msg *msg) } } } + } else { + msg->err = ERR_ARG; } } } @@ -1193,7 +1207,7 @@ do_recv(struct api_msg_msg *msg) static err_t do_writemore(struct netconn *conn) { - err_t err = ERR_OK; + err_t err; void *dataptr; u16_t len, available; u8_t write_finished = 0; @@ -1209,62 +1223,78 @@ do_writemore(struct netconn *conn) LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len", conn->write_offset < conn->current_msg->msg.w.len); - dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset; - diff = conn->current_msg->msg.w.len - conn->write_offset; - if (diff > 0xffffUL) { /* max_u16_t */ - len = 0xffff; +#if LWIP_SO_SNDTIMEO + if ((conn->send_timeout != 0) && + ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { + write_finished = 1; + if (conn->write_offset == 0) { + /* nothing has been written */ + err = ERR_WOULDBLOCK; + conn->current_msg->msg.w.len = 0; + } else { + /* partial write */ + err = ERR_OK; + conn->current_msg->msg.w.len = conn->write_offset; + } + } else +#endif /* LWIP_SO_SNDTIMEO */ + { + dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset; + diff = conn->current_msg->msg.w.len - conn->write_offset; + if (diff > 0xffffUL) { /* max_u16_t */ + len = 0xffff; #if LWIP_TCPIP_CORE_LOCKING - conn->flags |= NETCONN_FLAG_WRITE_DELAYED; + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; #endif - apiflags |= TCP_WRITE_FLAG_MORE; - } else { - len = (u16_t)diff; - } - available = tcp_sndbuf(conn->pcb.tcp); - if (available < len) { - /* don't try to write more than sendbuf */ - len = available; + apiflags |= TCP_WRITE_FLAG_MORE; + } else { + len = (u16_t)diff; + } + available = tcp_sndbuf(conn->pcb.tcp); + if (available < len) { + /* don't try to write more than sendbuf */ + len = available; + if (dontblock){ + if (!len) { + err = ERR_WOULDBLOCK; + goto err_mem; + } + } else { #if LWIP_TCPIP_CORE_LOCKING - conn->flags |= NETCONN_FLAG_WRITE_DELAYED; + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; #endif - apiflags |= TCP_WRITE_FLAG_MORE; - } - if (dontblock && (len < conn->current_msg->msg.w.len)) { - /* failed to send all data at once -> nonblocking write not possible */ - err = ERR_MEM; - } - if (err == ERR_OK) { + apiflags |= TCP_WRITE_FLAG_MORE; + } + } LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len)); err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); - } - if (dontblock && (err == ERR_MEM)) { - /* nonblocking write failed */ - write_finished = 1; - err = ERR_WOULDBLOCK; - /* let poll_tcp check writable space to mark the pcb - writable again */ - conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; - /* let select mark this pcb as non-writable. */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); - } else { /* if OK or memory error, check available space */ - if (((err == ERR_OK) || (err == ERR_MEM)) && - ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || - (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT))) { - /* The queued byte- or pbuf-count exceeds the configured low-water limit, - let select mark this pcb as non-writable. */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + if ((err == ERR_OK) || (err == ERR_MEM)) { +err_mem: + if (dontblock && (len < conn->current_msg->msg.w.len)) { + /* non-blocking write did not write everything: mark the pcb non-writable + and let poll_tcp check writable space to mark the pcb writable again */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; + } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || + (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { + /* The queued byte- or pbuf-count exceeds the configured low-water limit, + let select mark this pcb as non-writable. */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + } } if (err == ERR_OK) { conn->write_offset += len; - if (conn->write_offset == conn->current_msg->msg.w.len) { + if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) { + /* return sent length */ + conn->current_msg->msg.w.len = conn->write_offset; /* everything was written */ write_finished = 1; conn->write_offset = 0; } tcp_output(conn->pcb.tcp); - } else if (err == ERR_MEM) { + } else if ((err == ERR_MEM) && !dontblock) { /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called we do NOT return to the application thread, since ERR_MEM is only a temporary error! */ @@ -1272,16 +1302,16 @@ do_writemore(struct netconn *conn) /* tcp_write returned ERR_MEM, try tcp_output anyway */ tcp_output(conn->pcb.tcp); - #if LWIP_TCPIP_CORE_LOCKING +#if LWIP_TCPIP_CORE_LOCKING conn->flags |= NETCONN_FLAG_WRITE_DELAYED; - #endif +#endif } else { /* On errors != ERR_MEM, we don't try writing any more but return the error to the application thread. */ write_finished = 1; + conn->current_msg->msg.w.len = 0; } } - if (write_finished) { /* everything was written: set back connection state and back to application task */ diff --git a/reactos/lib/drivers/lwip/src/api/netdb.c b/reactos/lib/drivers/lwip/src/api/netdb.c index a7e4e06bca2..6a4bac561ce 100644 --- a/reactos/lib/drivers/lwip/src/api/netdb.c +++ b/reactos/lib/drivers/lwip/src/api/netdb.c @@ -49,7 +49,7 @@ /** helper struct for gethostbyname_r to access the char* buffer */ struct gethostbyname_r_helper { - ip_addr_t *addrs; + ip_addr_t *addr_list[2]; ip_addr_t addr; char *aliases; }; @@ -180,7 +180,7 @@ lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, } /* first thing to do: set *result to nothing */ *result = NULL; - if ((name == NULL) || (ret == NULL) || (buf == 0)) { + if ((name == NULL) || (ret == NULL) || (buf == NULL)) { /* not all arguments given */ *h_errnop = EINVAL; return -1; @@ -197,10 +197,10 @@ lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper); /* query host IP address */ - err = netconn_gethostbyname(name, &(h->addr)); + err = netconn_gethostbyname(name, &h->addr); if (err != ERR_OK) { LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); - *h_errnop = ENSRNOTFOUND; + *h_errnop = HOST_NOT_FOUND; return -1; } @@ -209,13 +209,14 @@ lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, hostname[namelen] = 0; /* fill hostent */ - h->addrs = &(h->addr); + h->addr_list[0] = &h->addr; + h->addr_list[1] = NULL; h->aliases = NULL; - ret->h_name = (char*)hostname; - ret->h_aliases = &(h->aliases); + ret->h_name = hostname; + ret->h_aliases = &h->aliases; ret->h_addrtype = AF_INET; ret->h_length = sizeof(ip_addr_t); - ret->h_addr_list = (char**)&(h->addrs); + ret->h_addr_list = (char**)&h->addr_list; /* set result != NULL */ *result = ret; diff --git a/reactos/lib/drivers/lwip/src/api/sockets.c b/reactos/lib/drivers/lwip/src/api/sockets.c index e36012ce43b..359919e7842 100644 --- a/reactos/lib/drivers/lwip/src/api/sockets.c +++ b/reactos/lib/drivers/lwip/src/api/sockets.c @@ -336,6 +336,10 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) err = netconn_accept(sock->conn, &newconn); if (err != ERR_OK) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); + if (netconn_type(sock->conn) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } sock_set_errno(sock, err_to_errno(err)); return -1; } @@ -537,6 +541,10 @@ lwip_listen(int s, int backlog) if (err != ERR_OK) { LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); + if (netconn_type(sock->conn) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } sock_set_errno(sock, err_to_errno(err)); return -1; } @@ -748,6 +756,7 @@ lwip_send(int s, const void *data, size_t size, int flags) struct lwip_sock *sock; err_t err; u8_t write_flags; + size_t written; LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", s, data, size, flags)); @@ -766,22 +775,15 @@ lwip_send(int s, const void *data, size_t size, int flags) #endif /* (LWIP_UDP || LWIP_RAW) */ } - if ((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) { - if ((size > TCP_SND_BUF) || ((size / TCP_MSS) > TCP_SND_QUEUELEN)) { - /* too much data to ever send nonblocking! */ - sock_set_errno(sock, EMSGSIZE); - return -1; - } - } - write_flags = NETCONN_COPY | ((flags & MSG_MORE) ? NETCONN_MORE : 0) | ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); - err = netconn_write(sock->conn, data, size, write_flags); + written = 0; + err = netconn_write_partly(sock->conn, data, size, write_flags, &written); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%"SZT_F"\n", s, err, size)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? (int)size : -1); + return (err == ERR_OK ? (int)written : -1); } int @@ -847,18 +849,29 @@ lwip_sendto(int s, const void *data, size_t size, int flags, inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr); remote_port = ntohs(to_in->sin_port); } else { - remote_addr = &sock->conn->pcb.raw->remote_ip; - if (sock->conn->type == NETCONN_RAW) { - remote_port = 0; - } else { + remote_addr = &sock->conn->pcb.ip->remote_ip; +#if LWIP_UDP + if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_UDP) { remote_port = sock->conn->pcb.udp->remote_port; + } else +#endif /* LWIP_UDP */ + { + remote_port = 0; } } LOCK_TCPIP_CORE(); - if (sock->conn->type == NETCONN_RAW) { + if (netconn_type(sock->conn) == NETCONN_RAW) { +#if LWIP_RAW err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr); - } else { +#else /* LWIP_RAW */ + err = ERR_ARG; +#endif /* LWIP_RAW */ + } +#if LWIP_UDP && LWIP_RAW + else +#endif /* LWIP_UDP && LWIP_RAW */ + { #if LWIP_UDP #if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p, @@ -1468,7 +1481,9 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) case SO_ERROR: case SO_KEEPALIVE: /* UNIMPL case SO_CONTIMEO: */ - /* UNIMPL case SO_SNDTIMEO: */ +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: +#endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO case SO_RCVTIMEO: #endif /* LWIP_SO_RCVTIMEO */ @@ -1676,7 +1691,7 @@ lwip_getsockopt_internal(void *arg) case SO_REUSEPORT: #endif /* SO_REUSE */ /*case SO_USELOOPBACK: UNIMPL */ - *(int*)optval = sock->conn->pcb.ip->so_options & optname; + *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname); LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", s, optname, (*(int*)optval?"on":"off"))); break; @@ -1713,6 +1728,11 @@ lwip_getsockopt_internal(void *arg) s, *(int *)optval)); break; +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + *(int *)optval = netconn_get_sendtimeout(sock->conn); + break; +#endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO case SO_RCVTIMEO: *(int *)optval = netconn_get_recvtimeout(sock->conn); @@ -1867,7 +1887,9 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt /* UNIMPL case SO_DONTROUTE: */ case SO_KEEPALIVE: /* UNIMPL case case SO_CONTIMEO: */ - /* UNIMPL case case SO_SNDTIMEO: */ +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: +#endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO case SO_RCVTIMEO: #endif /* LWIP_SO_RCVTIMEO */ @@ -2086,13 +2108,18 @@ lwip_setsockopt_internal(void *arg) #endif /* SO_REUSE */ /* UNIMPL case SO_USELOOPBACK: */ if (*(int*)optval) { - sock->conn->pcb.ip->so_options |= optname; + ip_set_option(sock->conn->pcb.ip, optname); } else { - sock->conn->pcb.ip->so_options &= ~optname; + ip_reset_option(sock->conn->pcb.ip, optname); } LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", s, optname, (*(int*)optval?"on":"off"))); break; +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + netconn_set_sendtimeout(sock->conn, (s32_t)*(int*)optval); + break; +#endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO case SO_RCVTIMEO: netconn_set_recvtimeout(sock->conn, *(int*)optval); @@ -2218,7 +2245,7 @@ lwip_setsockopt_internal(void *arg) case IPPROTO_UDPLITE: switch (optname) { case UDPLITE_SEND_CSCOV: - if ((*(int*)optval != 0) && ((*(int*)optval < 8)) || (*(int*)optval > 0xffff)) { + if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { /* don't allow illegal values! */ sock->conn->pcb.udp->chksum_len_tx = 8; } else { @@ -2228,7 +2255,7 @@ lwip_setsockopt_internal(void *arg) s, (*(int*)optval)) ); break; case UDPLITE_RECV_CSCOV: - if ((*(int*)optval != 0) && ((*(int*)optval < 8)) || (*(int*)optval > 0xffff)) { + if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { /* don't allow illegal values! */ sock->conn->pcb.udp->chksum_len_rx = 8; } else { diff --git a/reactos/lib/drivers/lwip/src/api/tcpip.c b/reactos/lib/drivers/lwip/src/api/tcpip.c index 857e7d9bd64..18d5f679f40 100644 --- a/reactos/lib/drivers/lwip/src/api/tcpip.c +++ b/reactos/lib/drivers/lwip/src/api/tcpip.c @@ -117,12 +117,6 @@ tcpip_thread(void *arg) break; #endif /* LWIP_NETIF_API */ - case TCPIP_MSG_CALLBACK: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); - msg->msg.cb.function(msg->msg.cb.ctx); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; - #if LWIP_TCPIP_TIMEOUT case TCPIP_MSG_TIMEOUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); @@ -136,6 +130,17 @@ tcpip_thread(void *arg) break; #endif /* LWIP_TCPIP_TIMEOUT */ + case TCPIP_MSG_CALLBACK: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + + case TCPIP_MSG_CALLBACK_STATIC: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + break; + default: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); LWIP_ASSERT("tcpip_thread: invalid message", 0); @@ -172,22 +177,22 @@ tcpip_input(struct pbuf *p, struct netif *inp) #else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ struct tcpip_msg *msg; - if (sys_mbox_valid(&mbox)) { - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_INPKT; - msg->msg.inp.p = p; - msg->msg.inp.netif = inp; - if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { - memp_free(MEMP_TCPIP_MSG_INPKT, msg); - return ERR_MEM; - } - return ERR_OK; + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; } - return ERR_VAL; + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_INPKT; + msg->msg.inp.p = p; + msg->msg.inp.netif = inp; + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + return ERR_MEM; + } + return ERR_OK; #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ } @@ -392,6 +397,52 @@ tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) #endif /* !LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_NETIF_API */ +/** + * Allocate a structure for a static callback message and initialize it. + * This is intended to be used to send "static" messages from interrupt context. + * + * @param function the function to call + * @param ctx parameter passed to function + * @return a struct pointer to pass to tcpip_trycallback(). + */ +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) +{ + struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return NULL; + } + msg->type = TCPIP_MSG_CALLBACK_STATIC; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + return (struct tcpip_callback_msg*)msg; +} + +/** + * Free a callback message allocated by tcpip_callbackmsg_new(). + * + * @param msg the message to free + */ +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg) +{ + memp_free(MEMP_TCPIP_MSG_API, msg); +} + +/** + * Try to post a callback-message to the tcpip_thread mbox + * This is intended to be used to send "static" messages from interrupt context. + * + * @param msg pointer to the message to post + * @return sys_mbox_trypost() return code + */ +err_t +tcpip_trycallback(struct tcpip_callback_msg* msg) +{ + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; + } + return sys_mbox_trypost(&mbox, msg); +} + /** * Initialize this module: * - initialize all sub modules diff --git a/reactos/lib/drivers/lwip/src/core/dhcp.c b/reactos/lib/drivers/lwip/src/core/dhcp.c index 81b4be271e9..eb12c550219 100644 --- a/reactos/lib/drivers/lwip/src/core/dhcp.c +++ b/reactos/lib/drivers/lwip/src/core/dhcp.c @@ -76,7 +76,6 @@ #include "lwip/ip_addr.h" #include "lwip/netif.h" #include "lwip/def.h" -#include "lwip/sys.h" #include "lwip/dhcp.h" #include "lwip/autoip.h" #include "lwip/dns.h" @@ -84,6 +83,13 @@ #include +/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using + * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) + */ +#ifndef DHCP_CREATE_RAND_XID +#define DHCP_CREATE_RAND_XID 1 +#endif + /** Default for DHCP_GLOBAL_XID is 0xABCD0000 * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. * #define DHCP_GLOBAL_XID_HEADER "stdlib.h" @@ -115,7 +121,7 @@ #define DHCP_OPTION_IDX_T2 5 #define DHCP_OPTION_IDX_SUBNET_MASK 6 #define DHCP_OPTION_IDX_ROUTER 7 -#define DHCP_OPTION_IDX_DNS_SERVER 8 +#define DHCP_OPTION_IDX_DNS_SERVER 8 #define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS) /** Holds the decoded option values, only valid while in dhcp_recv. @@ -126,6 +132,11 @@ u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX]; @todo: move this into struct dhcp? */ u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; +#ifdef DHCP_GLOBAL_XID +static u32_t xid; +static u8_t xid_initialised; +#endif /* DHCP_GLOBAL_XID */ + #define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0) #define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1) #define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0) @@ -164,6 +175,9 @@ static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len); static void dhcp_option_byte(struct dhcp *dhcp, u8_t value); static void dhcp_option_short(struct dhcp *dhcp, u16_t value); static void dhcp_option_long(struct dhcp *dhcp, u32_t value); +#if LWIP_NETIF_HOSTNAME +static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif); +#endif /* LWIP_NETIF_HOSTNAME */ /* always add the DHCP options trailer to end and pad */ static void dhcp_option_trailer(struct dhcp *dhcp); @@ -295,17 +309,7 @@ dhcp_select(struct netif *netif) dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); #if LWIP_NETIF_HOSTNAME - if (netif->hostname != NULL) { - const char *p = (const char*)netif->hostname; - u8_t namelen = (u8_t)strlen(p); - if (namelen > 0) { - LWIP_ASSERT("DHCP: hostname is too long!", namelen < 255); - dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, namelen); - while (*p) { - dhcp_option_byte(dhcp, *p++); - } - } - } + dhcp_option_hostname(dhcp, netif); #endif /* LWIP_NETIF_HOSTNAME */ dhcp_option_trailer(dhcp); @@ -676,7 +680,7 @@ dhcp_start(struct netif *netif) LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); return ERR_MEM; } - dhcp->pcb->so_options |= SOF_BROADCAST; + ip_set_option(dhcp->pcb, SOF_BROADCAST); /* set up local and remote port for the pcb */ udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); @@ -726,7 +730,7 @@ dhcp_inform(struct netif *netif) return; } dhcp.pcb = pcb; - dhcp.pcb->so_options |= SOF_BROADCAST; + ip_set_option(dhcp.pcb, SOF_BROADCAST); udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); } @@ -958,6 +962,11 @@ dhcp_bind(struct netif *netif) LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000)); } + /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */ + if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) { + dhcp->t1_timeout = 0; + } + if (dhcp->subnet_mask_given) { /* copy offered network mask */ ip_addr_copy(sn_mask, dhcp->offered_sn_mask); @@ -1024,20 +1033,6 @@ dhcp_renew(struct netif *netif) dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); -#if LWIP_NETIF_HOSTNAME - if (netif->hostname != NULL) { - const char *p = (const char*)netif->hostname; - u8_t namelen = (u8_t)strlen(p); - if (namelen > 0) { - LWIP_ASSERT("DHCP: hostname is too long!", namelen < 255); - dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, namelen); - while (*p) { - dhcp_option_byte(dhcp, *p++); - } - } - } -#endif /* LWIP_NETIF_HOSTNAME */ - #if 0 dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); @@ -1047,6 +1042,11 @@ dhcp_renew(struct netif *netif) dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); #endif + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + /* append DHCP message trailer */ dhcp_option_trailer(dhcp); @@ -1088,17 +1088,7 @@ dhcp_rebind(struct netif *netif) dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); #if LWIP_NETIF_HOSTNAME - if (netif->hostname != NULL) { - const char *p = (const char*)netif->hostname; - u8_t namelen = (u8_t)strlen(p); - if (namelen > 0) { - LWIP_ASSERT("DHCP: hostname is too long!", namelen < 255); - dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, namelen); - while (*p) { - dhcp_option_byte(dhcp, *p++); - } - } - } + dhcp_option_hostname(dhcp, netif); #endif /* LWIP_NETIF_HOSTNAME */ #if 0 @@ -1310,6 +1300,29 @@ dhcp_option_long(struct dhcp *dhcp, u32_t value) dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL)); } +#if LWIP_NETIF_HOSTNAME +static void +dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif) +{ + if (netif->hostname != NULL) { + size_t namelen = strlen(netif->hostname); + if (namelen > 0) { + u8_t len; + const char *p = netif->hostname; + /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME + and 1 byte for trailer) */ + size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3; + LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available); + len = LWIP_MIN(namelen, available); + dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, len); + while (len--) { + dhcp_option_byte(dhcp, *p++); + } + } + } +} +#endif /* LWIP_NETIF_HOSTNAME */ + /** * Extract the DHCP message and the DHCP options. * @@ -1387,44 +1400,44 @@ again: offset--; break; case(DHCP_OPTION_SUBNET_MASK): - LWIP_ASSERT("len == 4", len == 4); + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_SUBNET_MASK; break; case(DHCP_OPTION_ROUTER): decode_len = 4; /* only copy the first given router */ - LWIP_ASSERT("len >= decode_len", len >= decode_len); + LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_ROUTER; break; case(DHCP_OPTION_DNS_SERVER): /* special case: there might be more than one server */ - LWIP_ASSERT("len % 4 == 0", len % 4 == 0); + LWIP_ERROR("len % 4 == 0", len % 4 == 0, return ERR_VAL;); /* limit number of DNS servers */ decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS); - LWIP_ASSERT("len >= decode_len", len >= decode_len); + LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_DNS_SERVER; break; case(DHCP_OPTION_LEASE_TIME): - LWIP_ASSERT("len == 4", len == 4); + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_LEASE_TIME; break; case(DHCP_OPTION_OVERLOAD): - LWIP_ASSERT("len == 1", len == 1); + LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_OVERLOAD; break; case(DHCP_OPTION_MESSAGE_TYPE): - LWIP_ASSERT("len == 1", len == 1); + LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_MSG_TYPE; break; case(DHCP_OPTION_SERVER_ID): - LWIP_ASSERT("len == 4", len == 4); + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_SERVER_ID; break; case(DHCP_OPTION_T1): - LWIP_ASSERT("len == 4", len == 4); + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_T1; break; case(DHCP_OPTION_T2): - LWIP_ASSERT("len == 4", len == 4); + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); decode_idx = DHCP_OPTION_IDX_T2; break; default: @@ -1438,32 +1451,39 @@ again: u16_t copy_len; decode_next: LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX); - LWIP_ASSERT("option already decoded", !dhcp_option_given(dhcp, decode_idx)); - copy_len = LWIP_MIN(decode_len, 4); - pbuf_copy_partial(q, &value, copy_len, val_offset); - if (decode_len > 4) { - /* decode more than one u32_t */ - LWIP_ASSERT("decode_len % 4 == 0", decode_len % 4 == 0); + if (!dhcp_option_given(dhcp, decode_idx)) { + copy_len = LWIP_MIN(decode_len, 4); + pbuf_copy_partial(q, &value, copy_len, val_offset); + if (decode_len > 4) { + /* decode more than one u32_t */ + LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;); + dhcp_got_option(dhcp, decode_idx); + dhcp_set_option_value(dhcp, decode_idx, htonl(value)); + decode_len -= 4; + val_offset += 4; + decode_idx++; + goto decode_next; + } else if (decode_len == 4) { + value = ntohl(value); + } else { + LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;); + value = ((u8_t*)&value)[0]; + } dhcp_got_option(dhcp, decode_idx); - dhcp_set_option_value(dhcp, decode_idx, htonl(value)); - decode_len -= 4; - val_offset += 4; - decode_idx++; - goto decode_next; - } else if (decode_len == 4) { - value = ntohl(value); - } else { - LWIP_ASSERT("invalid decode_len", decode_len == 1); - value = ((u8_t*)&value)[0]; + dhcp_set_option_value(dhcp, decode_idx, value); } - dhcp_got_option(dhcp, decode_idx); - dhcp_set_option_value(dhcp, decode_idx, value); } if (offset >= q->len) { offset -= q->len; offset_max -= q->len; - q = q->next; - options = (u8_t*)q->payload; + if ((offset < offset_max) && offset_max) { + q = q->next; + LWIP_ASSERT("next pbuf was null", q); + options = (u8_t*)q->payload; + } else { + // We've run out of bytes, probably no end marker. Don't proceed. + break; + } } } /* is this an overloaded message? */ @@ -1626,10 +1646,12 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type) * with a packet analyser). We simply increment for each new request. * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ - static u32_t xid = 0xABCD0000; -#else +#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) static u32_t xid; - static u8_t xid_initialised = 0; +#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + static u32_t xid = 0xABCD0000; +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ +#else if (!xid_initialised) { xid = DHCP_GLOBAL_XID; xid_initialised = !xid_initialised; @@ -1650,7 +1672,11 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type) /* reuse transaction identifier in retransmissions */ if (dhcp->tries == 0) { - xid++; +#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) + xid = LWIP_RAND(); +#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + xid++; +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ } dhcp->xid = xid; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, @@ -1734,9 +1760,8 @@ dhcp_option_trailer(struct dhcp *dhcp) LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END; /* packet is too small, or not 4 byte aligned? */ - while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) { - /* LWIP_DEBUGF(DHCP_DEBUG,("dhcp_option_trailer:dhcp->options_out_len=%"U16_F", DHCP_OPTIONS_LEN=%"U16_F, dhcp->options_out_len, DHCP_OPTIONS_LEN)); */ - LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); + while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) && + (dhcp->options_out_len < DHCP_OPTIONS_LEN)) { /* add a fill/padding byte */ dhcp->msg_out->options[dhcp->options_out_len++] = 0; } diff --git a/reactos/lib/drivers/lwip/src/core/init.c b/reactos/lib/drivers/lwip/src/core/init.c index bf5c79da0d6..a7b15a776ab 100644 --- a/reactos/lib/drivers/lwip/src/core/init.c +++ b/reactos/lib/drivers/lwip/src/core/init.c @@ -56,6 +56,7 @@ #include "lwip/dns.h" #include "lwip/timers.h" #include "netif/etharp.h" +#include "lwip/api.h" /* Compile-time sanity checks for configuration errors. * These can be done independently of LWIP_DEBUG, without penalty. @@ -66,9 +67,6 @@ #if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" #endif -#if (!LWIP_ARP && ARP_QUEUEING) - #error "If you want to use ARP Queueing, you have to define LWIP_ARP=1 in your lwipopts.h" -#endif #if (!LWIP_UDP && LWIP_UDPLITE) #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" #endif @@ -87,6 +85,7 @@ #if (!LWIP_UDP && LWIP_DNS) #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" #endif +#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */ #if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" #endif @@ -99,6 +98,20 @@ #if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" #endif +#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) + #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" +#endif +#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) + #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" +#endif +/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ +#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT)) + #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" +#endif +#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) + #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" +#endif +#endif /* !MEMP_MEM_MALLOC */ #if (LWIP_TCP && (TCP_WND > 0xffff)) #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h" #endif @@ -114,18 +127,12 @@ #if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)) #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" #endif -#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) - #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" -#endif #if (LWIP_NETIF_API && (NO_SYS==1)) #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" #endif #if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" #endif -#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) - #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" -#endif #if (!LWIP_NETCONN && LWIP_SOCKET) #error "If you want to use Socket API, you have to define LWIP_NETCONN=1 in your lwipopts.h" #endif @@ -147,13 +154,6 @@ #if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" #endif -/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ -#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT)) - #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" -#endif -#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) - #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" -#endif #if (MEM_LIBC_MALLOC && MEM_USE_POOLS) #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" #endif @@ -163,9 +163,6 @@ #if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) #error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" #endif -#if (TCP_QUEUE_OOSEQ && !LWIP_TCP) - #error "TCP_QUEUE_OOSEQ requires LWIP_TCP" -#endif #if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" #endif @@ -187,6 +184,32 @@ #if IP_FRAG && IP_FRAG_USES_STATIC_BUF && LWIP_NETIF_TX_SINGLE_PBUF #error "LWIP_NETIF_TX_SINGLE_PBUF does not work with IP_FRAG_USES_STATIC_BUF==1 as that creates pbuf queues" #endif +#if LWIP_NETCONN && LWIP_TCP +#if NETCONN_COPY != TCP_WRITE_FLAG_COPY + #error "NETCONN_COPY != TCP_WRITE_FLAG_COPY" +#endif +#if NETCONN_MORE != TCP_WRITE_FLAG_MORE + #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE" +#endif +#endif /* LWIP_NETCONN && LWIP_TCP */ +#if LWIP_SOCKET +/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */ +#if SO_ACCEPTCONN != SOF_ACCEPTCONN + #error "SO_ACCEPTCONN != SOF_ACCEPTCONN" +#endif +#if SO_REUSEADDR != SOF_REUSEADDR + #error "WARNING: SO_REUSEADDR != SOF_REUSEADDR" +#endif +#if SO_KEEPALIVE != SOF_KEEPALIVE + #error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE" +#endif +#if SO_BROADCAST != SOF_BROADCAST + #error "WARNING: SO_BROADCAST != SOF_BROADCAST" +#endif +#if SO_LINGER != SOF_LINGER + #error "WARNING: SO_LINGER != SOF_LINGER" +#endif +#endif /* LWIP_SOCKET */ /* Compile-time checks for deprecated options. @@ -210,48 +233,54 @@ #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." #endif -#ifdef LWIP_DEBUG -static void -lwip_sanity_check(void) -{ - /* Warnings */ +#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS +#define LWIP_DISABLE_TCP_SANITY_CHECKS 0 +#endif +#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS +#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0 +#endif + +/* MEMP sanity checks */ +#if !LWIP_DISABLE_MEMP_SANITY_CHECKS #if LWIP_NETCONN - if (MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB)) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN\n")); +#if MEMP_MEM_MALLOC +#if !MEMP_NUM_NETCONN && LWIP_SOCKET +#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!" +#endif +#else /* MEMP_MEM_MALLOC */ +#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB) +#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error." +#endif +#endif /* MEMP_MEM_MALLOC */ #endif /* LWIP_NETCONN */ +#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */ + +/* TCP sanity checks */ +#if !LWIP_DISABLE_TCP_SANITY_CHECKS #if LWIP_TCP - if (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN\n")); - if (TCP_SND_BUF < 2 * TCP_MSS) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly\n")); - if (TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF/TCP_MSS))) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work\n")); - if (TCP_SNDLOWAT >= TCP_SND_BUF) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF.\n")); - if (TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN.\n")); - if (TCP_WND > (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE)) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE\n")); - if (TCP_WND < TCP_MSS) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is smaller than MSS\n")); +#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) + #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SND_BUF < (2 * TCP_MSS) + #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) + #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SNDLOWAT >= TCP_SND_BUF + #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN + #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if !MEMP_MEM_MALLOC && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) + #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_WND < TCP_MSS + #error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif #endif /* LWIP_TCP */ -#if LWIP_SOCKET - /* Check that the SO_* socket options and SOF_* lwIP-internal flags match */ - if (SO_ACCEPTCONN != SOF_ACCEPTCONN) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: SO_ACCEPTCONN != SOF_ACCEPTCONN\n")); - if (SO_REUSEADDR != SOF_REUSEADDR) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: SO_REUSEADDR != SOF_REUSEADDR\n")); - if (SO_KEEPALIVE != SOF_KEEPALIVE) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: SO_KEEPALIVE != SOF_KEEPALIVE\n")); - if (SO_BROADCAST != SOF_BROADCAST) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: SO_BROADCAST != SOF_BROADCAST\n")); - if (SO_LINGER != SOF_LINGER) - LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: SO_LINGER != SOF_LINGER\n")); -#endif /* LWIP_SOCKET */ -} -#else /* LWIP_DEBUG */ -#define lwip_sanity_check() -#endif /* LWIP_DEBUG */ +#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */ /** * Perform Sanity check of user-configurable values, and initialize all modules. @@ -259,9 +288,6 @@ lwip_sanity_check(void) void lwip_init(void) { - /* Sanity check user-configurable values */ - lwip_sanity_check(); - /* Modules initialization */ stats_init(); #if !NO_SYS diff --git a/reactos/lib/drivers/lwip/src/core/ipv4/autoip.c b/reactos/lib/drivers/lwip/src/core/ipv4/autoip.c index 92bb4591f1a..b122da27e3f 100644 --- a/reactos/lib/drivers/lwip/src/core/ipv4/autoip.c +++ b/reactos/lib/drivers/lwip/src/core/ipv4/autoip.c @@ -122,14 +122,6 @@ static err_t autoip_bind(struct netif *netif); /* start sending probes for llipaddr */ static void autoip_start_probing(struct netif *netif); -/** - * Initialize this module - */ -void -autoip_init(void) -{ - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_init()\n")); -} /** Set a statically allocated struct autoip to work with. * Using this prevents autoip_start to allocate it using mem_malloc. @@ -170,8 +162,8 @@ autoip_handle_arp_conflict(struct netif *netif) /* Somehow detect if we are defending or retreating */ unsigned char defend = 1; /* tbd */ - if(defend) { - if(netif->autoip->lastconflict > 0) { + if (defend) { + if (netif->autoip->lastconflict > 0) { /* retreat, there was a conflicting ARP in the last * DEFEND_INTERVAL seconds */ @@ -295,7 +287,7 @@ autoip_start(struct netif *netif) struct autoip *autoip = netif->autoip; err_t result = ERR_OK; - if(netif_is_up(netif)) { + if (netif_is_up(netif)) { netif_set_down(netif); } @@ -309,12 +301,12 @@ autoip_start(struct netif *netif) LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - if(autoip == NULL) { + if (autoip == NULL) { /* no AutoIP client attached yet? */ LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): starting new AUTOIP client\n")); autoip = (struct autoip *)mem_malloc(sizeof(struct autoip)); - if(autoip == NULL) { + if (autoip == NULL) { LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): could not allocate autoip\n")); return ERR_MEM; @@ -360,7 +352,7 @@ autoip_start_probing(struct netif *netif) * accquiring and probing address * compliant to RFC 3927 Section 2.2.1 */ - if(autoip->tried_llipaddr > MAX_CONFLICTS) { + if (autoip->tried_llipaddr > MAX_CONFLICTS) { autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; } } @@ -404,7 +396,7 @@ autoip_tmr() while (netif != NULL) { /* only act on AutoIP configured interfaces */ if (netif->autoip != NULL) { - if(netif->autoip->lastconflict > 0) { + if (netif->autoip->lastconflict > 0) { netif->autoip->lastconflict--; } @@ -414,10 +406,10 @@ autoip_tmr() switch(netif->autoip->state) { case AUTOIP_STATE_PROBING: - if(netif->autoip->ttw > 0) { + if (netif->autoip->ttw > 0) { netif->autoip->ttw--; } else { - if(netif->autoip->sent_num >= PROBE_NUM) { + if (netif->autoip->sent_num >= PROBE_NUM) { netif->autoip->state = AUTOIP_STATE_ANNOUNCING; netif->autoip->sent_num = 0; netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; @@ -439,10 +431,10 @@ autoip_tmr() break; case AUTOIP_STATE_ANNOUNCING: - if(netif->autoip->ttw > 0) { + if (netif->autoip->ttw > 0) { netif->autoip->ttw--; } else { - if(netif->autoip->sent_num == 0) { + if (netif->autoip->sent_num == 0) { /* We are here the first time, so we waited ANNOUNCE_WAIT seconds * Now we can bind to an IP address and use it. * @@ -458,7 +450,7 @@ autoip_tmr() netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; netif->autoip->sent_num++; - if(netif->autoip->sent_num >= ANNOUNCE_NUM) { + if (netif->autoip->sent_num >= ANNOUNCE_NUM) { netif->autoip->state = AUTOIP_STATE_BOUND; netif->autoip->sent_num = 0; netif->autoip->ttw = 0; diff --git a/reactos/lib/drivers/lwip/src/core/ipv4/icmp.c b/reactos/lib/drivers/lwip/src/core/ipv4/icmp.c index 32902a522ca..47ba857138d 100644 --- a/reactos/lib/drivers/lwip/src/core/ipv4/icmp.c +++ b/reactos/lib/drivers/lwip/src/core/ipv4/icmp.c @@ -190,12 +190,16 @@ icmp_input(struct pbuf *p, struct netif *inp) ip_addr_copy(iphdr->src, *ip_current_dest_addr()); ip_addr_copy(iphdr->dest, *ip_current_src_addr()); ICMPH_TYPE_SET(iecho, ICMP_ER); +#if CHECKSUM_GEN_ICMP /* adjust the checksum */ if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; } else { iecho->chksum += PP_HTONS(ICMP_ECHO << 8); } +#else /* CHECKSUM_GEN_ICMP */ + iecho->chksum = 0; +#endif /* CHECKSUM_GEN_ICMP */ /* Set the correct TTL and recalculate the header checksum. */ IPH_TTL_SET(iphdr, ICMP_TTL); diff --git a/reactos/lib/drivers/lwip/src/core/ipv4/igmp.c b/reactos/lib/drivers/lwip/src/core/ipv4/igmp.c index 4e4405e16f9..45bb5d95c29 100644 --- a/reactos/lib/drivers/lwip/src/core/ipv4/igmp.c +++ b/reactos/lib/drivers/lwip/src/core/ipv4/igmp.c @@ -139,7 +139,6 @@ static struct igmp_group *igmp_lookup_group(struct netif *ifp, ip_addr_t *addr); static err_t igmp_remove_group(struct igmp_group *group); static void igmp_timeout( struct igmp_group *group); static void igmp_start_timer(struct igmp_group *group, u8_t max_time); -static void igmp_stop_timer(struct igmp_group *group); static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp); static err_t igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif); static void igmp_send(struct igmp_group *group, u8_t type); @@ -706,17 +705,6 @@ igmp_start_timer(struct igmp_group *group, u8_t max_time) group->timer = (LWIP_RAND() % (max_time - 1)) + 1; } -/** - * Stop a timer for an igmp_group - * - * @param group the igmp_group for which to stop the timer - */ -static void -igmp_stop_timer(struct igmp_group *group) -{ - group->timer = 0; -} - /** * Delaying membership report for a group if necessary * diff --git a/reactos/lib/drivers/lwip/src/core/ipv4/ip.c b/reactos/lib/drivers/lwip/src/core/ipv4/ip.c index 6f248716b63..95d2db404c0 100644 --- a/reactos/lib/drivers/lwip/src/core/ipv4/ip.c +++ b/reactos/lib/drivers/lwip/src/core/ipv4/ip.c @@ -83,7 +83,7 @@ || (LWIP_IP_ACCEPT_UDP_PORT(port))) #elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ /* accept custom port only */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(dst_port)) +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) #else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ /* accept DHCP client port only */ #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) @@ -125,8 +125,15 @@ ip_route(ip_addr_t *dest) { struct netif *netif; +#ifdef LWIP_HOOK_IP4_ROUTE + netif = LWIP_HOOK_IP4_ROUTE(dest); + if (netif != NULL) { + return netif; + } +#endif + /* iterate through netifs */ - for(netif = netif_list; netif != NULL; netif = netif->next) { + for (netif = netif_list; netif != NULL; netif = netif->next) { /* network mask matches? */ if (netif_is_up(netif)) { if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { @@ -147,6 +154,41 @@ ip_route(ip_addr_t *dest) } #if IP_FORWARD +/** + * Determine whether an IP address is in a reserved set of addresses + * that may not be forwarded, or whether datagrams to that destination + * may be forwarded. + * @param p the packet to forward + * @param dest the destination IP address + * @return 1: can forward 0: discard + */ +static int +ip_canforward(struct pbuf *p) +{ + u32_t addr = ip4_addr_get_u32(ip_current_dest_addr()); + + if (p->flags & PBUF_FLAG_LLBCAST) { + /* don't route link-layer broadcasts */ + return 0; + } + if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) { + /* don't route link-layer multicasts unless the destination address is an IP + multicast address */ + return 0; + } + if (IP_EXPERIMENTAL(addr)) { + return 0; + } + if (IP_CLASSA(addr)) { + u32_t net = addr & IP_CLASSA_NET; + if ((net == 0) || (net == (IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) { + /* don't route loopback packets */ + return 0; + } + } + return 1; +} + /** * Forwards an IP packet. It finds an appropriate route for the * packet, decrements the TTL value of the packet, adjusts the @@ -163,6 +205,10 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) PERF_START; + if (!ip_canforward(p)) { + goto return_noroute; + } + /* RFC3927 2.7: do not forward link-local addresses */ if (ip_addr_islinklocal(¤t_iphdr_dest)) { LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", @@ -177,14 +223,17 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + /* @todo: send ICMP_DUR_NET? */ goto return_noroute; } +#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF /* Do not forward packets onto the same network interface on which * they arrived. */ if (netif == inp) { LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); goto return_noroute; } +#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */ /* decrement TTL */ IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); @@ -216,6 +265,20 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) snmp_inc_ipforwdatagrams(); PERF_STOP("ip_forward"); + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { +#if IP_FRAG + ip_frag(p, netif, ip_current_dest_addr()); +#else /* IP_FRAG */ + /* @todo: send ICMP Destination Unreacheable code 13 "Communication administratively prohibited"? */ +#endif /* IP_FRAG */ + } else { + /* send ICMP Destination Unreacheable code 4: "Fragmentation Needed and DF Set" */ + icmp_dest_unreach(p, ICMP_DUR_FRAG); + } + return; + } /* transmit pbuf on chosen interface */ netif->output(netif, p, ¤t_iphdr_dest); return; @@ -264,6 +327,13 @@ ip_input(struct pbuf *p, struct netif *inp) return ERR_OK; } +#ifdef LWIP_HOOK_IP4_INPUT + if (LWIP_HOOK_IP4_INPUT(p, inp)) { + /* the packet has been eaten */ + return ERR_OK; + } +#endif + /* obtain IP header length in number of 32-bit words */ iphdr_hlen = IPH_HL(iphdr); /* calculate IP header length in bytes */ @@ -488,7 +558,6 @@ ip_input(struct pbuf *p, struct netif *inp) if (raw_input(p, inp) == 0) #endif /* LWIP_RAW */ { - switch (IPH_PROTO(iphdr)) { #if LWIP_UDP case IP_PROTO_UDP: @@ -657,9 +726,10 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; #endif /* CHECKSUM_GEN_IP_INLINE */ - IPH_VHLTOS_SET(iphdr, 4, ip_hlen / 4, tos); + IPH_VHL_SET(iphdr, 4, ip_hlen / 4); + IPH_TOS_SET(iphdr, tos); #if CHECKSUM_GEN_IP_INLINE - chk_sum += iphdr->_v_hl_tos; + chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl); #endif /* CHECKSUM_GEN_IP_INLINE */ IPH_LEN_SET(iphdr, htons(p->tot_len)); #if CHECKSUM_GEN_IP_INLINE @@ -801,9 +871,9 @@ ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, return ERR_RTE; } - netif->addr_hint = addr_hint; + NETIF_SET_HWADDRHINT(netif, addr_hint); err = ip_output_if(p, src, dest, ttl, tos, proto, netif); - netif->addr_hint = NULL; + NETIF_SET_HWADDRHINT(netif, NULL); return err; } @@ -817,9 +887,6 @@ void ip_debug_print(struct pbuf *p) { struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; - u8_t *payload; - - payload = (u8_t *)iphdr + IP_HLEN; LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); diff --git a/reactos/lib/drivers/lwip/src/core/ipv6/ip6.c b/reactos/lib/drivers/lwip/src/core/ipv6/ip6.c index b945fc5d35d..ad59b725c0a 100644 --- a/reactos/lib/drivers/lwip/src/core/ipv6/ip6.c +++ b/reactos/lib/drivers/lwip/src/core/ipv6/ip6.c @@ -341,9 +341,9 @@ ip_output_hinted(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, return ERR_RTE; } - netif->addr_hint = addr_hint; + LWIP_NETIF_HWADDRHINT(netif, addr_hint); err = ip_output_if(p, src, dest, ttl, tos, proto, netif); - netif->addr_hint = NULL; + LWIP_NETIF_HWADDRHINT(netif, NULL); return err; } diff --git a/reactos/lib/drivers/lwip/src/core/mem.c b/reactos/lib/drivers/lwip/src/core/mem.c index 98375553b9e..1659a2c7a43 100644 --- a/reactos/lib/drivers/lwip/src/core/mem.c +++ b/reactos/lib/drivers/lwip/src/core/mem.c @@ -78,9 +78,10 @@ void * mem_malloc(mem_size_t size) { + void *ret; struct memp_malloc_helper *element; memp_t poolnr; - mem_size_t required_size = size + sizeof(struct memp_malloc_helper); + mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) { #if MEM_USE_POOLS_TRY_BIGGER_POOL @@ -113,9 +114,9 @@ again: /* save the pool number this element came from */ element->poolnr = poolnr; /* and return a pointer to the memory directly after the struct memp_malloc_helper */ - element++; + ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); - return element; + return ret; } /** @@ -128,13 +129,13 @@ again: void mem_free(void *rmem) { - struct memp_malloc_helper *hmem = (struct memp_malloc_helper*)rmem; + struct memp_malloc_helper *hmem; LWIP_ASSERT("rmem != NULL", (rmem != NULL)); LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); /* get the original struct memp_malloc_helper */ - hmem--; + hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))); LWIP_ASSERT("hmem != NULL", (hmem != NULL)); LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); @@ -190,7 +191,9 @@ static struct mem *ram_end; static struct mem *lfree; /** concurrent access protection */ +#if !NO_SYS static sys_mutex_t mem_mutex; +#endif #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT @@ -518,7 +521,7 @@ mem_malloc(mem_size_t size) sys_mutex_lock(&mem_mutex); LWIP_MEM_ALLOC_PROTECT(); #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - /* run as long as a mem_free disturbed mem_malloc */ + /* run as long as a mem_free disturbed mem_malloc or mem_trim */ do { local_mem_free_count = 0; #endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ @@ -532,12 +535,14 @@ mem_malloc(mem_size_t size) #if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT mem_free_count = 0; LWIP_MEM_ALLOC_UNPROTECT(); - /* allow mem_free to run */ + /* allow mem_free or mem_trim to run */ LWIP_MEM_ALLOC_PROTECT(); if (mem_free_count != 0) { - local_mem_free_count = mem_free_count; + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem. */ + local_mem_free_count = 1; + break; } - mem_free_count = 0; #endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ if ((!mem->used) && @@ -581,15 +586,27 @@ mem_malloc(mem_size_t size) mem->used = 1; MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); } - +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +mem_malloc_adjust_lfree: +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ if (mem == lfree) { + struct mem *cur = lfree; /* Find next free block after mem and update lowest free pointer */ - while (lfree->used && lfree != ram_end) { + while (cur->used && cur != ram_end) { +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 0; LWIP_MEM_ALLOC_UNPROTECT(); /* prevent high interrupt latency... */ LWIP_MEM_ALLOC_PROTECT(); - lfree = (struct mem *)(void *)&ram[lfree->next]; + if (mem_free_count != 0) { + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem or lfree. */ + goto mem_malloc_adjust_lfree; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + cur = (struct mem *)(void *)&ram[cur->next]; } + lfree = cur; LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); } LWIP_MEM_ALLOC_UNPROTECT(); diff --git a/reactos/lib/drivers/lwip/src/core/memp.c b/reactos/lib/drivers/lwip/src/core/memp.c index 4da879a57b4..9f680e244f9 100644 --- a/reactos/lib/drivers/lwip/src/core/memp.c +++ b/reactos/lib/drivers/lwip/src/core/memp.c @@ -176,19 +176,20 @@ static u8_t memp_memory[MEM_ALIGNMENT - 1 #if MEMP_SANITY_CHECK /** - * Check that memp-lists don't form a circle + * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm". */ static int memp_sanity(void) { - s16_t i, c; - struct memp *m, *n; + s16_t i; + struct memp *t, *h; for (i = 0; i < MEMP_MAX; i++) { - for (m = memp_tab[i]; m != NULL; m = m->next) { - c = 1; - for (n = memp_tab[i]; n != NULL; n = n->next) { - if (n == m && --c < 0) { + t = memp_tab[i]; + if(t != NULL) { + for (h = t->next; (t != NULL) && (h != NULL); t = t->next, + h = (((h->next != NULL) && (h->next->next != NULL)) ? h->next->next : NULL)) { + if (t == h) { return 0; } } diff --git a/reactos/lib/drivers/lwip/src/core/netif.c b/reactos/lib/drivers/lwip/src/core/netif.c index f190b1f2e03..4a02e77f31f 100644 --- a/reactos/lib/drivers/lwip/src/core/netif.c +++ b/reactos/lib/drivers/lwip/src/core/netif.c @@ -75,6 +75,8 @@ struct netif *netif_list; struct netif *netif_default; +static u8_t netif_num; + #if LWIP_HAVE_LOOPIF static struct netif loop_netif; @@ -137,7 +139,6 @@ struct netif * netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) { - static u8_t netifnum = 0; LWIP_ASSERT("No init function given", init != NULL); @@ -170,11 +171,9 @@ netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, /* remember netif specific state information data */ netif->state = state; - netif->num = netifnum++; + netif->num = netif_num++; netif->input = input; -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, NULL); #if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS netif->loop_cnt_current = 0; #endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ @@ -273,6 +272,11 @@ netif_remove(struct netif *netif) /* reset default netif */ netif_set_default(NULL); } +#if LWIP_NETIF_REMOVE_CALLBACK + if (netif->remove_callback) { + netif->remove_callback(netif); + } +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); } @@ -325,7 +329,7 @@ netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) struct tcp_pcb_listen *lpcb; /* address is actually being changed? */ - if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { + if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); pcb = tcp_active_pcbs; @@ -491,6 +495,11 @@ void netif_set_down(struct netif *netif) snmp_get_sysuptime(&netif->ts); #endif +#if LWIP_ARP + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_cleanup_netif(netif); + } +#endif /* LWIP_ARP */ NETIF_STATUS_CALLBACK(netif); } } @@ -507,6 +516,19 @@ void netif_set_status_callback(struct netif *netif, netif_status_callback_fn sta } #endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK +/** + * Set callback to be called when the interface has been removed + */ +void +netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback) +{ + if (netif) { + netif->remove_callback = remove_callback; + } +} +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + /** * Called by a driver when its link goes up */ diff --git a/reactos/lib/drivers/lwip/src/core/pbuf.c b/reactos/lib/drivers/lwip/src/core/pbuf.c index dd9ff64eef9..1e5e53b12a4 100644 --- a/reactos/lib/drivers/lwip/src/core/pbuf.c +++ b/reactos/lib/drivers/lwip/src/core/pbuf.c @@ -70,7 +70,7 @@ #include "lwip/pbuf.h" #include "lwip/sys.h" #include "arch/perf.h" -#if TCP_QUEUE_OOSEQ +#if LWIP_TCP && TCP_QUEUE_OOSEQ #include "lwip/tcp_impl.h" #endif #if LWIP_CHECKSUM_ON_COPY @@ -84,18 +84,25 @@ aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */ #define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) -#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || NO_SYS +#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ #define PBUF_POOL_IS_EMPTY() -#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || NO_SYS */ -/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ -#ifndef PBUF_POOL_FREE_OOSEQ -#define PBUF_POOL_FREE_OOSEQ 1 -#endif /* PBUF_POOL_FREE_OOSEQ */ +#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ -#if PBUF_POOL_FREE_OOSEQ +#if !NO_SYS +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL #include "lwip/tcpip.h" +#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \ + if(tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \ + SYS_ARCH_PROTECT(old_level); \ + pbuf_free_ooseq_pending = 0; \ + SYS_ARCH_UNPROTECT(old_level); \ + } } while(0) +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +#endif /* !NO_SYS */ + +volatile u8_t pbuf_free_ooseq_pending; #define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() -static u8_t pbuf_free_ooseq_queued; + /** * Attempt to reclaim some memory from queued out-of-sequence TCP segments * if we run out of pool pbufs. It's better to give priority to new packets @@ -104,15 +111,17 @@ static u8_t pbuf_free_ooseq_queued; * This must be done in the correct thread context therefore this function * can only be used with NO_SYS=0 and through tcpip_callback. */ -static void -pbuf_free_ooseq(void* arg) +#if !NO_SYS +static +#endif /* !NO_SYS */ +void +pbuf_free_ooseq(void) { struct tcp_pcb* pcb; SYS_ARCH_DECL_PROTECT(old_level); - LWIP_UNUSED_ARG(arg); SYS_ARCH_PROTECT(old_level); - pbuf_free_ooseq_queued = 0; + pbuf_free_ooseq_pending = 0; SYS_ARCH_UNPROTECT(old_level); for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { @@ -126,29 +135,42 @@ pbuf_free_ooseq(void* arg) } } +#if !NO_SYS +/** + * Just a callback function for tcpip_timeout() that calls pbuf_free_ooseq(). + */ +static void +pbuf_free_ooseq_callback(void *arg) +{ + LWIP_UNUSED_ARG(arg); + pbuf_free_ooseq(); +} +#endif /* !NO_SYS */ + /** Queue a call to pbuf_free_ooseq if not already queued. */ static void pbuf_pool_is_empty(void) { +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 1; + SYS_ARCH_UNPROTECT(old_level); +#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ u8_t queued; SYS_ARCH_DECL_PROTECT(old_level); - SYS_ARCH_PROTECT(old_level); - queued = pbuf_free_ooseq_queued; - pbuf_free_ooseq_queued = 1; + queued = pbuf_free_ooseq_pending; + pbuf_free_ooseq_pending = 1; SYS_ARCH_UNPROTECT(old_level); if(!queued) { /* queue a call to pbuf_free_ooseq if not already queued */ - if(tcpip_callback_with_block(pbuf_free_ooseq, NULL, 0) != ERR_OK) { - SYS_ARCH_PROTECT(old_level); - pbuf_free_ooseq_queued = 0; - SYS_ARCH_UNPROTECT(old_level); - } + PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); } +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ } -#endif /* PBUF_POOL_FREE_OOSEQ */ -#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || NO_SYS */ +#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ /** * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type). @@ -190,21 +212,21 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); /* determine header offset */ - offset = 0; switch (layer) { case PBUF_TRANSPORT: /* add room for transport (often TCP) layer header */ - offset += PBUF_TRANSPORT_HLEN; - /* FALLTHROUGH */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; case PBUF_IP: /* add room for IP layer header */ - offset += PBUF_IP_HLEN; - /* FALLTHROUGH */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; case PBUF_LINK: /* add room for link layer header */ - offset += PBUF_LINK_HLEN; + offset = PBUF_LINK_HLEN; break; case PBUF_RAW: + offset = 0; break; default: LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); @@ -336,7 +358,8 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) * @param p pointer to the custom pbuf to initialize (already allocated) * @param payload_mem pointer to the buffer that is used for payload and headers, * must be at least big enough to hold 'length' plus the header size, - * may be NULL if set later + * may be NULL if set later. + * ATTENTION: The caller is responsible for correct alignment of this buffer!! * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least * big enough to hold 'length' plus the header size */ @@ -348,35 +371,35 @@ pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_cust LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); /* determine header offset */ - offset = 0; switch (l) { case PBUF_TRANSPORT: /* add room for transport (often TCP) layer header */ - offset += PBUF_TRANSPORT_HLEN; - /* FALLTHROUGH */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; case PBUF_IP: /* add room for IP layer header */ - offset += PBUF_IP_HLEN; - /* FALLTHROUGH */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; case PBUF_LINK: /* add room for link layer header */ - offset += PBUF_LINK_HLEN; + offset = PBUF_LINK_HLEN; break; case PBUF_RAW: + offset = 0; break; default: LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); return NULL; } - if (LWIP_MEM_ALIGN_SIZE(offset) + length < payload_mem_len) { + if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); return NULL; } p->pbuf.next = NULL; if (payload_mem != NULL) { - p->pbuf.payload = LWIP_MEM_ALIGN((void *)((u8_t *)payload_mem + offset)); + p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); } else { p->pbuf.payload = NULL; } @@ -840,7 +863,6 @@ pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) /* iterate through pbuf chain */ do { - LWIP_ASSERT("p_to != NULL", p_to != NULL); /* copy one part of the original chain */ if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { /* complete current p_from fits into current p_to */ @@ -853,17 +875,18 @@ pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) offset_to += len; offset_from += len; LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); - if (offset_to == p_to->len) { - /* on to next p_to (if any) */ - offset_to = 0; - p_to = p_to->next; - } LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); if (offset_from >= p_from->len) { /* on to next p_from (if any) */ offset_from = 0; p_from = p_from->next; } + if (offset_to == p_to->len) { + /* on to next p_to (if any) */ + offset_to = 0; + p_to = p_to->next; + LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;); + } if((p_from != NULL) && (p_from->len == p_from->tot_len)) { /* don't copy more than one packet! */ diff --git a/reactos/lib/drivers/lwip/src/core/raw.c b/reactos/lib/drivers/lwip/src/core/raw.c index 9fcb100316d..7160c0fbd9c 100644 --- a/reactos/lib/drivers/lwip/src/core/raw.c +++ b/reactos/lib/drivers/lwip/src/core/raw.c @@ -95,7 +95,7 @@ raw_input(struct pbuf *p, struct netif *inp) ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest))) { #if IP_SOF_BROADCAST_RECV /* broadcast filter? */ - if ((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(¤t_iphdr_dest, inp)) + if (ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(¤t_iphdr_dest, inp)) #endif /* IP_SOF_BROADCAST_RECV */ { /* receive callback function available? */ @@ -245,7 +245,7 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) #if IP_SOF_BROADCAST /* broadcast filter? */ - if (((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif)) { + if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) { LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); /* free any temporary header pbuf allocated by pbuf_header() */ if (q != p) { @@ -263,13 +263,9 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) src_ip = &(pcb->local_ip); } -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = &(pcb->addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, NULL); /* did we chain a header earlier? */ if (q != p) { diff --git a/reactos/lib/drivers/lwip/src/core/snmp/mib2.c b/reactos/lib/drivers/lwip/src/core/snmp/mib2.c index 29decd306f3..4775ba9932e 100644 --- a/reactos/lib/drivers/lwip/src/core/snmp/mib2.c +++ b/reactos/lib/drivers/lwip/src/core/snmp/mib2.c @@ -73,7 +73,7 @@ #endif #ifndef SNMP_GET_SYSUPTIME -#define SNMP_GET_SYSUPTIME(sysuptime) +#define SNMP_GET_SYSUPTIME(sysuptime) (sysuptime = (sys_now() / 10)) #endif static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); diff --git a/reactos/lib/drivers/lwip/src/core/snmp/msg_in.c b/reactos/lib/drivers/lwip/src/core/snmp/msg_in.c index 2dfb55b253a..be940c62db9 100644 --- a/reactos/lib/drivers/lwip/src/core/snmp/msg_in.c +++ b/reactos/lib/drivers/lwip/src/core/snmp/msg_in.c @@ -90,7 +90,7 @@ snmp_init(void) trap_msg.pcb = snmp1_pcb; #ifdef SNMP_PRIVATE_MIB_INIT - /* If defined, rhis must be a function-like define to initialize the + /* If defined, this must be a function-like define to initialize the * private MIB after the stack has been initialized. * The private MIB can also be initialized in tcpip_callback (or after * the stack is initialized), this define is only for convenience. */ @@ -105,13 +105,28 @@ snmp_init(void) static void snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error) { + /* move names back from outvb to invb */ + int v; + struct snmp_varbind *vbi = msg_ps->invb.head; + struct snmp_varbind *vbo = msg_ps->outvb.head; + for (v=0; vvb_idx; v++) { + vbi->ident_len = vbo->ident_len; + vbo->ident_len = 0; + vbi->ident = vbo->ident; + vbo->ident = NULL; + vbi = vbi->next; + vbo = vbo->next; + } + /* free outvb */ snmp_varbind_list_free(&msg_ps->outvb); + /* we send invb back */ msg_ps->outvb = msg_ps->invb; msg_ps->invb.head = NULL; msg_ps->invb.tail = NULL; msg_ps->invb.count = 0; msg_ps->error_status = error; - msg_ps->error_index = 1 + msg_ps->vb_idx; + /* error index must be 0 for error too big */ + msg_ps->error_index = (error != SNMP_ES_TOOBIG) ? (1 + msg_ps->vb_idx) : 0; snmp_send_response(msg_ps); snmp_varbind_list_free(&msg_ps->outvb); msg_ps->state = SNMP_MSG_EMPTY; @@ -182,7 +197,6 @@ snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) /* allocate output varbind */ vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - LWIP_ASSERT("vb != NULL",vb != NULL); if (vb != NULL) { vb->next = NULL; @@ -202,7 +216,6 @@ snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) { LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); vb->value = memp_malloc(MEMP_SNMP_VALUE); - LWIP_ASSERT("vb->value != NULL",vb->value != NULL); if (vb->value != NULL) { en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); @@ -297,7 +310,6 @@ snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; /* allocate output varbind */ vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - LWIP_ASSERT("vb != NULL",vb != NULL); if (vb != NULL) { vb->next = NULL; @@ -318,7 +330,6 @@ snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); vb->value = memp_malloc(MEMP_SNMP_VALUE); - LWIP_ASSERT("vb->value != NULL",vb->value != NULL); if (vb->value != NULL) { mn->get_value(&object_def, vb->value_len, vb->value); @@ -331,6 +342,8 @@ snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n")); msg_ps->vb_ptr->ident = vb->ident; msg_ps->vb_ptr->ident_len = vb->ident_len; + vb->ident = NULL; + vb->ident_len = 0; memp_free(MEMP_SNMP_VARBIND, vb); snmp_error_response(msg_ps,SNMP_ES_TOOBIG); } @@ -1305,7 +1318,6 @@ snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) struct snmp_varbind *vb; vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); - LWIP_ASSERT("vb != NULL",vb != NULL); if (vb != NULL) { u8_t i; @@ -1319,9 +1331,9 @@ snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH); /* allocate array of s32_t for our object identifier */ vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE); - LWIP_ASSERT("vb->ident != NULL",vb->ident != NULL); if (vb->ident == NULL) { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate ident value space\n")); memp_free(MEMP_SNMP_VARBIND, vb); return NULL; } @@ -1343,9 +1355,9 @@ snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); /* allocate raw bytes for our object value */ vb->value = memp_malloc(MEMP_SNMP_VALUE); - LWIP_ASSERT("vb->value != NULL",vb->value != NULL); if (vb->value == NULL) { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate value space\n")); if (vb->ident != NULL) { memp_free(MEMP_SNMP_VALUE, vb->ident); @@ -1360,6 +1372,10 @@ snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) vb->value = NULL; } } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate varbind space\n")); + } return vb; } diff --git a/reactos/lib/drivers/lwip/src/core/snmp/msg_out.c b/reactos/lib/drivers/lwip/src/core/snmp/msg_out.c index f9e51c2c084..485f076a531 100644 --- a/reactos/lib/drivers/lwip/src/core/snmp/msg_out.c +++ b/reactos/lib/drivers/lwip/src/core/snmp/msg_out.c @@ -145,14 +145,7 @@ snmp_send_response(struct snmp_msg_pstat *m_stat) /* pass 1, size error, encode packet ino the pbuf(s) */ ofs = snmp_resp_header_enc(m_stat, p); - if (m_stat->error_status == SNMP_ES_TOOBIG) - { - snmp_varbind_list_enc(&emptyvb, p, ofs); - } - else - { - snmp_varbind_list_enc(&m_stat->outvb, p, ofs); - } + snmp_varbind_list_enc(&m_stat->outvb, p, ofs); switch (m_stat->error_status) { @@ -313,7 +306,7 @@ snmp_authfail_trap(void) * * @param vb_len varbind-list length * @param rhl points to returned header lengths - * @return the required length for encoding the response header + * @return the required lenght for encoding the response header */ static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len) @@ -360,7 +353,7 @@ snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len) * * @param vb_len varbind-list length * @param thl points to returned header lengths - * @return the required length for encoding the trap header + * @return the required lenght for encoding the trap header */ static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len) @@ -415,7 +408,7 @@ snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len) * annotates lengths in varbind for second encoding pass. * * @param root points to the root of the variable binding list - * @return the required length for encoding the variable bindings + * @return the required lenght for encoding the variable bindings */ static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root) @@ -429,7 +422,7 @@ snmp_varbind_list_sum(struct snmp_varbind_root *root) vb = root->tail; while ( vb != NULL ) { - /* encoded value length depends on type */ + /* encoded value lenght depends on type */ switch (vb->value_type) { case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): diff --git a/reactos/lib/drivers/lwip/src/core/stats.c b/reactos/lib/drivers/lwip/src/core/stats.c index 69f97d41fca..8ea82497674 100644 --- a/reactos/lib/drivers/lwip/src/core/stats.c +++ b/reactos/lib/drivers/lwip/src/core/stats.c @@ -69,7 +69,7 @@ void stats_init(void) #if LWIP_STATS_DISPLAY void -stats_display_proto(struct stats_proto *proto, char *name) +stats_display_proto(struct stats_proto *proto, const char *name) { LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); @@ -110,7 +110,7 @@ stats_display_igmp(struct stats_igmp *igmp) #if MEM_STATS || MEMP_STATS void -stats_display_mem(struct stats_mem *mem, char *name) +stats_display_mem(struct stats_mem *mem, const char *name) { LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name)); LWIP_PLATFORM_DIAG(("avail: %"U32_F"\n\t", (u32_t)mem->avail)); diff --git a/reactos/lib/drivers/lwip/src/core/sys.c b/reactos/lib/drivers/lwip/src/core/sys.c index d3a77deb289..f1777372621 100644 --- a/reactos/lib/drivers/lwip/src/core/sys.c +++ b/reactos/lib/drivers/lwip/src/core/sys.c @@ -45,6 +45,7 @@ #if !NO_SYS +#ifndef sys_msleep /** * Sleep for some ms. Timeouts are NOT processed while sleeping. * @@ -62,5 +63,6 @@ sys_msleep(u32_t ms) } } } +#endif /* sys_msleep */ #endif /* !NO_SYS */ diff --git a/reactos/lib/drivers/lwip/src/core/tcp.c b/reactos/lib/drivers/lwip/src/core/tcp.c index c629bc4e8ac..b710d2e2a46 100644 --- a/reactos/lib/drivers/lwip/src/core/tcp.c +++ b/reactos/lib/drivers/lwip/src/core/tcp.c @@ -55,6 +55,22 @@ #include +#ifndef TCP_LOCAL_PORT_RANGE_START +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define TCP_LOCAL_PORT_RANGE_START 0xc000 +#define TCP_LOCAL_PORT_RANGE_END 0xffff +#define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START) +#endif + +#if LWIP_TCP_KEEPALIVE +#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl) +#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl) +#else /* LWIP_TCP_KEEPALIVE */ +#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE +#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT +#endif /* LWIP_TCP_KEEPALIVE */ + const char * const tcp_state_str[] = { "CLOSED", "LISTEN", @@ -69,6 +85,9 @@ const char * const tcp_state_str[] = { "TIME_WAIT" }; +/* last local TCP port */ +static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; + /* Incremented every coarse grained timer shot (typically every 500 ms). */ u32_t tcp_ticks; const u8_t tcp_backoff[13] = @@ -97,13 +116,26 @@ struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcb /** Only used for temporary storage. */ struct tcp_pcb *tcp_tmp_pcb; +u8_t tcp_active_pcbs_changed; + /** Timer counter to handle calling slow-timer from tcp_tmr() */ static u8_t tcp_timer; +static u8_t tcp_timer_ctr; static u16_t tcp_new_port(void); +/** + * Initialize this module. + */ +void +tcp_init(void) +{ +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + /** * Called periodically to dispatch TCP timers. - * */ void tcp_tmr(void) @@ -139,7 +171,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) { err_t err; - if (rst_on_unacked_data && (pcb->state != LISTEN)) { + if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) { /* Not all data received by application, send RST to tell the remote side about this. */ @@ -151,14 +183,15 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) pcb->local_port, pcb->remote_port); tcp_pcb_purge(pcb); - - /* TODO: to which state do we move now? */ - - /* move to TIME_WAIT since we close actively */ - TCP_RMV(&tcp_active_pcbs, pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - + TCP_RMV_ACTIVE(pcb); + if (pcb->state == ESTABLISHED) { + /* move to TIME_WAIT since we close actively */ + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } else { + /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ + memp_free(MEMP_TCP_PCB, pcb); + } return ERR_OK; } } @@ -187,7 +220,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) break; case SYN_SENT: err = ERR_OK; - tcp_pcb_remove(&tcp_active_pcbs, pcb); + TCP_PCB_REMOVE_ACTIVE(pcb); memp_free(MEMP_TCP_PCB, pcb); pcb = NULL; snmp_inc_tcpattemptfails(); @@ -266,7 +299,9 @@ tcp_close(struct tcp_pcb *pcb) /** * Causes all or part of a full-duplex connection of this PCB to be shut down. - * This doesn't deallocate the PCB! + * This doesn't deallocate the PCB unless shutting down both sides! + * Shutting down both sides is the same as calling tcp_close, so if it succeds, + * the PCB should not be referenced any more. * * @param pcb PCB to shutdown * @param shut_rx shut down receive side if this is != 0 @@ -281,28 +316,32 @@ tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) return ERR_CONN; } if (shut_rx) { - /* shut down the receive side: free buffered data... */ + /* shut down the receive side: set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + if (shut_tx) { + /* shutting down the tx AND rx side is the same as closing for the raw API */ + return tcp_close_shutdown(pcb, 1); + } + /* ... and free buffered data */ if (pcb->refused_data != NULL) { pbuf_free(pcb->refused_data); pcb->refused_data = NULL; } - /* ... and set a flag not to receive any more data */ - pcb->flags |= TF_RXCLOSED; } if (shut_tx) { /* This can't happen twice since if it succeeds, the pcb's state is changed. Only close in these states as the others directly deallocate the PCB */ switch (pcb->state) { - case SYN_RCVD: - case ESTABLISHED: - case CLOSE_WAIT: - return tcp_close_shutdown(pcb, 0); - default: - /* don't shut down other states */ - break; + case SYN_RCVD: + case ESTABLISHED: + case CLOSE_WAIT: + return tcp_close_shutdown(pcb, shut_rx); + default: + /* Not (yet?) connected, cannot shutdown the TX side as that would bring us + into CLOSED state, where the PCB is deallocated. */ + return ERR_CONN; } } - /* @todo: return another err_t if not in correct state or already shut? */ return ERR_OK; } @@ -318,8 +357,6 @@ void tcp_abandon(struct tcp_pcb *pcb, int reset) { u32_t seqno, ackno; - u16_t remote_port, local_port; - ip_addr_t remote_ip, local_ip; #if LWIP_CALLBACK_API tcp_err_fn errf; #endif /* LWIP_CALLBACK_API */ @@ -337,15 +374,11 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) } else { seqno = pcb->snd_nxt; ackno = pcb->rcv_nxt; - ip_addr_copy(local_ip, pcb->local_ip); - ip_addr_copy(remote_ip, pcb->remote_ip); - local_port = pcb->local_port; - remote_port = pcb->remote_port; #if LWIP_CALLBACK_API errf = pcb->errf; #endif /* LWIP_CALLBACK_API */ errf_arg = pcb->callback_arg; - tcp_pcb_remove(&tcp_active_pcbs, pcb); + TCP_PCB_REMOVE_ACTIVE(pcb); if (pcb->unacked != NULL) { tcp_segs_free(pcb->unacked); } @@ -357,12 +390,12 @@ tcp_abandon(struct tcp_pcb *pcb, int reset) tcp_segs_free(pcb->ooseq); } #endif /* TCP_QUEUE_OOSEQ */ - memp_free(MEMP_TCP_PCB, pcb); - TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); if (reset) { LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); - tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port); + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); } + memp_free(MEMP_TCP_PCB, pcb); + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); } } @@ -411,13 +444,16 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) We do not dump TIME_WAIT pcb's; they can still be matched by incoming packets using both local and remote IP addresses and ports to distinguish. */ - if ((pcb->so_options & SOF_REUSEADDR) != 0) { + if (ip_get_option(pcb, SOF_REUSEADDR)) { max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; } #endif /* SO_REUSE */ if (port == 0) { port = tcp_new_port(); + if (port == 0) { + return ERR_BUF; + } } /* Check if the address already is in use (on all lists) */ @@ -428,8 +464,8 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) /* Omit checking for the same port if both pcbs have REUSEADDR set. For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in tcp_connect. */ - if (((pcb->so_options & SOF_REUSEADDR) == 0) || - ((cpcb->so_options & SOF_REUSEADDR) == 0)) + if (!ip_get_option(pcb, SOF_REUSEADDR) || + !ip_get_option(cpcb, SOF_REUSEADDR)) #endif /* SO_REUSE */ { if (ip_addr_isany(&(cpcb->local_ip)) || @@ -492,7 +528,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) return pcb; } #if SO_REUSE - if ((pcb->so_options & SOF_REUSEADDR) != 0) { + if (ip_get_option(pcb, SOF_REUSEADDR)) { /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage is declared (listen-/connection-pcb), we have to make sure now that this port is only used once for every local IP. */ @@ -515,7 +551,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) lpcb->state = LISTEN; lpcb->prio = pcb->prio; lpcb->so_options = pcb->so_options; - lpcb->so_options |= SOF_ACCEPTCONN; + ip_set_option(lpcb, SOF_ACCEPTCONN); lpcb->ttl = pcb->ttl; lpcb->tos = pcb->tos; ip_addr_copy(lpcb->local_ip, pcb->local_ip); @@ -576,6 +612,9 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) { int wnd_inflation; + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_recved for listen-pcbs", + pcb->state != LISTEN); LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", len <= 0xffff - pcb->rcv_wnd ); @@ -600,37 +639,33 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len) } /** - * A nastly hack featuring 'goto' statements that allocates a - * new TCP local port. + * Allocate a new local TCP port. * * @return a new (free) local TCP port number */ static u16_t tcp_new_port(void) { - int i; + u8_t i; + u16_t n = 0; struct tcp_pcb *pcb; -#ifndef TCP_LOCAL_PORT_RANGE_START -/* From http://www.iana.org/assignments/port-numbers: - "The Dynamic and/or Private Ports are those from 49152 through 65535" */ -#define TCP_LOCAL_PORT_RANGE_START 0xc000 -#define TCP_LOCAL_PORT_RANGE_END 0xffff -#endif - static u16_t port = TCP_LOCAL_PORT_RANGE_START; - again: - if (port++ >= TCP_LOCAL_PORT_RANGE_END) { - port = TCP_LOCAL_PORT_RANGE_START; +again: + if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) { + tcp_port = TCP_LOCAL_PORT_RANGE_START; } /* Check all PCB lists. */ for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { - if (pcb->local_port == port) { + if (pcb->local_port == tcp_port) { + if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { + return 0; + } goto again; } } } - return port; + return tcp_port; } /** @@ -679,9 +714,12 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, old_local_port = pcb->local_port; if (pcb->local_port == 0) { pcb->local_port = tcp_new_port(); + if (pcb->local_port == 0) { + return ERR_BUF; + } } #if SO_REUSE - if ((pcb->so_options & SOF_REUSEADDR) != 0) { + if (ip_get_option(pcb, SOF_REUSEADDR)) { /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure now that the 5-tuple is unique. */ struct tcp_pcb *cpcb; @@ -731,7 +769,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, if (old_local_port != 0) { TCP_RMV(&tcp_bound_pcbs, pcb); } - TCP_REG(&tcp_active_pcbs, pcb); + TCP_REG_ACTIVE(pcb); snmp_inc_tcpactiveopens(); tcp_output(pcb); @@ -758,7 +796,9 @@ tcp_slowtmr(void) err = ERR_OK; ++tcp_ticks; + ++tcp_timer_ctr; +tcp_slowtmr_start: /* Steps through all of the active PCBs. */ prev = NULL; pcb = tcp_active_pcbs; @@ -770,6 +810,12 @@ tcp_slowtmr(void) LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); + if (pcb->last_timer == tcp_timer_ctr) { + /* skip this pcb, we have already processed it */ + pcb = pcb->next; + continue; + } + pcb->last_timer = tcp_timer_ctr; pcb_remove = 0; pcb_reset = 0; @@ -795,8 +841,9 @@ tcp_slowtmr(void) } } else { /* Increase the retransmission timer if it is running */ - if(pcb->rtime >= 0) + if(pcb->rtime >= 0) { ++pcb->rtime; + } if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { /* Time for a retransmission. */ @@ -832,25 +879,24 @@ tcp_slowtmr(void) } /* Check if this PCB has stayed too long in FIN-WAIT-2 */ if (pcb->state == FIN_WAIT_2) { - if ((u32_t)(tcp_ticks - pcb->tmr) > - TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); + /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ + if (pcb->flags & TF_RXCLOSED) { + /* PCB was fully closed (either through close() or SHUT_RDWR): + normal FIN-WAIT timeout handling. */ + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); + } } } /* Check if KEEPALIVE should be sent */ - if((pcb->so_options & SOF_KEEPALIVE) && + if(ip_get_option(pcb, SOF_KEEPALIVE) && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { -#if LWIP_TCP_KEEPALIVE if((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl)) - / TCP_SLOW_INTERVAL) -#else - if((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL) -#endif /* LWIP_TCP_KEEPALIVE */ + (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) { LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), @@ -859,15 +905,9 @@ tcp_slowtmr(void) ++pcb_remove; ++pcb_reset; } -#if LWIP_TCP_KEEPALIVE else if((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl) + (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) / TCP_SLOW_INTERVAL) -#else - else if((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT) - / TCP_SLOW_INTERVAL) -#endif /* LWIP_TCP_KEEPALIVE */ { tcp_keepalive(pcb); pcb->keep_cnt_sent++; @@ -906,6 +946,8 @@ tcp_slowtmr(void) /* If the PCB should be removed, do it. */ if (pcb_remove) { struct tcp_pcb *pcb2; + tcp_err_fn err_fn; + void *err_arg; tcp_pcb_purge(pcb); /* Remove PCB from tcp_active_pcbs list. */ if (prev != NULL) { @@ -917,15 +959,22 @@ tcp_slowtmr(void) tcp_active_pcbs = pcb->next; } - TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT); if (pcb_reset) { tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); } + err_fn = pcb->errf; + err_arg = pcb->callback_arg; pcb2 = pcb; pcb = pcb->next; memp_free(MEMP_TCP_PCB, pcb2); + + tcp_active_pcbs_changed = 0; + TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT); + if (tcp_active_pcbs_changed) { + goto tcp_slowtmr_start; + } } else { /* get the 'next' element now and work with 'prev' below (in case of abort) */ prev = pcb; @@ -936,7 +985,11 @@ tcp_slowtmr(void) if (prev->polltmr >= prev->pollinterval) { prev->polltmr = 0; LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); + tcp_active_pcbs_changed = 0; TCP_EVENT_POLL(prev, err); + if (tcp_active_pcbs_changed) { + goto tcp_slowtmr_start; + } /* if err == ERR_ABRT, 'prev' is already deallocated */ if (err == ERR_OK) { tcp_output(prev); @@ -992,34 +1045,78 @@ tcp_slowtmr(void) void tcp_fasttmr(void) { - struct tcp_pcb *pcb = tcp_active_pcbs; + struct tcp_pcb *pcb; + + ++tcp_timer_ctr; + +tcp_fasttmr_start: + pcb = tcp_active_pcbs; while(pcb != NULL) { - struct tcp_pcb *next = pcb->next; - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - /* Notify again application with data previously received. */ - err_t err; - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n")); - TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err); - if (err == ERR_OK) { - pcb->refused_data = NULL; - } else if (err == ERR_ABRT) { - /* if err == ERR_ABRT, 'pcb' is already deallocated */ - pcb = NULL; + if (pcb->last_timer != tcp_timer_ctr) { + struct tcp_pcb *next; + pcb->last_timer = tcp_timer_ctr; + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + tcp_ack_now(pcb); + tcp_output(pcb); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + + next = pcb->next; + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + tcp_active_pcbs_changed = 0; + tcp_process_refused_data(pcb); + if (tcp_active_pcbs_changed) { + /* application callback has changed the pcb list: restart the loop */ + goto tcp_fasttmr_start; + } + } + pcb = next; + } + } +} + +/** Pass pcb->refused_data to the recv callback */ +err_t +tcp_process_refused_data(struct tcp_pcb *pcb) +{ + err_t err; + u8_t refused_flags = pcb->refused_data->flags; + /* set pcb->refused_data to NULL in case the callback frees it and then + closes the pcb */ + struct pbuf *refused_data = pcb->refused_data; + pcb->refused_data = NULL; + /* Notify again application with data previously received. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); + TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); + if (err == ERR_OK) { + /* did refused_data include a FIN? */ + if (refused_flags & PBUF_FLAG_TCP_FIN) { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + pcb->rcv_wnd++; + } + TCP_EVENT_CLOSED(pcb, err); + if (err == ERR_ABRT) { + return ERR_ABRT; } } - - /* send delayed ACKs */ - if (pcb && (pcb->flags & TF_ACK_DELAY)) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); - tcp_ack_now(pcb); - tcp_output(pcb); - pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); - } - - pcb = next; + } else if (err == ERR_ABRT) { + /* if err == ERR_ABRT, 'pcb' is already deallocated */ + /* Drop incoming packets because pcb is "full" (only if the incoming + segment contains data). */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); + return ERR_ABRT; + } else { + /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ + pcb->refused_data = refused_data; } + return ERR_OK; } /** @@ -1111,7 +1208,8 @@ tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) #endif /* LWIP_CALLBACK_API */ /** - * Kills the oldest active connection that has lower priority than prio. + * Kills the oldest active connection that has the same or lower priority than + * 'prio'. * * @param prio minimum priority */ @@ -1228,6 +1326,7 @@ tcp_alloc(u8_t prio) pcb->lastack = iss; pcb->snd_lbb = iss; pcb->tmr = tcp_ticks; + pcb->last_timer = tcp_timer_ctr; pcb->polltmr = 0; @@ -1275,7 +1374,9 @@ tcp_new(void) */ void tcp_arg(struct tcp_pcb *pcb, void *arg) -{ +{ + /* This function is allowed to be called for both listen pcbs and + connection pcbs. */ pcb->callback_arg = arg; } #if LWIP_CALLBACK_API @@ -1290,6 +1391,7 @@ tcp_arg(struct tcp_pcb *pcb, void *arg) void tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) { + LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN); pcb->recv = recv; } @@ -1303,6 +1405,7 @@ tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) void tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) { + LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN); pcb->sent = sent; } @@ -1317,6 +1420,7 @@ tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) void tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) { + LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN); pcb->errf = err; } @@ -1331,6 +1435,8 @@ tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) void tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) { + /* This function is allowed to be called for both listen pcbs and + connection pcbs. */ pcb->accept = accept; } #endif /* LWIP_CALLBACK_API */ @@ -1345,6 +1451,7 @@ tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) void tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval) { + LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN); #if LWIP_CALLBACK_API pcb->poll = poll; #else /* LWIP_CALLBACK_API */ diff --git a/reactos/lib/drivers/lwip/src/core/tcp_in.c b/reactos/lib/drivers/lwip/src/core/tcp_in.c index 302d336c73b..4ec971ac0fb 100644 --- a/reactos/lib/drivers/lwip/src/core/tcp_in.c +++ b/reactos/lib/drivers/lwip/src/core/tcp_in.c @@ -117,20 +117,14 @@ tcp_input(struct pbuf *p, struct netif *inp) /* drop short packets */ LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); TCP_STATS_INC(tcp.lenerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } /* Don't even process incoming broadcasts/multicasts. */ if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) || ip_addr_ismulticast(¤t_iphdr_dest)) { TCP_STATS_INC(tcp.proterr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } #if CHECKSUM_CHECK_TCP @@ -144,10 +138,7 @@ tcp_input(struct pbuf *p, struct netif *inp) tcp_debug_print(tcphdr); #endif /* TCP_DEBUG */ TCP_STATS_INC(tcp.chkerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } #endif @@ -158,10 +149,7 @@ tcp_input(struct pbuf *p, struct netif *inp) /* drop short packets */ LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); TCP_STATS_INC(tcp.lenerr); - TCP_STATS_INC(tcp.drop); - snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto dropped; } /* Convert fields in TCP header to host byte order. */ @@ -297,22 +285,19 @@ tcp_input(struct pbuf *p, struct netif *inp) recv_data = NULL; recv_flags = 0; + if (flags & TCP_PSH) { + p->flags |= PBUF_FLAG_PUSH; + } + /* If there is data which was previously "refused" by upper layer */ if (pcb->refused_data != NULL) { - /* Notify again application with data previously received. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); - TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err); - if (err == ERR_OK) { - pcb->refused_data = NULL; - } else if ((err == ERR_ABRT) || (tcplen > 0)) { - /* if err == ERR_ABRT, 'pcb' is already deallocated */ - /* Drop incoming packets because pcb is "full" (only if the incoming - segment contains data). */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); + if ((tcp_process_refused_data(pcb) == ERR_ABRT) || + ((pcb->refused_data != NULL) && (tcplen > 0))) { + /* pcb has been aborted or refused data is still refused and the new + segment contains data */ TCP_STATS_INC(tcp.drop); snmp_inc_tcpinerrs(); - pbuf_free(p); - return; + goto aborted; } } tcp_input_pcb = pcb; @@ -331,9 +316,11 @@ tcp_input(struct pbuf *p, struct netif *inp) } else if (recv_flags & TF_CLOSED) { /* The connection has been closed and we will deallocate the PCB. */ - TCP_EVENT_CLOSED(pcb, err); - if (err == ERR_ABRT) { - goto aborted; + if (!(pcb->flags & TF_RXCLOSED)) { + /* Connection closed although the application has only shut down the + tx side: call the PCB's err callback and indicate the closure to + ensure the application doesn't continue using the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD); } tcp_pcb_remove(&tcp_active_pcbs, pcb); memp_free(MEMP_TCP_PCB, pcb); @@ -358,9 +345,6 @@ tcp_input(struct pbuf *p, struct netif *inp) tcp_abort(pcb); goto aborted; } - if (flags & TCP_PSH) { - recv_data->flags |= PBUF_FLAG_PUSH; - } /* Notify application that data has been received. */ TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); @@ -378,14 +362,19 @@ tcp_input(struct pbuf *p, struct netif *inp) /* If a FIN segment was received, we call the callback function with a NULL buffer to indicate EOF. */ if (recv_flags & TF_GOT_FIN) { - /* correct rcv_wnd as the application won't call tcp_recved() - for the FIN's seqno */ - if (pcb->rcv_wnd != TCP_WND) { - pcb->rcv_wnd++; - } - TCP_EVENT_CLOSED(pcb, err); - if (err == ERR_ABRT) { - goto aborted; + if (pcb->refused_data != NULL) { + /* Delay this if we have refused data. */ + pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; + } else { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + pcb->rcv_wnd++; + } + TCP_EVENT_CLOSED(pcb, err); + if (err == ERR_ABRT) { + goto aborted; + } } } @@ -428,6 +417,11 @@ aborted: LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); PERF_STOP("tcp_input"); + return; +dropped: + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); } /** @@ -448,15 +442,19 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) struct tcp_pcb *npcb; err_t rc; + if (flags & TCP_RST) { + /* An incoming RST should be ignored. Return. */ + return ERR_OK; + } + /* In the LISTEN state, we check for incoming SYN segments, creates a new PCB, and responds with a SYN|ACK. */ if (flags & TCP_ACK) { /* For incoming segments with the ACK flag set, respond with a RST. */ LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); - tcp_rst(ackno + 1, seqno + tcplen, - ip_current_dest_addr(), ip_current_src_addr(), - tcphdr->dest, tcphdr->src); + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); } else if (flags & TCP_SYN) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); #if TCP_LISTEN_BACKLOG @@ -486,6 +484,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) npcb->rcv_nxt = seqno + 1; npcb->rcv_ann_right_edge = npcb->rcv_nxt; npcb->snd_wnd = tcphdr->wnd; + npcb->snd_wnd_max = tcphdr->wnd; npcb->ssthresh = npcb->snd_wnd; npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ npcb->callback_arg = pcb->callback_arg; @@ -496,7 +495,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) npcb->so_options = pcb->so_options & SOF_INHERITED; /* Register the new PCB so that we can begin receiving segments for it. */ - TCP_REG(&tcp_active_pcbs, npcb); + TCP_REG_ACTIVE(npcb); /* Parse any options in the SYN. */ tcp_parseopt(npcb); @@ -637,6 +636,7 @@ tcp_process(struct tcp_pcb *pcb) pcb->rcv_ann_right_edge = pcb->rcv_nxt; pcb->lastack = ackno; pcb->snd_wnd = tcphdr->wnd; + pcb->snd_wnd_max = tcphdr->wnd; pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ pcb->state = ESTABLISHED; @@ -654,6 +654,7 @@ tcp_process(struct tcp_pcb *pcb) LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); rseg = pcb->unacked; pcb->unacked = rseg->next; + tcp_seg_free(rseg); /* If there's nothing left to acknowledge, stop the retransmit timer, otherwise reset it to start again */ @@ -664,8 +665,6 @@ tcp_process(struct tcp_pcb *pcb) pcb->nrtx = 0; } - tcp_seg_free(rseg); - /* Call the user specified function to call when sucessfully * connected. */ TCP_EVENT_CONNECTED(pcb, ERR_OK, err); @@ -745,7 +744,7 @@ tcp_process(struct tcp_pcb *pcb) ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_ack_now(pcb); tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); + TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); } else { @@ -762,7 +761,7 @@ tcp_process(struct tcp_pcb *pcb) LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_ack_now(pcb); tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); + TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); } @@ -772,7 +771,7 @@ tcp_process(struct tcp_pcb *pcb) if (flags & TCP_ACK && ackno == pcb->snd_nxt) { LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); tcp_pcb_purge(pcb); - TCP_RMV(&tcp_active_pcbs, pcb); + TCP_RMV_ACTIVE(pcb); pcb->state = TIME_WAIT; TCP_REG(&tcp_tw_pcbs, pcb); } @@ -837,7 +836,7 @@ tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) * data, and if so frees the memory of the buffered data. Next, is places the * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until - * i it has been removed from the buffer. + * it has been removed from the buffer. * * If the incoming segment constitutes an ACK for a segment that was used for RTT * estimation, the RTT is estimated here as well. @@ -857,6 +856,12 @@ tcp_receive(struct tcp_pcb *pcb) u32_t right_wnd_edge; u16_t new_tot_len; int found_dupack = 0; +#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS + u32_t ooseq_blen; + u16_t ooseq_qlen; +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ + + LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); if (flags & TCP_ACK) { right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; @@ -866,9 +871,21 @@ tcp_receive(struct tcp_pcb *pcb) (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { pcb->snd_wnd = tcphdr->wnd; + /* keep track of the biggest window announced by the remote host to calculate + the maximum segment size */ + if (pcb->snd_wnd_max < tcphdr->wnd) { + pcb->snd_wnd_max = tcphdr->wnd; + } pcb->snd_wl1 = seqno; pcb->snd_wl2 = ackno; - if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) { + if (pcb->snd_wnd == 0) { + if (pcb->persist_backoff == 0) { + /* start persist timer */ + pcb->persist_cnt = 0; + pcb->persist_backoff = 1; + } + } else if (pcb->persist_backoff > 0) { + /* stop persist timer */ pcb->persist_backoff = 0; } LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd)); @@ -915,8 +932,9 @@ tcp_receive(struct tcp_pcb *pcb) /* Clause 5 */ if (pcb->lastack == ackno) { found_dupack = 1; - if (pcb->dupacks + 1 > pcb->dupacks) + if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { ++pcb->dupacks; + } if (pcb->dupacks > 3) { /* Inflate the congestion window, but not if it means that the value overflows. */ @@ -1043,6 +1061,11 @@ tcp_receive(struct tcp_pcb *pcb) next = pcb->unsent; pcb->unsent = pcb->unsent->next; +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); /* Prevent ACK for FIN to generate a sent event */ @@ -1091,8 +1114,10 @@ tcp_receive(struct tcp_pcb *pcb) } /* If the incoming segment contains data, we must process it - further. */ - if (tcplen > 0) { + further unless the pcb already received a FIN. + (RFC 793, chapeter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, + LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ + if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { /* This code basically does three things: +) If the incoming segment contains data that is the next @@ -1230,8 +1255,7 @@ tcp_receive(struct tcp_pcb *pcb) pcb->ooseq = pcb->ooseq->next; tcp_seg_free(old_ooseq); } - } - else { + } else { next = pcb->ooseq; /* Remove all segments on ooseq that are covered by inseg already. * FIN is copied from ooseq to inseg if present. */ @@ -1382,7 +1406,7 @@ tcp_receive(struct tcp_pcb *pcb) } break; } else { - /* Either the lengths are the same or the incoming + /* Either the lenghts are the same or the incoming segment was smaller than the old one; in either case, we ditch the incoming segment. */ break; @@ -1464,8 +1488,32 @@ tcp_receive(struct tcp_pcb *pcb) prev = next; } } +#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS + /* Check that the data on ooseq doesn't exceed one of the limits + and throw away everything above that limit. */ + ooseq_blen = 0; + ooseq_qlen = 0; + prev = NULL; + for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) { + struct pbuf *p = next->p; + ooseq_blen += p->tot_len; + ooseq_qlen += pbuf_clen(p); + if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) || + (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) { + /* too much ooseq data, dump this and everything after it */ + tcp_segs_free(next); + if (prev == NULL) { + /* first ooseq segment is too much, dump the whole queue */ + pcb->ooseq = NULL; + } else { + /* just dump 'next' and everything after it */ + prev->next = NULL; + } + break; + } + } +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ #endif /* TCP_QUEUE_OOSEQ */ - } } else { /* The incoming segment is not withing the window. */ diff --git a/reactos/lib/drivers/lwip/src/core/tcp_out.c b/reactos/lib/drivers/lwip/src/core/tcp_out.c index 83f7ec01583..ee19fe06f69 100644 --- a/reactos/lib/drivers/lwip/src/core/tcp_out.c +++ b/reactos/lib/drivers/lwip/src/core/tcp_out.c @@ -46,12 +46,14 @@ #include "lwip/def.h" #include "lwip/mem.h" #include "lwip/memp.h" -#include "lwip/sys.h" #include "lwip/ip_addr.h" #include "lwip/netif.h" #include "lwip/inet_chksum.h" #include "lwip/stats.h" #include "lwip/snmp.h" +#if LWIP_TCP_TIMESTAMPS +#include "lwip/sys.h" +#endif #include @@ -227,7 +229,7 @@ tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, LWIP_UNUSED_ARG(apiflags); LWIP_UNUSED_ARG(first_seg); /* always create MSS-sized pbufs */ - alloc = TCP_MSS; + alloc = max_length; #else /* LWIP_NETIF_TX_SINGLE_PBUF */ if (length < max_length) { /* Should we allocate an oversized pbuf, or just the minimum @@ -367,6 +369,8 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) u16_t concat_chksummed = 0; #endif /* TCP_CHECKSUM_ON_COPY */ err_t err; + /* don't allocate segments bigger than half the maximum window we ever received */ + u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2); #if LWIP_NETIF_TX_SINGLE_PBUF /* Always copy to try to create single pbufs for TX */ @@ -425,7 +429,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) /* Usable space at the end of the last unsent segment */ unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags); - space = pcb->mss - (last_unsent->len + unsent_optlen); + space = mss_local - (last_unsent->len + unsent_optlen); /* * Phase 1: Copy data directly into an oversized pbuf. @@ -476,7 +480,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) goto memerr; } #if TCP_OVERSIZE_DBGCHECK - last_unsent->oversize_left = oversize; + last_unsent->oversize_left += oversize; #endif /* TCP_OVERSIZE_DBGCHECK */ TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped); #if TCP_CHECKSUM_ON_COPY @@ -518,7 +522,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) while (pos < len) { struct pbuf *p; u16_t left = len - pos; - u16_t max_len = pcb->mss - optlen; + u16_t max_len = mss_local - optlen; u16_t seglen = left > max_len ? max_len : left; #if TCP_CHECKSUM_ON_COPY u16_t chksum = 0; @@ -528,7 +532,7 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) if (apiflags & TCP_WRITE_FLAG_COPY) { /* If copy is set, memory should be allocated and data copied * into pbuf */ - if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, pcb->mss, &oversize, pcb, apiflags, queue == NULL)) == NULL) { + if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) { LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); goto memerr; } @@ -631,6 +635,8 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) } last_unsent->len += oversize_used; #if TCP_OVERSIZE_DBGCHECK + LWIP_ASSERT("last_unsent->oversize_left >= oversize_used", + last_unsent->oversize_left >= oversize_used); last_unsent->oversize_left -= oversize_used; #endif /* TCP_OVERSIZE_DBGCHECK */ } @@ -811,7 +817,6 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) return ERR_OK; } - #if LWIP_TCP_TIMESTAMPS /* Build a timestamp option (12 bytes long) at the specified options pointer) @@ -898,6 +903,10 @@ tcp_output(struct tcp_pcb *pcb) s16_t i = 0; #endif /* TCP_CWND_DEBUG */ + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_output for listen-pcbs", + pcb->state != LISTEN); + /* First, check if we are invoked by the TCP input processing code. If so, we do not output anything. Instead, we rely on the input processing code to call us when input processing is done @@ -1026,13 +1035,6 @@ tcp_output(struct tcp_pcb *pcb) } #endif /* TCP_OVERSIZE */ - if (seg != NULL && pcb->persist_backoff == 0 && - ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) { - /* prepare for persist timer */ - pcb->persist_cnt = 0; - pcb->persist_backoff = 1; - } - pcb->flags &= ~TF_NAGLEMEMERR; return ERR_OK; } @@ -1064,10 +1066,15 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) /* Add any requested options. NB MSS option is only set on SYN packets, so ignore it here */ - LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0); opts = (u32_t *)(void *)(seg->tcphdr + 1); if (seg->flags & TF_SEG_OPTS_MSS) { - TCP_BUILD_MSS_OPTION(*opts); + u16_t mss; +#if TCP_CALCULATE_EFF_SEND_MSS + mss = tcp_eff_send_mss(TCP_MSS, &pcb->remote_ip); +#else /* TCP_CALCULATE_EFF_SEND_MSS */ + mss = TCP_MSS; +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + *opts = TCP_BUILD_MSS_OPTION(mss); opts += 1; } #if LWIP_TCP_TIMESTAMPS @@ -1245,6 +1252,7 @@ tcp_rexmit_rto(struct tcp_pcb *pcb) pcb->unsent = pcb->unacked; /* unacked queue is now empty */ pcb->unacked = NULL; + /* last unsent hasn't changed, no need to reset unsent_oversize */ /* increment number of retransmissions */ ++pcb->nrtx; @@ -1285,6 +1293,12 @@ tcp_rexmit(struct tcp_pcb *pcb) } seg->next = *cur_seg; *cur_seg = seg; +#if TCP_OVERSIZE + if (seg->next == NULL) { + /* the retransmitted segment is last in unsent, so reset unsent_oversize */ + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ ++pcb->nrtx; @@ -1441,9 +1455,11 @@ tcp_zero_window_probe(struct tcp_pcb *pcb) TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); } else { /* Data segment, copy in one byte from the head of the unacked queue */ - struct tcp_hdr *thdr = (struct tcp_hdr *)seg->p->payload; char *d = ((char *)p->payload + TCP_HLEN); - pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4); + /* Depending on whether the segment has already been sent (unacked) or not + (unsent), seg->p->payload points to the IP header or TCP header. + Ensure we copy the first TCP data byte: */ + pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); } #if CHECKSUM_GEN_TCP diff --git a/reactos/lib/drivers/lwip/src/core/timers.c b/reactos/lib/drivers/lwip/src/core/timers.c index f0e92ccebe7..e30846660af 100644 --- a/reactos/lib/drivers/lwip/src/core/timers.c +++ b/reactos/lib/drivers/lwip/src/core/timers.c @@ -56,6 +56,8 @@ #include "lwip/autoip.h" #include "lwip/igmp.h" #include "lwip/dns.h" +#include "lwip/sys.h" +#include "lwip/pbuf.h" /** The one and only timeout list */ @@ -355,22 +357,25 @@ sys_untimeout(sys_timeout_handler handler, void *arg) void sys_check_timeouts(void) { - struct sys_timeo *tmptimeout; - u32_t diff; - sys_timeout_handler handler; - void *arg; - int had_one; - u32_t now; - - now = sys_now(); if (next_timeout) { + struct sys_timeo *tmptimeout; + u32_t diff; + sys_timeout_handler handler; + void *arg; + u8_t had_one; + u32_t now; + + now = sys_now(); /* this cares for wraparounds */ - diff = LWIP_U32_DIFF(now, timeouts_last_time); + diff = now - timeouts_last_time; do { +#if PBUF_POOL_FREE_OOSEQ + PBUF_CHECK_FREE_OOSEQ(); +#endif /* PBUF_POOL_FREE_OOSEQ */ had_one = 0; tmptimeout = next_timeout; - if (tmptimeout->time <= diff) { + if (tmptimeout && (tmptimeout->time <= diff)) { /* timeout has expired */ had_one = 1; timeouts_last_time = now; diff --git a/reactos/lib/drivers/lwip/src/core/udp.c b/reactos/lib/drivers/lwip/src/core/udp.c index 4596ba2b79e..32c7d38403a 100644 --- a/reactos/lib/drivers/lwip/src/core/udp.c +++ b/reactos/lib/drivers/lwip/src/core/udp.c @@ -64,10 +64,77 @@ #include +#ifndef UDP_LOCAL_PORT_RANGE_START +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define UDP_LOCAL_PORT_RANGE_START 0xc000 +#define UDP_LOCAL_PORT_RANGE_END 0xffff +#define UDP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START) +#endif + +/* last local UDP port */ +static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; + /* The list of UDP PCBs */ /* exported in udp.h (was static) */ struct udp_pcb *udp_pcbs; +/** + * Initialize this module. + */ +void +udp_init(void) +{ +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + +/** + * Allocate a new local UDP port. + * + * @return a new (free) local UDP port number + */ +static u16_t +udp_new_port(void) +{ + u16_t n = 0; + struct udp_pcb *pcb; + +again: + if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { + udp_port = UDP_LOCAL_PORT_RANGE_START; + } + /* Check all PCBs. */ + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == udp_port) { + if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { + return 0; + } + goto again; + } + } + return udp_port; +#if 0 + struct udp_pcb *ipcb = udp_pcbs; + while ((ipcb != NULL) && (udp_port != UDP_LOCAL_PORT_RANGE_END)) { + if (ipcb->local_port == udp_port) { + /* port is already used by another udp_pcb */ + udp_port++; + /* restart scanning all udp pcbs */ + ipcb = udp_pcbs; + } else { + /* go on with next udp pcb */ + ipcb = ipcb->next; + } + } + if (ipcb != NULL) { + return 0; + } + return udp_port; +#endif +} + /** * Process an incoming UDP datagram. * @@ -171,22 +238,28 @@ udp_input(struct pbuf *p, struct netif *inp) ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip), pcb->remote_port)); /* compare PCB local addr+port to UDP destination addr+port */ - if ((pcb->local_port == dest) && - ((!broadcast && ip_addr_isany(&pcb->local_ip)) || + if (pcb->local_port == dest) { + if ( + (!broadcast && ip_addr_isany(&pcb->local_ip)) || ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest) || #if LWIP_IGMP ip_addr_ismulticast(¤t_iphdr_dest) || #endif /* LWIP_IGMP */ #if IP_SOF_BROADCAST_RECV - (broadcast && (pcb->so_options & SOF_BROADCAST)))) { -#else /* IP_SOF_BROADCAST_RECV */ - (broadcast))) { -#endif /* IP_SOF_BROADCAST_RECV */ - local_match = 1; - if ((uncon_pcb == NULL) && - ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { - /* the first unconnected matching PCB */ - uncon_pcb = pcb; + (broadcast && ip_get_option(pcb, SOF_BROADCAST) && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { +#endif /* IP_SOF_BROADCAST_RECV */ + local_match = 1; + if ((uncon_pcb == NULL) && + ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { + /* the first unconnected matching PCB */ + uncon_pcb = pcb; + } } } /* compare PCB remote addr+port to UDP source addr+port */ @@ -278,7 +351,7 @@ udp_input(struct pbuf *p, struct netif *inp) snmp_inc_udpindatagrams(); #if SO_REUSE && SO_REUSE_RXTOALL if ((broadcast || ip_addr_ismulticast(¤t_iphdr_dest)) && - ((pcb->so_options & SOF_REUSEADDR) != 0)) { + ip_get_option(pcb, SOF_REUSEADDR)) { /* pass broadcast- or multicast packets to all multicast pcbs if SOF_REUSEADDR is set on the first match */ struct udp_pcb *mpcb; @@ -293,7 +366,7 @@ udp_input(struct pbuf *p, struct netif *inp) ip_addr_ismulticast(¤t_iphdr_dest) || #endif /* LWIP_IGMP */ #if IP_SOF_BROADCAST_RECV - (broadcast && (mpcb->so_options & SOF_BROADCAST)))) { + (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))) { #else /* IP_SOF_BROADCAST_RECV */ (broadcast))) { #endif /* IP_SOF_BROADCAST_RECV */ @@ -494,7 +567,7 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, #if IP_SOF_BROADCAST /* broadcast filter? */ - if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(dst_ip, netif) ) { + if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(dst_ip, netif)) { LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); return ERR_VAL; @@ -616,13 +689,9 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, #endif /* CHECKSUM_GEN_UDP */ /* output to IP */ LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n")); -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = &(pcb->addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif); -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, NULL); } else #endif /* LWIP_UDPLITE */ { /* UDP */ @@ -655,13 +724,9 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n")); /* output to IP */ -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = &(pcb->addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif); -#if LWIP_NETIF_HWADDRHINT - netif->addr_hint = NULL; -#endif /* LWIP_NETIF_HWADDRHINT*/ + NETIF_SET_HWADDRHINT(netif, NULL); } /* TODO: must this be increased even if error occured? */ snmp_inc_udpoutdatagrams(); @@ -722,8 +787,8 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) PCB is alread bound to, unless *all* PCBs with that port have tha REUSEADDR flag set. */ #if SO_REUSE - else if (((pcb->so_options & SOF_REUSEADDR) == 0) && - ((ipcb->so_options & SOF_REUSEADDR) == 0)) { + else if (!ip_get_option(pcb, SOF_REUSEADDR) && + !ip_get_option(ipcb, SOF_REUSEADDR)) { #else /* SO_REUSE */ /* port matches that of PCB in list and REUSEADDR not set -> reject */ else { @@ -745,26 +810,8 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) /* no port specified? */ if (port == 0) { -#ifndef UDP_LOCAL_PORT_RANGE_START -/* From http://www.iana.org/assignments/port-numbers: - "The Dynamic and/or Private Ports are those from 49152 through 65535" */ -#define UDP_LOCAL_PORT_RANGE_START 0xc000 -#define UDP_LOCAL_PORT_RANGE_END 0xffff -#endif - port = UDP_LOCAL_PORT_RANGE_START; - ipcb = udp_pcbs; - while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) { - if (ipcb->local_port == port) { - /* port is already used by another udp_pcb */ - port++; - /* restart scanning all udp pcbs */ - ipcb = udp_pcbs; - } else { - /* go on with next udp pcb */ - ipcb = ipcb->next; - } - } - if (ipcb != NULL) { + port = udp_new_port(); + if (port == 0) { /* no more ports available in local range */ LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); return ERR_USE; diff --git a/reactos/lib/drivers/lwip/src/include/ipv4/lwip/autoip.h b/reactos/lib/drivers/lwip/src/include/ipv4/lwip/autoip.h index 23c264a1e04..e62b72e8cd8 100644 --- a/reactos/lib/drivers/lwip/src/include/ipv4/lwip/autoip.h +++ b/reactos/lib/drivers/lwip/src/include/ipv4/lwip/autoip.h @@ -89,8 +89,7 @@ struct autoip }; -/** Init srand, has to be called before entering mainloop */ -void autoip_init(void); +#define autoip_init() /* Compatibility define, no init needed. */ /** Set a struct autoip allocated by the application to work with */ void autoip_set_struct(struct netif *netif, struct autoip *autoip); diff --git a/reactos/lib/drivers/lwip/src/include/ipv4/lwip/ip.h b/reactos/lib/drivers/lwip/src/include/ipv4/lwip/ip.h index 74f501d1ab4..00c83a0a12a 100644 --- a/reactos/lib/drivers/lwip/src/include/ipv4/lwip/ip.h +++ b/reactos/lib/drivers/lwip/src/include/ipv4/lwip/ip.h @@ -94,16 +94,16 @@ struct ip_pcb { /* * Option flags per-socket. These are the same like SO_XXX. */ -/*#define SOF_DEBUG (u8_t)0x01U Unimplemented: turn on debugging info recording */ -#define SOF_ACCEPTCONN (u8_t)0x02U /* socket has had listen() */ -#define SOF_REUSEADDR (u8_t)0x04U /* allow local address reuse */ -#define SOF_KEEPALIVE (u8_t)0x08U /* keep connections alive */ -/*#define SOF_DONTROUTE (u8_t)0x10U Unimplemented: just use interface addresses */ -#define SOF_BROADCAST (u8_t)0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ -/*#define SOF_USELOOPBACK (u8_t)0x40U Unimplemented: bypass hardware when possible */ -#define SOF_LINGER (u8_t)0x80U /* linger on close if data present */ -/*#define SOF_OOBINLINE (u16_t)0x0100U Unimplemented: leave received OOB data in line */ -/*#define SOF_REUSEPORT (u16_t)0x0200U Unimplemented: allow local address & port reuse */ +/*#define SOF_DEBUG 0x01U Unimplemented: turn on debugging info recording */ +#define SOF_ACCEPTCONN 0x02U /* socket has had listen() */ +#define SOF_REUSEADDR 0x04U /* allow local address reuse */ +#define SOF_KEEPALIVE 0x08U /* keep connections alive */ +/*#define SOF_DONTROUTE 0x10U Unimplemented: just use interface addresses */ +#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +/*#define SOF_USELOOPBACK 0x40U Unimplemented: bypass hardware when possible */ +#define SOF_LINGER 0x80U /* linger on close if data present */ +/*#define SOF_OOBINLINE 0x0100U Unimplemented: leave received OOB data in line */ +/*#define SOF_REUSEPORT 0x0200U Unimplemented: allow local address & port reuse */ /* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ #define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/) @@ -114,8 +114,10 @@ struct ip_pcb { #endif PACK_STRUCT_BEGIN struct ip_hdr { - /* version / header length / type of service */ - PACK_STRUCT_FIELD(u16_t _v_hl_tos); + /* version / header length */ + PACK_STRUCT_FIELD(u8_t _v_hl); + /* type of service */ + PACK_STRUCT_FIELD(u8_t _tos); /* total length */ PACK_STRUCT_FIELD(u16_t _len); /* identification */ @@ -141,9 +143,9 @@ PACK_STRUCT_END # include "arch/epstruct.h" #endif -#define IPH_V(hdr) (ntohs((hdr)->_v_hl_tos) >> 12) -#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f) -#define IPH_TOS(hdr) (ntohs((hdr)->_v_hl_tos) & 0xff) +#define IPH_V(hdr) ((hdr)->_v_hl >> 4) +#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) +#define IPH_TOS(hdr) ((hdr)->_tos) #define IPH_LEN(hdr) ((hdr)->_len) #define IPH_ID(hdr) ((hdr)->_id) #define IPH_OFFSET(hdr) ((hdr)->_offset) @@ -151,7 +153,8 @@ PACK_STRUCT_END #define IPH_PROTO(hdr) ((hdr)->_proto) #define IPH_CHKSUM(hdr) ((hdr)->_chksum) -#define IPH_VHLTOS_SET(hdr, v, hl, tos) (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos))) +#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl)) +#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) #define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) #define IPH_ID_SET(hdr, id) (hdr)->_id = (id) #define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) @@ -198,6 +201,13 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, /** Destination IP address of current_header */ #define ip_current_dest_addr() (¤t_iphdr_dest) +/** Gets an IP pcb option (SOF_* flags) */ +#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) +/** Sets an IP pcb option (SOF_* flags) */ +#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) +/** Resets an IP pcb option (SOF_* flags) */ +#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) + #if IP_DEBUG void ip_debug_print(struct pbuf *p); #else diff --git a/reactos/lib/drivers/lwip/src/include/lwip/api.h b/reactos/lib/drivers/lwip/src/include/lwip/api.h index 91b9e5d2435..7a9fa9366c0 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/api.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/api.h @@ -159,6 +159,11 @@ struct netconn { #if LWIP_SOCKET int socket; #endif /* LWIP_SOCKET */ +#if LWIP_SO_SNDTIMEO + /** timeout to wait for sending data (which means enqueueing data for sending + in internal buffers) */ + s32_t send_timeout; +#endif /* LWIP_SO_RCVTIMEO */ #if LWIP_SO_RCVTIMEO /** timeout to wait for new data to be received (or connections to arrive for listening netconns) */ @@ -230,8 +235,10 @@ void netconn_recved(struct netconn *conn, u32_t length); err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port); err_t netconn_send(struct netconn *conn, struct netbuf *buf); -err_t netconn_write(struct netconn *conn, const void *dataptr, size_t size, - u8_t apiflags); +err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written); +#define netconn_write(conn, dataptr, size, apiflags) \ + netconn_write_partly(conn, dataptr, size, apiflags, NULL) err_t netconn_close(struct netconn *conn); err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); @@ -262,6 +269,12 @@ err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); /** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ #define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0) +#if LWIP_SO_SNDTIMEO +/** Set the send timeout in milliseconds */ +#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) +/** Get the send timeout in milliseconds */ +#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) +#endif /* LWIP_SO_SNDTIMEO */ #if LWIP_SO_RCVTIMEO /** Set the receive timeout in milliseconds */ #define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) diff --git a/reactos/lib/drivers/lwip/src/include/lwip/api_msg.h b/reactos/lib/drivers/lwip/src/include/lwip/api_msg.h index f99d8c3b719..f9e1c7d2954 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/api_msg.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/api_msg.h @@ -89,6 +89,9 @@ struct api_msg_msg { const void *dataptr; size_t len; u8_t apiflags; +#if LWIP_SO_SNDTIMEO + u32_t time_started; +#endif /* LWIP_SO_SNDTIMEO */ } w; /** used for do_recv */ struct { diff --git a/reactos/lib/drivers/lwip/src/include/lwip/arch.h b/reactos/lib/drivers/lwip/src/include/lwip/arch.h index 524af6be038..4d6df773fc3 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/arch.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/arch.h @@ -204,27 +204,6 @@ extern "C" { #define ENOMEDIUM 123 /* No medium found */ #define EMEDIUMTYPE 124 /* Wrong medium type */ - -#define ENSROK 0 /* DNS server returned answer with no data */ -#define ENSRNODATA 160 /* DNS server returned answer with no data */ -#define ENSRFORMERR 161 /* DNS server claims query was misformatted */ -#define ENSRSERVFAIL 162 /* DNS server returned general failure */ -#define ENSRNOTFOUND 163 /* Domain name not found */ -#define ENSRNOTIMP 164 /* DNS server does not implement requested operation */ -#define ENSRREFUSED 165 /* DNS server refused query */ -#define ENSRBADQUERY 166 /* Misformatted DNS query */ -#define ENSRBADNAME 167 /* Misformatted domain name */ -#define ENSRBADFAMILY 168 /* Unsupported address family */ -#define ENSRBADRESP 169 /* Misformatted DNS reply */ -#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */ -#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */ -#define ENSROF 172 /* End of file */ -#define ENSRFILE 173 /* Error reading file */ -#define ENSRNOMEM 174 /* Out of memory */ -#define ENSRDESTRUCTION 175 /* Application terminated lookup */ -#define ENSRQUERYDOMAINTOOLONG 176 /* Domain name is too long */ -#define ENSRCNAMELOOP 177 /* Domain name is too long */ - #ifndef errno extern int errno; #endif diff --git a/reactos/lib/drivers/lwip/src/include/lwip/debug.h b/reactos/lib/drivers/lwip/src/include/lwip/debug.h index d8359ea3a53..0fe041396fc 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/debug.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/debug.h @@ -33,6 +33,7 @@ #define __LWIP_DEBUG_H__ #include "lwip/arch.h" +#include "lwip/opt.h" /** lower two bits indicate debug level * - 0 all diff --git a/reactos/lib/drivers/lwip/src/include/lwip/def.h b/reactos/lib/drivers/lwip/src/include/lwip/def.h index 9b6de6a8b81..73a1b560b31 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/def.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/def.h @@ -47,10 +47,6 @@ extern "C" { #define NULL ((void *)0) #endif -/** Get the absolute difference between 2 u32_t values (correcting overflows) - * 'a' is expected to be 'higher' (without overflow) than 'b'. */ -#define LWIP_U32_DIFF(a, b) (((a) >= (b)) ? ((a) - (b)) : (((a) + ((b) ^ 0xFFFFFFFF) + 1))) - /* Endianess-optimized shifting of two u8_t to create one u16_t */ #if BYTE_ORDER == LITTLE_ENDIAN #define LWIP_MAKE_U16(a, b) ((a << 8) | b) diff --git a/reactos/lib/drivers/lwip/src/include/lwip/init.h b/reactos/lib/drivers/lwip/src/include/lwip/init.h index 77dcdfc7757..32385345429 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/init.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/init.h @@ -43,7 +43,7 @@ extern "C" { /** x.X.x: Minor version of the stack */ #define LWIP_VERSION_MINOR 4U /** x.x.X: Revision of the stack */ -#define LWIP_VERSION_REVISION 0U +#define LWIP_VERSION_REVISION 1U /** For release candidates, this is set to 1..254 * For official releases, this is set to 255 (LWIP_RC_RELEASE) * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ diff --git a/reactos/lib/drivers/lwip/src/include/lwip/mem.h b/reactos/lib/drivers/lwip/src/include/lwip/mem.h index 9507c0aec41..5bb906b63fe 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/mem.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/mem.h @@ -43,6 +43,7 @@ extern "C" { #include /* for size_t */ typedef size_t mem_size_t; +#define MEM_SIZE_F SZT_F /* aliases for C library malloc() */ #define mem_init() diff --git a/reactos/lib/drivers/lwip/src/include/lwip/memp_std.h b/reactos/lib/drivers/lwip/src/include/lwip/memp_std.h index 6ce408fb02a..461ed1acf8a 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/memp_std.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/memp_std.h @@ -63,9 +63,9 @@ LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), #endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ #endif /* NO_SYS==0 */ -#if ARP_QUEUEING +#if LWIP_ARP && ARP_QUEUEING LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") -#endif /* ARP_QUEUEING */ +#endif /* LWIP_ARP && ARP_QUEUEING */ #if LWIP_IGMP LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") diff --git a/reactos/lib/drivers/lwip/src/include/lwip/netif.h b/reactos/lib/drivers/lwip/src/include/lwip/netif.h index a8790b5f6a5..f7e4937453d 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/netif.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/netif.h @@ -163,6 +163,10 @@ struct netif { */ netif_status_callback_fn link_callback; #endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK + /** This function is called when the netif has been removed */ + netif_status_callback_fn remove_callback; +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ /** This field can be set by the device driver and could point * to state information for the device. */ void *state; @@ -280,6 +284,9 @@ void netif_set_down(struct netif *netif); #if LWIP_NETIF_STATUS_CALLBACK void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); #endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK +void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ void netif_set_link_up(struct netif *netif); void netif_set_link_down(struct netif *netif); @@ -308,6 +315,12 @@ void netif_poll_all(void); #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ #endif /* ENABLE_LOOPBACK */ +#if LWIP_NETIF_HWADDRHINT +#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) +#else /* LWIP_NETIF_HWADDRHINT */ +#define NETIF_SET_HWADDRHINT(netif, hint) +#endif /* LWIP_NETIF_HWADDRHINT */ + #ifdef __cplusplus } #endif diff --git a/reactos/lib/drivers/lwip/src/include/lwip/opt.h b/reactos/lib/drivers/lwip/src/include/lwip/opt.h index a1b876583f1..b8ebec86b15 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/opt.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/opt.h @@ -309,9 +309,11 @@ /** * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. * (requires NO_SYS==0) + * The default number of timeouts is calculated here for all enabled modules. + * The formula expects settings to be either '0' or '1'. */ #ifndef MEMP_NUM_SYS_TIMEOUT -#define MEMP_NUM_SYS_TIMEOUT 3 +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT) #endif /** @@ -461,6 +463,8 @@ * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) + * that returns 1 to accept a packet or 0 to drop a packet. */ #ifndef ETHARP_SUPPORT_VLAN #define ETHARP_SUPPORT_VLAN 0 @@ -593,6 +597,26 @@ #define IP_SOF_BROADCAST_RECV 0 #endif +/** + * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back + * out on the netif where it was received. This should only be used for + * wireless networks. + * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming + * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! + */ +#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF +#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 +#endif + +/** + * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first + * local TCP/UDP pcb (default==0). This can prevent creating predictable port + * numbers after booting a device. + */ +#ifndef LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS +#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 +#endif + /* ---------------------------------- ---------- ICMP options ---------- @@ -946,10 +970,11 @@ /** - * TCP_SND_BUF: TCP sender buffer space (bytes). + * TCP_SND_BUF: TCP sender buffer space (bytes). + * To achieve good performance, this should be at least 2 * TCP_MSS. */ #ifndef TCP_SND_BUF -#define TCP_SND_BUF 256 +#define TCP_SND_BUF (2 * TCP_MSS) #endif /** @@ -966,16 +991,32 @@ * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). */ #ifndef TCP_SNDLOWAT -#define TCP_SNDLOWAT ((TCP_SND_BUF)/2) +#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) #endif /** - * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be grater + * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below * this number, select returns writable (combined with TCP_SNDLOWAT). */ #ifndef TCP_SNDQUEUELOWAT -#define TCP_SNDQUEUELOWAT ((TCP_SND_QUEUELEN)/2) +#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#endif + +/** + * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_BYTES +#define TCP_OOSEQ_MAX_BYTES 0 +#endif + +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_PBUFS +#define TCP_OOSEQ_MAX_PBUFS 0 #endif /** @@ -1032,14 +1073,11 @@ * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all * events (accept, sent, etc) that happen in the system. * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. + * for the event. This is the default. */ -#ifndef LWIP_EVENT_API +#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) #define LWIP_EVENT_API 0 #define LWIP_CALLBACK_API 1 -#else -#define LWIP_EVENT_API 1 -#define LWIP_CALLBACK_API 0 #endif @@ -1102,6 +1140,14 @@ #define LWIP_NETIF_LINK_CALLBACK 0 #endif +/** + * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called + * when a netif has been removed + */ +#ifndef LWIP_NETIF_REMOVE_CALLBACK +#define LWIP_NETIF_REMOVE_CALLBACK 0 +#endif + /** * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table * indices) in struct netif. TCP and UDP can make use of this to prevent @@ -1407,7 +1453,16 @@ #endif /** - * LWIP_SO_RCVTIMEO==1: Enable SO_RCVTIMEO processing. + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#ifndef LWIP_SO_SNDTIMEO +#define LWIP_SO_SNDTIMEO 0 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. */ #ifndef LWIP_SO_RCVTIMEO #define LWIP_SO_RCVTIMEO 0 @@ -1749,6 +1804,13 @@ #ifndef CHECKSUM_GEN_TCP #define CHECKSUM_GEN_TCP 1 #endif + +/** + * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. + */ +#ifndef CHECKSUM_GEN_ICMP +#define CHECKSUM_GEN_ICMP 1 +#endif /** * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. @@ -1779,6 +1841,34 @@ #define LWIP_CHECKSUM_ON_COPY 0 #endif +/* + --------------------------------------- + ---------- Hook options --------------- + --------------------------------------- +*/ + +/* Hooks are undefined by default, define them to a function if you need them. */ + +/** + * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): + * - called from ip_input() (IPv4) + * - pbuf: received struct pbuf passed to ip_input() + * - input_netif: struct netif on which the packet has been received + * Return values: + * - 0: Hook has not consumed the packet, packet is processed as normal + * - != 0: Hook has consumed the packet. + * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook + * (i.e. free it when done). + */ + +/** + * LWIP_HOOK_IP4_ROUTE(dest): + * - called from ip_route() (IPv4) + * - dest: destination IPv4 address + * Returns the destination netif or NULL if no destination netif is found. In + * that case, ip_route() continues as normal. + */ + /* --------------------------------------- ---------- Debugging options ---------- diff --git a/reactos/lib/drivers/lwip/src/include/lwip/pbuf.h b/reactos/lib/drivers/lwip/src/include/lwip/pbuf.h index 3b1d608b9cb..99d5443bf36 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/pbuf.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/pbuf.h @@ -69,6 +69,12 @@ typedef enum { #define PBUF_FLAG_IS_CUSTOM 0x02U /** indicates this pbuf is UDP multicast to be looped back */ #define PBUF_FLAG_MCASTLOOP 0x04U +/** indicates this pbuf was received as link-level broadcast */ +#define PBUF_FLAG_LLBCAST 0x08U +/** indicates this pbuf was received as link-level multicast */ +#define PBUF_FLAG_LLMCAST 0x10U +/** indicates this pbuf includes a TCP FIN flag */ +#define PBUF_FLAG_TCP_FIN 0x20U struct pbuf { /** next pbuf in singly linked pbuf chain */ @@ -116,6 +122,24 @@ struct pbuf_custom { }; #endif /* LWIP_SUPPORT_CUSTOM_PBUF */ +#if LWIP_TCP && TCP_QUEUE_OOSEQ +/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ +#ifndef PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_FREE_OOSEQ 1 +#endif /* PBUF_POOL_FREE_OOSEQ */ +#if NO_SYS && PBUF_POOL_FREE_OOSEQ +extern volatile u8_t pbuf_free_ooseq_pending; +void pbuf_free_ooseq(); +/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level to check if ooseq pbufs need to be + freed! */ +#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ + /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ + ooseq queued pbufs now */ \ + pbuf_free_ooseq(); }}while(0) +#endif /* NO_SYS && PBUF_POOL_FREE_OOSEQ*/ +#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ */ + /* Initializes the pbuf module. This call is empty for now, but may not be in future. */ #define pbuf_init() diff --git a/reactos/lib/drivers/lwip/src/include/lwip/sockets.h b/reactos/lib/drivers/lwip/src/include/lwip/sockets.h index 3c8fed24e6e..3ea32f13fba 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/sockets.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/sockets.h @@ -62,8 +62,10 @@ struct sockaddr { char sa_data[14]; }; -#ifndef socklen_t -# define socklen_t u32_t +/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) +typedef u32_t socklen_t; #endif /* Socket protocol types (TCP/UDP/RAW) */ @@ -363,6 +365,7 @@ int lwip_fcntl(int s, int cmd, int val); #define read(a,b,c) lwip_read(a,b,c) #define write(a,b,c) lwip_write(a,b,c) #define close(s) lwip_close(s) +#define fcntl(a,b,c) lwip_fcntl(a,b,c) #endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ #endif /* LWIP_COMPAT_SOCKETS */ diff --git a/reactos/lib/drivers/lwip/src/include/lwip/stats.h b/reactos/lib/drivers/lwip/src/include/lwip/stats.h index 015b7ce79d8..1f5152a9491 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/stats.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/stats.h @@ -271,9 +271,9 @@ void stats_init(void); /* Display of statistics */ #if LWIP_STATS_DISPLAY void stats_display(void); -void stats_display_proto(struct stats_proto *proto, char *name); +void stats_display_proto(struct stats_proto *proto, const char *name); void stats_display_igmp(struct stats_igmp *igmp); -void stats_display_mem(struct stats_mem *mem, char *name); +void stats_display_mem(struct stats_mem *mem, const char *name); void stats_display_memp(struct stats_mem *mem, int index); void stats_display_sys(struct stats_sys *sys); #else /* LWIP_STATS_DISPLAY */ diff --git a/reactos/lib/drivers/lwip/src/include/lwip/sys.h b/reactos/lib/drivers/lwip/src/include/lwip/sys.h index 9f62c7540e6..dc9351335a9 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/sys.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/sys.h @@ -51,16 +51,22 @@ typedef u8_t sys_mbox_t; #define sys_sem_wait(s) #define sys_arch_sem_wait(s,t) #define sys_sem_free(s) +#define sys_sem_valid(s) 0 +#define sys_sem_set_invalid(s) #define sys_mutex_new(mu) ERR_OK #define sys_mutex_lock(mu) #define sys_mutex_unlock(mu) #define sys_mutex_free(mu) +#define sys_mutex_valid(mu) 0 +#define sys_mutex_set_invalid(mu) #define sys_mbox_new(m, s) ERR_OK #define sys_mbox_fetch(m,d) #define sys_mbox_tryfetch(m,d) #define sys_mbox_post(m,d) #define sys_mbox_trypost(m,d) #define sys_mbox_free(m) +#define sys_mbox_valid(m) +#define sys_mbox_set_invalid(m) #define sys_thread_new(n,t,a,s,p) diff --git a/reactos/lib/drivers/lwip/src/include/lwip/tcp.h b/reactos/lib/drivers/lwip/src/include/lwip/tcp.h index 07dcd10e786..c6e61ad1f1b 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/tcp.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/tcp.h @@ -36,7 +36,6 @@ #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ -#include "lwip/sys.h" #include "lwip/mem.h" #include "lwip/pbuf.h" #include "lwip/ip.h" @@ -156,11 +155,11 @@ enum tcp_state { */ #define TCP_PCB_COMMON(type) \ type *next; /* for the linked list */ \ - enum tcp_state state; /* TCP state */ \ - u8_t prio; \ void *callback_arg; \ /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \ DEF_ACCEPT_CALLBACK \ + enum tcp_state state; /* TCP state */ \ + u8_t prio; \ /* ports are in host byte order */ \ u16_t local_port @@ -187,21 +186,23 @@ struct tcp_pcb { /* the rest of the fields are in host byte order as we have to do some math with them */ + + /* Timers */ + u8_t polltmr, pollinterval; + u8_t last_timer; + u32_t tmr; + /* receiver variables */ u32_t rcv_nxt; /* next seqno expected */ u16_t rcv_wnd; /* receiver window available */ u16_t rcv_ann_wnd; /* receiver window to announce */ u32_t rcv_ann_right_edge; /* announced right edge of window */ - /* Timers */ - u32_t tmr; - u8_t polltmr, pollinterval; - /* Retransmission timer. */ s16_t rtime; - + u16_t mss; /* maximum segment size */ - + /* RTT (round trip time) estimation variables */ u32_t rttest; /* RTT estimate in 500ms ticks */ u32_t rtseq; /* sequence number being timed */ @@ -211,22 +212,23 @@ struct tcp_pcb { u8_t nrtx; /* number of retransmissions */ /* fast retransmit/recovery */ - u32_t lastack; /* Highest acknowledged seqno. */ u8_t dupacks; - + u32_t lastack; /* Highest acknowledged seqno. */ + /* congestion avoidance/control variables */ - u16_t cwnd; + u16_t cwnd; u16_t ssthresh; /* sender variables */ u32_t snd_nxt; /* next new seqno to be sent */ - u16_t snd_wnd; /* sender window */ u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last window update. */ u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ + u16_t snd_wnd; /* sender window */ + u16_t snd_wnd_max; /* the maximum sender window announced by the remote host */ u16_t acked; - + u16_t snd_buf; /* Available buffer space for sending (in bytes). */ #define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */ @@ -271,7 +273,7 @@ struct tcp_pcb { #endif /* LWIP_TCP_KEEPALIVE */ /* Persist timer counter */ - u32_t persist_cnt; + u8_t persist_cnt; /* Persist timer back-off */ u8_t persist_backoff; @@ -333,7 +335,7 @@ void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0) #else /* TCP_LISTEN_BACKLOG */ #define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \ - pcb->state == LISTEN) + (pcb)->state == LISTEN) #endif /* TCP_LISTEN_BACKLOG */ void tcp_recved (struct tcp_pcb *pcb, u16_t len); diff --git a/reactos/lib/drivers/lwip/src/include/lwip/tcp_impl.h b/reactos/lib/drivers/lwip/src/include/lwip/tcp_impl.h index b4feec0da19..173de44e444 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/tcp_impl.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/tcp_impl.h @@ -37,7 +37,6 @@ #if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ #include "lwip/tcp.h" -#include "lwip/sys.h" #include "lwip/mem.h" #include "lwip/pbuf.h" #include "lwip/ip.h" @@ -51,7 +50,7 @@ extern "C" { /* Functions for interfacing with TCP: */ /* Lower layer interface to TCP: */ -#define tcp_init() /* Compatibility define, no init needed. */ +void tcp_init (void); /* Initialize this module. */ void tcp_tmr (void); /* Must be called every TCP_TMR_INTERVAL ms. (Typically 250 ms). */ @@ -71,6 +70,7 @@ void tcp_rexmit (struct tcp_pcb *pcb); void tcp_rexmit_rto (struct tcp_pcb *pcb); void tcp_rexmit_fast (struct tcp_pcb *pcb); u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); +err_t tcp_process_refused_data(struct tcp_pcb *pcb); /** * This is the Nagle algorithm: try to combine user data to send as few TCP @@ -84,15 +84,16 @@ u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); #define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ - ((tpcb)->unsent->len >= (tpcb)->mss))) \ + ((tpcb)->unsent->len >= (tpcb)->mss))) || \ + ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ ) ? 1 : 0) #define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) -#define TCP_SEQ_LT(a,b) ((s32_t)((a)-(b)) < 0) -#define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0) -#define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0) -#define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0) +#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) +#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) +#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) +#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) /* is b<=a<=c? */ #if 0 /* see bug #10548 */ #define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) @@ -170,11 +171,9 @@ PACK_STRUCT_END # include "arch/epstruct.h" #endif -#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8) #define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) #define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) -#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr)) #define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) #define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) #define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) @@ -301,14 +300,12 @@ struct tcp_seg { (flags & TF_SEG_OPTS_TS ? 12 : 0) /** This returns a TCP header option for MSS in an u32_t */ -#define TCP_BUILD_MSS_OPTION(x) (x) = PP_HTONL(((u32_t)2 << 24) | \ - ((u32_t)4 << 16) | \ - (((u32_t)TCP_MSS / 256) << 8) | \ - (TCP_MSS & 255)) +#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) /* Global variables: */ extern struct tcp_pcb *tcp_input_pcb; extern u32_t tcp_ticks; +extern u8_t tcp_active_pcbs_changed; /* The TCP PCB lists. */ union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ @@ -395,6 +392,24 @@ extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ #endif /* LWIP_DEBUG */ +#define TCP_REG_ACTIVE(npcb) \ + do { \ + TCP_REG(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_RMV_ACTIVE(npcb) \ + do { \ + TCP_RMV(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_PCB_REMOVE_ACTIVE(pcb) \ + do { \ + tcp_pcb_remove(&tcp_active_pcbs, pcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + /* Internal functions: */ struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); diff --git a/reactos/lib/drivers/lwip/src/include/lwip/tcpip.h b/reactos/lib/drivers/lwip/src/include/lwip/tcpip.h index 995ba8ad007..637476e1a90 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/tcpip.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/tcpip.h @@ -77,6 +77,9 @@ typedef void (*tcpip_init_done_fn)(void *arg); /** Function prototype for functions passed to tcpip_callback() */ typedef void (*tcpip_callback_fn)(void *ctx); +/* Forward declarations */ +struct tcpip_callback_msg; + void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); #if LWIP_NETCONN @@ -98,6 +101,10 @@ err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); #define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); +err_t tcpip_trycallback(struct tcpip_callback_msg* msg); + /* free pbufs or heap memory from another context without blocking */ err_t pbuf_free_callback(struct pbuf *p); err_t mem_free_callback(void *m); @@ -119,7 +126,8 @@ enum tcpip_msg_type { TCPIP_MSG_TIMEOUT, TCPIP_MSG_UNTIMEOUT, #endif /* LWIP_TCPIP_TIMEOUT */ - TCPIP_MSG_CALLBACK + TCPIP_MSG_CALLBACK, + TCPIP_MSG_CALLBACK_STATIC }; struct tcpip_msg { diff --git a/reactos/lib/drivers/lwip/src/include/lwip/timers.h b/reactos/lib/drivers/lwip/src/include/lwip/timers.h index fb92b4b47c5..04e78e0feab 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/timers.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/timers.h @@ -41,7 +41,9 @@ #if LWIP_TIMERS #include "lwip/err.h" +#if !NO_SYS #include "lwip/sys.h" +#endif #ifdef __cplusplus extern "C" { diff --git a/reactos/lib/drivers/lwip/src/include/lwip/udp.h b/reactos/lib/drivers/lwip/src/include/lwip/udp.h index c98c1b3ec14..f1e6d3f1e4f 100644 --- a/reactos/lib/drivers/lwip/src/include/lwip/udp.h +++ b/reactos/lib/drivers/lwip/src/include/lwip/udp.h @@ -154,7 +154,7 @@ err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, /* The following functions are the lower layer interface to UDP. */ void udp_input (struct pbuf *p, struct netif *inp); -#define udp_init() /* Compatibility define, not init needed. */ +void udp_init (void); #if UDP_DEBUG void udp_debug_print(struct udp_hdr *udphdr); diff --git a/reactos/lib/drivers/lwip/src/include/netif/etharp.h b/reactos/lib/drivers/lwip/src/include/netif/etharp.h index 691575fa130..859608df912 100644 --- a/reactos/lib/drivers/lwip/src/include/netif/etharp.h +++ b/reactos/lib/drivers/lwip/src/include/netif/etharp.h @@ -190,6 +190,7 @@ err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr); * nodes to update an entry in their ARP cache. * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ #define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr) +void etharp_cleanup_netif(struct netif *netif); #if ETHARP_SUPPORT_STATIC_ENTRIES err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr); diff --git a/reactos/lib/drivers/lwip/src/include/netif/slipif.h b/reactos/lib/drivers/lwip/src/include/netif/slipif.h index ccd03c8a16b..7b6ce5e28f5 100644 --- a/reactos/lib/drivers/lwip/src/include/netif/slipif.h +++ b/reactos/lib/drivers/lwip/src/include/netif/slipif.h @@ -34,14 +34,44 @@ #ifndef __NETIF_SLIPIF_H__ #define __NETIF_SLIPIF_H__ +#include "lwip/opt.h" #include "lwip/netif.h" +/** Set this to 1 to start a thread that blocks reading on the serial line + * (using sio_read()). + */ +#ifndef SLIP_USE_RX_THREAD +#define SLIP_USE_RX_THREAD !NO_SYS +#endif + +/** Set this to 1 to enable functions to pass in RX bytes from ISR context. + * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled + * packets on a queue, which is fed into lwIP from slipif_poll(). + * If disabled, slipif_poll() polls the serila line (using sio_tryread()). + */ +#ifndef SLIP_RX_FROM_ISR +#define SLIP_RX_FROM_ISR 0 +#endif + +/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets + * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. + * If disabled, packets will be dropped if more than one packet is received. + */ +#ifndef SLIP_RX_QUEUE +#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR +#endif + #ifdef __cplusplus extern "C" { #endif err_t slipif_init(struct netif * netif); void slipif_poll(struct netif *netif); +#if SLIP_RX_FROM_ISR +void slipif_process_rxqueue(struct netif *netif); +void slipif_received_byte(struct netif *netif, u8_t data); +void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); +#endif /* SLIP_RX_FROM_ISR */ #ifdef __cplusplus } diff --git a/reactos/lib/drivers/lwip/src/netif/etharp.c b/reactos/lib/drivers/lwip/src/netif/etharp.c index b60dadd0244..5e382d1d60e 100644 --- a/reactos/lib/drivers/lwip/src/netif/etharp.c +++ b/reactos/lib/drivers/lwip/src/netif/etharp.c @@ -65,13 +65,22 @@ const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; const struct eth_addr ethzero = {{0,0,0,0,0,0}}; +/** The 24-bit IANA multicast OUI is 01-00-5e: */ +#define LL_MULTICAST_ADDR_0 0x01 +#define LL_MULTICAST_ADDR_1 0x00 +#define LL_MULTICAST_ADDR_2 0x5e + #if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ /** the time an ARP entry stays valid after its last update, * for ARP_TMR_INTERVAL = 5000, this is * (240 * 5) seconds = 20 minutes. */ -#define ARP_MAXAGE 240 +#define ARP_MAXAGE 240 +/** Re-request a used ARP entry 1 minute before it would expire to prevent + * breaking a steadily used connection because the ARP entry timed out. */ +#define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12) + /** the time an ARP entry stays pending after first request, * for ARP_TMR_INTERVAL = 5000, this is * (2 * 5) seconds = 10 seconds. @@ -86,7 +95,11 @@ const struct eth_addr ethzero = {{0,0,0,0,0,0}}; enum etharp_state { ETHARP_STATE_EMPTY = 0, ETHARP_STATE_PENDING, - ETHARP_STATE_STABLE + ETHARP_STATE_STABLE, + ETHARP_STATE_STABLE_REREQUESTING +#if ETHARP_SUPPORT_STATIC_ENTRIES + ,ETHARP_STATE_STATIC +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ }; struct etharp_entry { @@ -98,15 +111,10 @@ struct etharp_entry { struct pbuf *q; #endif /* ARP_QUEUEING */ ip_addr_t ipaddr; - struct eth_addr ethaddr; -#if LWIP_SNMP struct netif *netif; -#endif /* LWIP_SNMP */ + struct eth_addr ethaddr; u8_t state; u8_t ctime; -#if ETHARP_SUPPORT_STATIC_ENTRIES - u8_t static_entry; -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ }; static struct etharp_entry arp_table[ARP_TABLE_SIZE]; @@ -119,7 +127,9 @@ static u8_t etharp_cached_entry; the cache (even if this means removing an active entry or so). */ #define ETHARP_FLAG_TRY_HARD 1 #define ETHARP_FLAG_FIND_ONLY 2 +#if ETHARP_SUPPORT_STATIC_ENTRIES #define ETHARP_FLAG_STATIC_ENTRY 4 +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ #if LWIP_NETIF_HWADDRHINT #define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ @@ -128,8 +138,6 @@ static u8_t etharp_cached_entry; #define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) #endif /* LWIP_NETIF_HWADDRHINT */ -static err_t update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags); - /* Some checks, instead of etharp_init(): */ #if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) @@ -166,28 +174,23 @@ free_etharp_q(struct etharp_q_entry *q) /** Clean up ARP table entries */ static void -free_entry(int i) +etharp_free_entry(int i) { /* remove from SNMP ARP index tree */ snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); /* and empty packet queue */ if (arp_table[i].q != NULL) { /* remove all queued packets */ - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); free_etharp_q(arp_table[i].q); arp_table[i].q = NULL; } - /* recycle entry for re-use */ + /* recycle entry for re-use */ arp_table[i].state = ETHARP_STATE_EMPTY; -#if ETHARP_SUPPORT_STATIC_ENTRIES - arp_table[i].static_entry = 0; -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ #ifdef LWIP_DEBUG /* for debugging, clean out the complete entry */ arp_table[i].ctime = 0; -#if LWIP_SNMP arp_table[i].netif = NULL; -#endif /* LWIP_SNMP */ ip_addr_set_zero(&arp_table[i].ipaddr); arp_table[i].ethaddr = ethzero; #endif /* LWIP_DEBUG */ @@ -210,7 +213,7 @@ etharp_tmr(void) u8_t state = arp_table[i].state; if (state != ETHARP_STATE_EMPTY #if ETHARP_SUPPORT_STATIC_ENTRIES - && (arp_table[i].static_entry == 0) + && (state != ETHARP_STATE_STATIC) #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ ) { arp_table[i].ctime++; @@ -219,9 +222,14 @@ etharp_tmr(void) (arp_table[i].ctime >= ARP_MAXPENDING))) { /* pending or stable entry has become old! */ LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", - arp_table[i].state == ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); + arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); /* clean up entries that have just been expired */ - free_entry(i); + etharp_free_entry(i); + } + else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) { + /* Reset state to stable, so that the next transmitted packet will + re-send an ARP request. */ + arp_table[i].state = ETHARP_STATE_STABLE; } #if ARP_QUEUEING /* still pending entry? (not expired) */ @@ -255,7 +263,7 @@ etharp_tmr(void) * entry is found or could be recycled. */ static s8_t -find_entry(ip_addr_t *ipaddr, u8_t flags) +etharp_find_entry(ip_addr_t *ipaddr, u8_t flags) { s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; s8_t empty = ARP_TABLE_SIZE; @@ -284,15 +292,15 @@ find_entry(ip_addr_t *ipaddr, u8_t flags) u8_t state = arp_table[i].state; /* no empty entry found yet and now we do find one? */ if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { - LWIP_DEBUGF(ETHARP_DEBUG, ("find_entry: found empty entry %"U16_F"\n", (u16_t)i)); + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i)); /* remember first empty entry */ empty = i; } else if (state != ETHARP_STATE_EMPTY) { - LWIP_ASSERT("state == ETHARP_STATE_PENDING || state == ETHARP_STATE_STABLE", - state == ETHARP_STATE_PENDING || state == ETHARP_STATE_STABLE); + LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", + state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); /* if given, does IP address match IP address in ARP entry? */ if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching entry %"U16_F"\n", (u16_t)i)); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i)); /* found exact IP address match, simply bail out */ return i; } @@ -313,10 +321,10 @@ find_entry(ip_addr_t *ipaddr, u8_t flags) } } /* stable entry? */ - } else if (state == ETHARP_STATE_STABLE) { + } else if (state >= ETHARP_STATE_STABLE) { #if ETHARP_SUPPORT_STATIC_ENTRIES /* don't record old_stable for static entries since they never expire */ - if (arp_table[i].static_entry == 0) + if (state < ETHARP_STATE_STATIC) #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ { /* remember entry with oldest stable entry in oldest, its age in maxtime */ @@ -334,7 +342,7 @@ find_entry(ip_addr_t *ipaddr, u8_t flags) if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || /* or no empty entry found and not allowed to recycle? */ ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty entry found and not allowed to recycle\n")); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); return (s8_t)ERR_MEM; } @@ -350,34 +358,34 @@ find_entry(ip_addr_t *ipaddr, u8_t flags) /* 1) empty entry available? */ if (empty < ARP_TABLE_SIZE) { i = empty; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); } else { /* 2) found recyclable stable entry? */ if (old_stable < ARP_TABLE_SIZE) { /* recycle oldest stable*/ i = old_stable; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); /* no queued packets should exist on stable entries */ LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); /* 3) found recyclable pending entry without queued packets? */ } else if (old_pending < ARP_TABLE_SIZE) { /* recycle oldest pending */ i = old_pending; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); /* 4) found recyclable pending entry with queued packets? */ } else if (old_queue < ARP_TABLE_SIZE) { - /* recycle oldest pending (queued packets are free in free_entry) */ + /* recycle oldest pending (queued packets are free in etharp_free_entry) */ i = old_queue; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); /* no empty or recyclable entries found */ } else { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty or recyclable entries found\n")); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); return (s8_t)ERR_MEM; } /* { empty or recyclable entry found } */ LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); - free_entry(i); + etharp_free_entry(i); } LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); @@ -390,9 +398,6 @@ find_entry(ip_addr_t *ipaddr, u8_t flags) ip_addr_copy(arp_table[i].ipaddr, *ipaddr); } arp_table[i].ctime = 0; -#if ETHARP_SUPPORT_STATIC_ENTRIES - arp_table[i].static_entry = 0; -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ return (err_t)i; } @@ -440,11 +445,11 @@ etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct * @see pbuf_free() */ static err_t -update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) +etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) { s8_t i; LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); @@ -452,11 +457,11 @@ update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethadd if (ip_addr_isany(ipaddr) || ip_addr_isbroadcast(ipaddr, netif) || ip_addr_ismulticast(ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n")); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); return ERR_ARG; } /* find or create ARP entry */ - i = find_entry(ipaddr, flags); + i = etharp_find_entry(ipaddr, flags); /* bail out if no entry could be found */ if (i < 0) { return (err_t)i; @@ -465,21 +470,20 @@ update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethadd #if ETHARP_SUPPORT_STATIC_ENTRIES if (flags & ETHARP_FLAG_STATIC_ENTRY) { /* record static type */ - arp_table[i].static_entry = 1; - } + arp_table[i].state = ETHARP_STATE_STATIC; + } else #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* mark it stable */ + arp_table[i].state = ETHARP_STATE_STABLE; + } - /* mark it stable */ - arp_table[i].state = ETHARP_STATE_STABLE; - -#if LWIP_SNMP /* record network interface */ arp_table[i].netif = netif; -#endif /* LWIP_SNMP */ /* insert in SNMP ARP index tree */ snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); /* update address */ ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr); /* reset time stamp */ @@ -532,7 +536,7 @@ etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr) return ERR_RTE; } - return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); + return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); } /** Remove a static entry from the ARP table previously added with a call to @@ -551,23 +555,39 @@ etharp_remove_static_entry(ip_addr_t *ipaddr) ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); /* find or create ARP entry */ - i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); /* bail out if no entry could be found */ if (i < 0) { return (err_t)i; } - if ((arp_table[i].state != ETHARP_STATE_STABLE) || - (arp_table[i].static_entry == 0)) { + if (arp_table[i].state != ETHARP_STATE_STATIC) { /* entry wasn't a static entry, cannot remove it */ return ERR_ARG; } /* entry found, free it */ - free_entry(i); + etharp_free_entry(i); return ERR_OK; } #endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ +/** + * Remove all ARP table entries of the specified netif. + * + * @param netif points to a network interface + */ +void etharp_cleanup_netif(struct netif *netif) +{ + u8_t i; + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) { + etharp_free_entry(i); + } + } +} + /** * Finds (stable) ethernet/IP address pair from ARP table * using interface and IP address index. @@ -590,8 +610,8 @@ etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, LWIP_UNUSED_ARG(netif); - i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); - if((i >= 0) && arp_table[i].state == ETHARP_STATE_STABLE) { + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); + if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { *eth_ret = &arp_table[i].ethaddr; *ip_ret = &arp_table[i].ipaddr; return i; @@ -645,7 +665,7 @@ etharp_ip_input(struct netif *netif, struct pbuf *p) /* update the source IP address in the cache, if present */ /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk * back soon (for example, if the destination IP address is ours. */ - update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY); + etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY); } #endif /* ETHARP_TRUST_IP_MAC */ @@ -738,7 +758,7 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) can result in directly sending the queued packets for this host. ARP message not directed to us? -> update the source IP address in the cache, if present */ - update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), + etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); /* now act on the message itself */ @@ -815,6 +835,28 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) pbuf_free(p); } +/** Just a small helper function that sends a pbuf to an ethernet address + * in the arp_table specified by the index 'arp_idx'. + */ +static err_t +etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx) +{ + LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", + arp_table[arp_idx].state >= ETHARP_STATE_STABLE); + /* if arp table entry is about to expire: re-request it, + but only if its state is ETHARP_STATE_STABLE to prevent flooding the + network with ARP requests if this address is used frequently. */ + if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && + (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) { + if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { + arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING; + } + } + + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), + &arp_table[arp_idx].ethaddr); +} + /** * Resolve and fill-in Ethernet address header for outgoing IP packet. * @@ -836,7 +878,13 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) { - struct eth_addr *dest, mcastaddr; + struct eth_addr *dest; + struct eth_addr mcastaddr; + ip_addr_t *dst_addr = ipaddr; + + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); /* make room for Ethernet header - should not fail */ if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { @@ -847,8 +895,6 @@ etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) return ERR_BUF; } - /* assume unresolved Ethernet address */ - dest = NULL; /* Determine on destination hardware address. Broadcasts and multicasts * are special, other IP addresses are looked up in the ARP table. */ @@ -859,9 +905,9 @@ etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) /* multicast destination IP address? */ } else if (ip_addr_ismulticast(ipaddr)) { /* Hash IP multicast address to MAC address.*/ - mcastaddr.addr[0] = 0x01; - mcastaddr.addr[1] = 0x00; - mcastaddr.addr[2] = 0x5e; + mcastaddr.addr[0] = LL_MULTICAST_ADDR_0; + mcastaddr.addr[1] = LL_MULTICAST_ADDR_1; + mcastaddr.addr[2] = LL_MULTICAST_ADDR_2; mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; mcastaddr.addr[4] = ip4_addr3(ipaddr); mcastaddr.addr[5] = ip4_addr4(ipaddr); @@ -869,7 +915,9 @@ etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) dest = &mcastaddr; /* unicast destination IP address? */ } else { - /* outside local network? */ + s8_t i; + /* outside local network? if so, this can neither be a global broadcast nor + a subnet broadcast. */ if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && !ip_addr_islinklocal(ipaddr)) { #if LWIP_AUTOIP @@ -885,7 +933,7 @@ etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) /* interface has default gateway? */ if (!ip_addr_isany(&netif->gw)) { /* send to hardware address of default gateway IP address */ - ipaddr = &(netif->gw); + dst_addr = &(netif->gw); /* no default gateway available */ } else { /* no route to destination error (default gateway missing) */ @@ -899,19 +947,30 @@ etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) u8_t etharp_cached_entry = *(netif->addr_hint); if (etharp_cached_entry < ARP_TABLE_SIZE) { #endif /* LWIP_NETIF_HWADDRHINT */ - if ((arp_table[etharp_cached_entry].state == ETHARP_STATE_STABLE) && - (ip_addr_cmp(ipaddr, &arp_table[etharp_cached_entry].ipaddr))) { + if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && + (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { /* the per-pcb-cached entry is stable and the right one! */ ETHARP_STATS_INC(etharp.cachehit); - return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), - &arp_table[etharp_cached_entry].ethaddr); + return etharp_output_to_arp_index(netif, q, etharp_cached_entry); } #if LWIP_NETIF_HWADDRHINT } } #endif /* LWIP_NETIF_HWADDRHINT */ - /* queue on destination Ethernet address belonging to ipaddr */ - return etharp_query(netif, ipaddr, q); + + /* find stable entry: do this here since this is a critical path for + throughput and etharp_find_entry() is kind of slow */ + for (i = 0; i < ARP_TABLE_SIZE; i++) { + if ((arp_table[i].state >= ETHARP_STATE_STABLE) && + (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { + /* found an existing, stable entry */ + ETHARP_SET_HINT(netif, i); + return etharp_output_to_arp_index(netif, q, i); + } + } + /* no stable entry found, use the (slower) query function: + queue on destination Ethernet address belonging to ipaddr */ + return etharp_query(netif, dst_addr, q); } /* continuation for multicast/broadcast destinations */ @@ -969,7 +1028,7 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) } /* find entry in ARP cache, ask to create entry if queueing packet */ - i = find_entry(ipaddr, ETHARP_FLAG_TRY_HARD); + i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD); /* could not find or create entry? */ if (i < 0) { @@ -989,7 +1048,7 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) /* { i is either a STABLE or (new or existing) PENDING entry } */ LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", ((arp_table[i].state == ETHARP_STATE_PENDING) || - (arp_table[i].state == ETHARP_STATE_STABLE))); + (arp_table[i].state >= ETHARP_STATE_STABLE))); /* do we have a pending entry? or an implicit query request? */ if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) { @@ -1009,7 +1068,7 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) /* packet given? */ LWIP_ASSERT("q != NULL", q != NULL); /* stable entry? */ - if (arp_table[i].state == ETHARP_STATE_STABLE) { + if (arp_table[i].state >= ETHARP_STATE_STABLE) { /* we have a valid IP->Ethernet address mapping */ ETHARP_SET_HINT(netif, i); /* send the packet */ @@ -1127,6 +1186,8 @@ etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, const u8_t * ethdst_hwaddr; #endif /* LWIP_AUTOIP */ + LWIP_ASSERT("netif != NULL", netif != NULL); + /* allocate a pbuf for the outgoing ARP request packet */ p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM); /* could allocate a pbuf for an ARP request? */ @@ -1217,7 +1278,9 @@ ethernet_input(struct pbuf *p, struct netif *netif) { struct eth_hdr* ethhdr; u16_t type; +#if LWIP_ARP || ETHARP_SUPPORT_VLAN s16_t ip_hdr_offset = SIZEOF_ETH_HDR; +#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ if (p->len <= SIZEOF_ETH_HDR) { /* a packet with only an ethernet header (or less) is not valid for us */ @@ -1246,13 +1309,17 @@ ethernet_input(struct pbuf *p, struct netif *netif) ETHARP_STATS_INC(etharp.drop); goto free_and_return; } -#ifdef ETHARP_VLAN_CHECK /* if not, allow all VLANs */ +#if defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */ +#ifdef ETHARP_VLAN_CHECK_FN + if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) { +#elif defined(ETHARP_VLAN_CHECK) if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { +#endif /* silently ignore this packet: not for our VLAN */ pbuf_free(p); return ERR_OK; } -#endif /* ETHARP_VLAN_CHECK */ +#endif /* defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */ type = vlan->tpid; ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; } @@ -1262,6 +1329,20 @@ ethernet_input(struct pbuf *p, struct netif *netif) netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type)); #endif /* LWIP_ARP_FILTER_NETIF*/ + if (ethhdr->dest.addr[0] & 1) { + /* this might be a multicast or broadcast packet */ + if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) { + if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && + (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) { + /* mark the pbuf as link-layer multicast */ + p->flags |= PBUF_FLAG_LLMCAST; + } + } else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { + /* mark the pbuf as link-layer broadcast */ + p->flags |= PBUF_FLAG_LLBCAST; + } + } + switch (type) { #if LWIP_ARP /* IP packet? */ diff --git a/reactos/lib/drivers/lwip/src/netif/ethernetif.c b/reactos/lib/drivers/lwip/src/netif/ethernetif.c index a5b7d990b11..8ec40be12ef 100644 --- a/reactos/lib/drivers/lwip/src/netif/ethernetif.c +++ b/reactos/lib/drivers/lwip/src/netif/ethernetif.c @@ -50,7 +50,6 @@ #include "lwip/def.h" #include "lwip/mem.h" #include "lwip/pbuf.h" -#include "lwip/sys.h" #include #include #include "netif/etharp.h" diff --git a/reactos/lib/drivers/lwip/src/netif/loopif.c b/reactos/lib/drivers/lwip/src/netif/loopif.c deleted file mode 100644 index 1e1f28cf144..00000000000 --- a/reactos/lib/drivers/lwip/src/netif/loopif.c +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file - * Loop Interface - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#include "lwip/opt.h" - -#if LWIP_HAVE_LOOPIF - -#include "netif/loopif.h" -#include "lwip/snmp.h" - -/** - * Initialize a lwip network interface structure for a loopback interface - * - * @param netif the lwip network interface structure for this loopif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - */ -err_t -loopif_init(struct netif *netif) -{ - /* initialize the snmp variables and counters inside the struct netif - * ifSpeed: no assumption can be made! - */ - NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); - - netif->name[0] = 'l'; - netif->name[1] = 'o'; - netif->output = netif_loop_output; - return ERR_OK; -} - -#endif /* LWIP_HAVE_LOOPIF */ diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/auth.c b/reactos/lib/drivers/lwip/src/netif/ppp/auth.c index c3c49d22a25..0fd87a3796c 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/auth.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/auth.c @@ -68,7 +68,7 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "fsm.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/chap.c b/reactos/lib/drivers/lwip/src/netif/ppp/chap.c index 3a49ff8a5e4..f10e27d2eaf 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/chap.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/chap.c @@ -72,7 +72,7 @@ #if CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "magic.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/chpms.c b/reactos/lib/drivers/lwip/src/netif/ppp/chpms.c index 83acefcec6d..81a887b83a0 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/chpms.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/chpms.c @@ -75,7 +75,7 @@ #if MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "md4.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/fsm.c b/reactos/lib/drivers/lwip/src/netif/ppp/fsm.c index 2e73c5af8ff..e8a254ede52 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/fsm.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/fsm.c @@ -59,7 +59,7 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "fsm.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/ipcp.c b/reactos/lib/drivers/lwip/src/netif/ppp/ipcp.c index 461a600f85c..f0ab2e0e172 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/ipcp.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/ipcp.c @@ -55,7 +55,7 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "auth.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/lcp.c b/reactos/lib/drivers/lwip/src/netif/ppp/lcp.c index 21c83ac4449..54f758aa646 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/lcp.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/lcp.c @@ -55,7 +55,7 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "fsm.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/magic.c b/reactos/lib/drivers/lwip/src/netif/ppp/magic.c index 3901330895a..3732a424179 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/magic.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/magic.c @@ -53,7 +53,7 @@ #if PPP_SUPPORT -#include "ppp.h" +#include "ppp_impl.h" #include "randm.h" #include "magic.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/md5.c b/reactos/lib/drivers/lwip/src/netif/ppp/md5.c index 3cb69e2b065..dc3cc751b73 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/md5.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/md5.c @@ -37,7 +37,7 @@ #if CHAP_SUPPORT || MD5_SUPPORT -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "md5.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/pap.c b/reactos/lib/drivers/lwip/src/netif/ppp/pap.c index ac44e6464ce..5fb9f886c05 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/pap.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/pap.c @@ -55,7 +55,7 @@ #if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "auth.h" @@ -218,7 +218,7 @@ upap_timeout(void *arg) u->us_unit, u->us_timeouttime, u->us_clientstate)); if (u->us_clientstate != UPAPCS_AUTHREQ) { - UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n")); + UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n")); return; } diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/ppp.c b/reactos/lib/drivers/lwip/src/netif/ppp/ppp.c index e9b433b0534..8e8fae9f9f4 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/ppp.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/ppp.c @@ -83,9 +83,9 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ +#include "ppp_impl.h" #include "lwip/ip.h" /* for ip_input() */ -#include "ppp.h" #include "pppdebug.h" #include "randm.h" @@ -172,7 +172,9 @@ typedef struct PPPControlRx_s { /** the rx file descriptor */ sio_fd_t fd; /** receive buffer - encoded data is stored here */ +#if PPP_INPROC_OWNTHREAD u_char rxbuf[PPPOS_RX_BUFSIZE]; +#endif /* PPP_INPROC_OWNTHREAD */ /* The input packet. */ struct pbuf *inHead, *inTail; @@ -241,6 +243,7 @@ static void pppInputThread(void *arg); #endif /* PPP_INPROC_OWNTHREAD */ static void pppDrop(PPPControlRx *pcrx); static void pppInProc(PPPControlRx *pcrx, u_char *s, int l); +static void pppFreeCurrentInputPacket(PPPControlRx *pcrx); #endif /* PPPOS_SUPPORT */ @@ -339,6 +342,7 @@ static u_char pppACCMMask[] = { 0x80 }; +#if PPP_INPROC_OWNTHREAD /** Wake up the task blocked in reading from serial line (if any) */ static void pppRecvWakeup(int pd) @@ -348,6 +352,7 @@ pppRecvWakeup(int pd) sio_read_abort(pppControl[pd].fd); } } +#endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ void @@ -363,7 +368,9 @@ pppLinkTerminated(int pd) { #if PPPOS_SUPPORT PPPControl* pc; +#if PPP_INPROC_OWNTHREAD pppRecvWakeup(pd); +#endif /* PPP_INPROC_OWNTHREAD */ pc = &pppControl[pd]; PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); @@ -388,9 +395,9 @@ pppLinkDown(int pd) } else #endif /* PPPOE_SUPPORT */ { -#if PPPOS_SUPPORT +#if PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD pppRecvWakeup(pd); -#endif /* PPPOS_SUPPORT */ +#endif /* PPPOS_SUPPORT && PPP_INPROC_OWNTHREAD*/ } } @@ -527,7 +534,7 @@ pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) * pppOpen() is directly defined to this function. */ int -pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx) +pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) { PPPControl *pc; int pd; @@ -545,6 +552,8 @@ pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void pd = PPPERR_OPEN; } else { pc = &pppControl[pd]; + /* input pbuf left over from last session? */ + pppFreeCurrentInputPacket(&pc->rx); /* @todo: is this correct or do I overwrite something? */ memset(pc, 0, sizeof(PPPControl)); pc->rx.pd = pd; @@ -574,7 +583,7 @@ pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void pppStart(pd); #if PPP_INPROC_OWNTHREAD sys_thread_new(PPP_THREAD_NAME, pppInputThread, (void*)&pc->rx, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); -#endif +#endif /* PPP_INPROC_OWNTHREAD */ } return pd; @@ -595,7 +604,8 @@ pppOverEthernetClose(int pd) pppoe_destroy(&pc->netif); } -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx) +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, + pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx) { PPPControl *pc; int pd; @@ -671,7 +681,9 @@ pppClose(int pd) pc->errCode = PPPERR_USER; /* This will leave us at PHASE_DEAD. */ pppStop(pd); +#if PPP_INPROC_OWNTHREAD pppRecvWakeup(pd); +#endif /* PPP_INPROC_OWNTHREAD */ #endif /* PPPOS_SUPPORT */ } @@ -1260,7 +1272,7 @@ GetMask(u32_t addr) { u32_t mask, nmask; - htonl(addr); + addr = htonl(addr); if (IP_CLASSA(addr)) { /* determine network mask for address class */ nmask = IP_CLASSA_NET; } else if (IP_CLASSB(addr)) { @@ -1714,6 +1726,22 @@ out: * Drop the input packet. */ static void +pppFreeCurrentInputPacket(PPPControlRx *pcrx) +{ + if (pcrx->inHead != NULL) { + if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) { + pbuf_free(pcrx->inTail); + } + pbuf_free(pcrx->inHead); + pcrx->inHead = NULL; + } + pcrx->inTail = NULL; +} + +/* + * Drop the input packet and increase error counters. + */ +static void pppDrop(PPPControlRx *pcrx) { if (pcrx->inHead != NULL) { @@ -1721,13 +1749,8 @@ pppDrop(PPPControlRx *pcrx) PPPDEBUG(LOG_INFO, ("pppDrop: %d:%.*H\n", pcrx->inHead->len, min(60, pcrx->inHead->len * 2), pcrx->inHead->payload)); #endif PPPDEBUG(LOG_INFO, ("pppDrop: pbuf len=%d, addr %p\n", pcrx->inHead->len, (void*)pcrx->inHead)); - if (pcrx->inTail && (pcrx->inTail != pcrx->inHead)) { - pbuf_free(pcrx->inTail); - } - pbuf_free(pcrx->inHead); - pcrx->inHead = NULL; - pcrx->inTail = NULL; } + pppFreeCurrentInputPacket(pcrx); #if VJ_SUPPORT vj_uncompress_err(&pppControl[pcrx->pd].vjComp); #endif /* VJ_SUPPORT */ @@ -1736,6 +1759,7 @@ pppDrop(PPPControlRx *pcrx) snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif); } +#if !PPP_INPROC_OWNTHREAD /** Pass received raw characters to PPPoS to be decoded. This function is * thread-safe and can be called from a dedicated RX-thread or from a main-loop. * @@ -1748,6 +1772,7 @@ pppos_input(int pd, u_char* data, int len) { pppInProc(&pppControl[pd].rx, data, len); } +#endif /** * Process a received octet string. diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/ppp.h b/reactos/lib/drivers/lwip/src/netif/ppp/ppp.h index a72ac9576ba..08d6e62d87f 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/ppp.h +++ b/reactos/lib/drivers/lwip/src/netif/ppp/ppp.h @@ -46,67 +46,6 @@ #include "lwip/sys.h" #include "lwip/timers.h" -/** Some defines for code we skip compared to the original pppd. - * These are just here to minimise the use of the ugly "#if 0". */ -#define PPP_ADDITIONAL_CALLBACKS 0 - -/** Some error checks to test for unsupported code */ -#if CBCP_SUPPORT -#error "CBCP is not supported in lwIP PPP" -#endif -#if CCP_SUPPORT -#error "CCP is not supported in lwIP PPP" -#endif - -/* - * pppd.h - PPP daemon global declarations. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - */ -/* - * ppp_defs.h - PPP definitions. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) -#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) - #ifndef __u_char_defined @@ -118,123 +57,6 @@ typedef unsigned char u_char; #endif -/* - * Constants and structures defined by the internet system, - * Per RFC 790, September 1981, and numerous additions. - */ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#define PPP_COMP 0xfd /* compressed packet */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ - -/* - * Values for FCS calculations. - */ -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) - -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u_char ext_accm[32]; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Inline versions of get/put char/short/long. - * Pointer is advanced; we assume that both arguments - * are lvalues and will already be in registers. - * cp MUST be u_char *. - */ -#define GETCHAR(c, cp) { \ - (c) = *(cp)++; \ -} -#define PUTCHAR(c, cp) { \ - *(cp)++ = (u_char) (c); \ -} - - -#define GETSHORT(s, cp) { \ - (s) = *(cp); (cp)++; (s) <<= 8; \ - (s) |= *(cp); (cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s & 0xff); \ -} - -#define GETLONG(l, cp) { \ - (l) = *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (cp)++; (l) <<= 8; \ - (l) |= *(cp); (cp)++; \ -} -#define PUTLONG(l, cp) { \ - *(cp)++ = (u_char) ((l) >> 24); \ - *(cp)++ = (u_char) ((l) >> 16); \ - *(cp)++ = (u_char) ((l) >> 8); \ - *(cp)++ = (u_char) (l); \ -} - - -#define INCPTR(n, cp) ((cp) += (n)) -#define DECPTR(n, cp) ((cp) -= (n)) - -#define BCMP(s0, s1, l) memcmp((u_char *)(s0), (u_char *)(s1), (l)) -#define BCOPY(s, d, l) MEMCPY((d), (s), (l)) -#define BZERO(s, n) memset(s, 0, n) - -#if PPP_DEBUG -#define PRINTMSG(m, l) { m[l] = '\0'; LWIP_DEBUGF(LOG_INFO, ("Remote message: %s\n", m)); } -#else /* PPP_DEBUG */ -#define PRINTMSG(m, l) -#endif /* PPP_DEBUG */ - -/* - * MAKEHEADER - Add PPP Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } /************************* *** PUBLIC DEFINITIONS *** @@ -267,89 +89,10 @@ enum NPmode { *** PUBLIC DATA TYPES *** ************************/ -/* - * The following struct gives the addresses of procedures to call - * for a particular protocol. - */ -struct protent { - u_short protocol; /* PPP protocol number */ - /* Initialization procedure */ - void (*init) (int unit); - /* Process a received packet */ - void (*input) (int unit, u_char *pkt, int len); - /* Process a received protocol-reject */ - void (*protrej) (int unit); - /* Lower layer has come up */ - void (*lowerup) (int unit); - /* Lower layer has gone down */ - void (*lowerdown) (int unit); - /* Open the protocol */ - void (*open) (int unit); - /* Close the protocol */ - void (*close) (int unit, char *reason); -#if PPP_ADDITIONAL_CALLBACKS - /* Print a packet in readable form */ - int (*printpkt) (u_char *pkt, int len, - void (*printer) (void *, char *, ...), - void *arg); - /* Process a received data packet */ - void (*datainput) (int unit, u_char *pkt, int len); -#endif /* PPP_ADDITIONAL_CALLBACKS */ - int enabled_flag; /* 0 if protocol is disabled */ - char *name; /* Text name of protocol */ -#if PPP_ADDITIONAL_CALLBACKS - /* Check requested options, assign defaults */ - void (*check_options) (u_long); - /* Configure interface for demand-dial */ - int (*demand_conf) (int unit); - /* Say whether to bring up link for this pkt */ - int (*active_pkt) (u_char *pkt, int len); -#endif /* PPP_ADDITIONAL_CALLBACKS */ -}; - -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - u_short xmit_idle; /* seconds since last NP packet sent */ - u_short recv_idle; /* seconds since last NP packet received */ -}; - -struct ppp_settings { - - u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ - u_int auth_required : 1; /* Peer is required to authenticate */ - u_int explicit_remote : 1; /* remote_name specified with remotename opt */ - u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ - u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ - u_int usehostname : 1; /* Use hostname for our_name */ - u_int usepeerdns : 1; /* Ask peer for DNS adds */ - - u_short idle_time_limit; /* Shut down link if idle for this long */ - int maxconnect; /* Maximum connect time (seconds) */ - - char user [MAXNAMELEN + 1]; /* Username for PAP */ - char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ - char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ -}; - struct ppp_addrs { ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2; }; -/***************************** -*** PUBLIC DATA STRUCTURES *** -*****************************/ - -/* Buffers for outgoing packets. */ -extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; - -extern struct ppp_settings ppp_settings; - -extern struct protent *ppp_protocols[]; /* Table of pointers to supported protocols */ - /*********************** *** PUBLIC FUNCTIONS *** @@ -386,6 +129,10 @@ enum pppAuthType { void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); +/* Link status callback function prototype */ +typedef void (*pppLinkStatusCB_fn)(void *ctx, int errCode, void *arg); + +#if PPPOS_SUPPORT /* * Open a new PPP connection using the given serial I/O device. * This initializes the PPP control block but does not @@ -393,12 +140,16 @@ void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) * Return a new PPP connection descriptor on success or * an error code (negative) on failure. */ -int pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx); +int pppOverSerialOpen(sio_fd_t fd, pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); +#endif /* PPPOS_SUPPORT */ +#if PPPOE_SUPPORT /* * Open a new PPP Over Ethernet (PPPOE) connection. */ -int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx); +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, + pppLinkStatusCB_fn linkStatusCB, void *linkStatusCtx); +#endif /* PPPOE_SUPPORT */ /* for source code compatibility */ #define pppOpen(fd,cb,ls) pppOverSerialOpen(fd,cb,ls) @@ -426,55 +177,22 @@ int pppIOCtl(int pd, int cmd, void *arg); */ u_short pppMTU(int pd); +#if PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD /* - * Write n characters to a ppp link. - * RETURN: >= 0 Number of characters written, -1 Failed to write to device. + * PPP over Serial: this is the input function to be called for received data. + * If PPP_INPROC_OWNTHREAD==1, a seperate input thread using the blocking + * sio_read() is used, so this is deactivated. */ -int pppWrite(int pd, const u_char *s, int n); - -void pppInProcOverEthernet(int pd, struct pbuf *pb); - -struct pbuf *pppSingleBuf(struct pbuf *p); - -void pppLinkTerminated(int pd); - -void pppLinkDown(int pd); - void pppos_input(int pd, u_char* data, int len); +#endif /* PPPOS_SUPPORT && !PPP_INPROC_OWNTHREAD */ -/* Configure i/f transmit parameters */ -void ppp_send_config (int, u16_t, u32_t, int, int); -/* Set extended transmit ACCM */ -void ppp_set_xaccm (int, ext_accm *); -/* Configure i/f receive parameters */ -void ppp_recv_config (int, int, u32_t, int, int); -/* Find out how long link has been idle */ -int get_idle_time (int, struct ppp_idle *); - -/* Configure VJ TCP header compression */ -int sifvjcomp (int, int, u8_t, u8_t); -/* Configure i/f down (for IP) */ -int sifup (int); -/* Set mode for handling packets for proto */ -int sifnpmode (int u, int proto, enum NPmode mode); -/* Configure i/f down (for IP) */ -int sifdown (int); -/* Configure IP addresses for i/f */ -int sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t); -/* Reset i/f IP addresses */ -int cifaddr (int, u32_t, u32_t); -/* Create default route through i/f */ -int sifdefaultroute (int, u32_t, u32_t); -/* Delete default route through i/f */ -int cifdefaultroute (int, u32_t, u32_t); - -/* Get appropriate netmask for address */ -u32_t GetMask (u32_t); #if LWIP_NETIF_STATUS_CALLBACK +/* Set an lwIP-style status-callback for the selected PPP device */ void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback); #endif /* LWIP_NETIF_STATUS_CALLBACK */ #if LWIP_NETIF_LINK_CALLBACK +/* Set an lwIP-style link-callback for the selected PPP device */ void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback); #endif /* LWIP_NETIF_LINK_CALLBACK */ diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/ppp_oe.c b/reactos/lib/drivers/lwip/src/netif/ppp/ppp_oe.c index 040a0bc93c9..fdf52ae23d8 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/ppp_oe.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/ppp_oe.c @@ -74,7 +74,7 @@ #include "netif/ppp_oe.h" -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "lwip/timers.h" diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/randm.c b/reactos/lib/drivers/lwip/src/netif/ppp/randm.c index 2f35caf6a00..b736091fc51 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/randm.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/randm.c @@ -38,7 +38,7 @@ #include "md5.h" #include "randm.h" -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/vj.c b/reactos/lib/drivers/lwip/src/netif/ppp/vj.c index b7f2d54c627..40fdad13d0e 100644 --- a/reactos/lib/drivers/lwip/src/netif/ppp/vj.c +++ b/reactos/lib/drivers/lwip/src/netif/ppp/vj.c @@ -32,7 +32,7 @@ #if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ -#include "ppp.h" +#include "ppp_impl.h" #include "pppdebug.h" #include "vj.h" @@ -213,7 +213,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) */ INCR(vjs_misses); comp->last_cs = lcs; - hlen += TCPH_OFFSET(th); + hlen += TCPH_HDRLEN(th); hlen <<= 2; /* Check that the IP/TCP headers are contained in the first buffer. */ if (hlen > pb->len) { @@ -236,7 +236,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen]; deltaS = hlen; - hlen += TCPH_OFFSET(th); + hlen += TCPH_HDRLEN(th); hlen <<= 2; /* Check that the IP/TCP headers are contained in the first buffer. */ if (hlen > pb->len) { @@ -258,9 +258,9 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] - || TCPH_OFFSET(th) != TCPH_OFFSET(oth) + || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) - || (TCPH_OFFSET(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_OFFSET(th) - 5) << 2))) { + || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) { goto uncompressed; } @@ -434,7 +434,7 @@ vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) hlen = IPH_HL(ip) << 2; if (IPH_PROTO(ip) >= MAX_SLOTS || hlen + sizeof(struct tcp_hdr) > nb->len - || (hlen += TCPH_OFFSET(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2) + || (hlen += TCPH_HDRLEN(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2) > nb->len || hlen > MAX_HDR) { PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", diff --git a/reactos/lib/drivers/lwip/src/netif/ppp/vjbsdhdr.h b/reactos/lib/drivers/lwip/src/netif/ppp/vjbsdhdr.h deleted file mode 100644 index f46267614a1..00000000000 --- a/reactos/lib/drivers/lwip/src/netif/ppp/vjbsdhdr.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef VJBSDHDR_H -#define VJBSDHDR_H - -#include "lwip/tcp.h" - -/* - * Structure of an internet header, naked of options. - * - * We declare ip_len and ip_off to be short, rather than u_short - * pragmatically since otherwise unsigned comparisons can result - * against negative integers quite easily, and fail in subtle ways. - */ -PACK_STRUCT_BEGIN -struct ip -{ -#if defined(NO_CHAR_BITFIELDS) - u_char ip_hl_v; /* bug in GCC for mips means the bitfield stuff will sometimes break - so we use a char for both and get round it with macro's instead... */ -#else -#if BYTE_ORDER == LITTLE_ENDIAN - unsigned ip_hl:4, /* header length */ - ip_v :4; /* version */ -#elif BYTE_ORDER == BIG_ENDIAN - unsigned ip_v :4, /* version */ - ip_hl:4; /* header length */ -#else - COMPLAIN - NO BYTE ORDER SELECTED! -#endif -#endif - u_char ip_tos; /* type of service */ - u_short ip_len; /* total length */ - u_short ip_id; /* identification */ - u_short ip_off; /* fragment offset field */ -#define IP_DF 0x4000 /* dont fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - u_char ip_ttl; /* time to live */ - u_char ip_p; /* protocol */ - u_short ip_sum; /* checksum */ - struct in_addr ip_src,ip_dst; /* source and dest address */ -}; -PACK_STRUCT_END - -typedef u32_t tcp_seq; - -/* - * TCP header. - * Per RFC 793, September, 1981. - */ -PACK_STRUCT_BEGIN -struct tcphdr -{ - u_short th_sport; /* source port */ - u_short th_dport; /* destination port */ - tcp_seq th_seq; /* sequence number */ - tcp_seq th_ack; /* acknowledgement number */ -#if defined(NO_CHAR_BITFIELDS) - u_char th_x2_off; -#else -#if BYTE_ORDER == LITTLE_ENDIAN - unsigned th_x2 :4, /* (unused) */ - th_off:4; /* data offset */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - unsigned th_off:4, /* data offset */ - th_x2 :4; /* (unused) */ -#endif -#endif - u_char th_flags; - u_short th_win; /* window */ - u_short th_sum; /* checksum */ - u_short th_urp; /* urgent pointer */ -}; -PACK_STRUCT_END - -#endif /* VJBSDHDR_H */ diff --git a/reactos/lib/drivers/lwip/src/netif/slipif.c b/reactos/lib/drivers/lwip/src/netif/slipif.c index c19333dd704..2777630902a 100644 --- a/reactos/lib/drivers/lwip/src/netif/slipif.c +++ b/reactos/lib/drivers/lwip/src/netif/slipif.c @@ -35,6 +35,19 @@ * This file is built upon the file: src/arch/rtxc/netif/sioslip.c * * Author: Magnus Ivarsson + * Simon Goldschmidt + * + * Usage: This netif can be used in three ways: + * 1) For NO_SYS==0, an RX thread can be used which blocks on sio_read() + * until data is received. + * 2) In your main loop, call slipif_poll() to check for new RX bytes, + * completed packets are fed into netif->input(). + * 3) Call slipif_received_byte[s]() from your serial RX ISR and + * slipif_process_rxqueue() from your main loop. ISR level decodes + * packets and puts completed packets on a queue which is fed into + * the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for + * pbuf_alloc to work on ISR level!). + * */ /* @@ -49,20 +62,28 @@ #include "lwip/def.h" #include "lwip/pbuf.h" -#include "lwip/sys.h" #include "lwip/stats.h" #include "lwip/snmp.h" #include "lwip/sio.h" +#include "lwip/sys.h" -#define SLIP_BLOCK 1 -#define SLIP_DONTBLOCK 0 - -#define SLIP_END 0300 /* 0xC0 */ -#define SLIP_ESC 0333 /* 0xDB */ -#define SLIP_ESC_END 0334 /* 0xDC */ -#define SLIP_ESC_ESC 0335 /* 0xDD */ +#define SLIP_END 0xC0 /* 0300: start and end of every packet */ +#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */ +#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */ +#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */ +/** Maximum packet size that is received by this netif */ +#ifndef SLIP_MAX_SIZE #define SLIP_MAX_SIZE 1500 +#endif + +/** Define this to the interface speed for SNMP + * (sio_fd is the sio_fd_t returned by sio_open). + * The default value of zero means 'unknown'. + */ +#ifndef SLIP_SIO_SPEED +#define SLIP_SIO_SPEED(sio_fd) 0 +#endif enum slipif_recv_state { SLIP_RECV_NORMAL, @@ -73,8 +94,11 @@ struct slipif_priv { sio_fd_t sd; /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ struct pbuf *p, *q; - enum slipif_recv_state state; + u8_t state; u16_t i, recved; +#if SLIP_RX_FROM_ISR + struct pbuf *rxpackets; +#endif }; /** @@ -101,9 +125,11 @@ slipif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) LWIP_UNUSED_ARG(ipaddr); + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output(%"U16_F"): sending %"U16_F" bytes\n", (u16_t)netif->num, p->tot_len)); priv = netif->state; /* Send pbuf out on the serial I/O device. */ + /* Start with packet delimiter. */ sio_send(SLIP_END, priv->sd); for (q = p; q != NULL; q = q->next) { @@ -111,59 +137,39 @@ slipif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) c = ((u8_t *)q->payload)[i]; switch (c) { case SLIP_END: + /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */ sio_send(SLIP_ESC, priv->sd); sio_send(SLIP_ESC_END, priv->sd); break; case SLIP_ESC: + /* need to escape this byte (0xDB -> 0xDB, 0xDD) */ sio_send(SLIP_ESC, priv->sd); sio_send(SLIP_ESC_ESC, priv->sd); break; default: + /* normal byte - no need for escaping */ sio_send(c, priv->sd); break; } } } + /* End with packet delimiter. */ sio_send(SLIP_END, priv->sd); return ERR_OK; } -/** - * Static function for easy use of blockig or non-blocking - * sio_read - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @param block if 1, call sio_read; if 0, call sio_tryread - * @return return value of sio_read of sio_tryread - */ -static u32_t -slip_sio_read(sio_fd_t fd, u8_t* data, u32_t len, u8_t block) -{ - if (block) { - return sio_read(fd, data, len); - } else { - return sio_tryread(fd, data, len); - } -} - /** * Handle the incoming SLIP stream character by character * - * Poll the serial layer by calling sio_read() or sio_tryread(). - * * @param netif the lwip network interface structure for this slipif - * @param block if 1, block until data is received; if 0, return when all data - * from the buffer is received (multiple calls to this function will + * @param c received character (multiple calls to this function will * return a complete packet, NULL is returned before - used for polling) * @return The IP packet when SLIP_END is received */ -static struct pbuf * -slipif_input(struct netif *netif, u8_t block) +static struct pbuf* +slipif_rxbyte(struct netif *netif, u8_t c) { struct slipif_priv *priv; - u8_t c; struct pbuf *t; LWIP_ASSERT("netif != NULL", (netif != NULL)); @@ -171,89 +177,105 @@ slipif_input(struct netif *netif, u8_t block) priv = netif->state; - while (slip_sio_read(priv->sd, &c, 1, block) > 0) { - switch (priv->state) { - case SLIP_RECV_NORMAL: - switch (c) { - case SLIP_END: - if (priv->recved > 0) { - /* Received whole packet. */ - /* Trim the pbuf to the size of the received packet. */ - pbuf_realloc(priv->q, priv->recved); + switch (priv->state) { + case SLIP_RECV_NORMAL: + switch (c) { + case SLIP_END: + if (priv->recved > 0) { + /* Received whole packet. */ + /* Trim the pbuf to the size of the received packet. */ + pbuf_realloc(priv->q, priv->recved); - LINK_STATS_INC(link.recv); + LINK_STATS_INC(link.recv); - LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n")); - t = priv->q; - priv->p = priv->q = NULL; - priv->i = priv->recved = 0; - return t; - } - continue; - case SLIP_ESC: - priv->state = SLIP_RECV_ESCAPE; - continue; + LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved)); + t = priv->q; + priv->p = priv->q = NULL; + priv->i = priv->recved = 0; + return t; } + return NULL; + case SLIP_ESC: + priv->state = SLIP_RECV_ESCAPE; + return NULL; + } /* end switch (c) */ + break; + case SLIP_RECV_ESCAPE: + /* un-escape END or ESC bytes, leave other bytes + (although that would be a protocol error) */ + switch (c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; break; - case SLIP_RECV_ESCAPE: - switch (c) { - case SLIP_ESC_END: - c = SLIP_END; - break; - case SLIP_ESC_ESC: - c = SLIP_ESC; - break; - } - priv->state = SLIP_RECV_NORMAL; - /* FALLTHROUGH */ } + priv->state = SLIP_RECV_NORMAL; + break; + } /* end switch (priv->state) */ + + /* byte received, packet not yet completely received */ + if (priv->p == NULL) { + /* allocate a new pbuf */ + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); + priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL); - /* byte received, packet not yet completely received */ if (priv->p == NULL) { - /* allocate a new pbuf */ - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); - priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL); - - if (priv->p == NULL) { - LINK_STATS_INC(link.drop); - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); - /* don't process any further since we got no pbuf to receive to */ - break; - } - - if (priv->q != NULL) { - /* 'chain' the pbuf to the existing chain */ - pbuf_cat(priv->q, priv->p); - } else { - /* p is the first pbuf in the chain */ - priv->q = priv->p; - } + LINK_STATS_INC(link.drop); + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); + /* don't process any further since we got no pbuf to receive to */ + return NULL; } - /* this automatically drops bytes if > SLIP_MAX_SIZE */ - if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { - ((u8_t *)priv->p->payload)[priv->i] = c; - priv->recved++; - priv->i++; - if (priv->i >= priv->p->len) { - /* on to the next pbuf */ - priv->i = 0; - if (priv->p->next != NULL && priv->p->next->len > 0) { - /* p is a chain, on to the next in the chain */ - priv->p = priv->p->next; - } else { - /* p is a single pbuf, set it to NULL so next time a new - * pbuf is allocated */ - priv->p = NULL; - } - } + if (priv->q != NULL) { + /* 'chain' the pbuf to the existing chain */ + pbuf_cat(priv->q, priv->p); + } else { + /* p is the first pbuf in the chain */ + priv->q = priv->p; } } + /* this automatically drops bytes if > SLIP_MAX_SIZE */ + if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { + ((u8_t *)priv->p->payload)[priv->i] = c; + priv->recved++; + priv->i++; + if (priv->i >= priv->p->len) { + /* on to the next pbuf */ + priv->i = 0; + if (priv->p->next != NULL && priv->p->next->len > 0) { + /* p is a chain, on to the next in the chain */ + priv->p = priv->p->next; + } else { + /* p is a single pbuf, set it to NULL so next time a new + * pbuf is allocated */ + priv->p = NULL; + } + } + } return NULL; } -#if !NO_SYS +/** Like slipif_rxbyte, but passes completed packets to netif->input + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + */ +static void +slipif_rxbyte_input(struct netif *netif, u8_t c) +{ + struct pbuf *p; + p = slipif_rxbyte(netif, c); + if (p != NULL) { + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + } +} + +#if SLIP_USE_RX_THREAD /** * The SLIP input thread. * @@ -264,20 +286,17 @@ slipif_input(struct netif *netif, u8_t block) static void slipif_loop_thread(void *nf) { - struct pbuf *p; + u8_t c; struct netif *netif = (struct netif *)nf; + struct slipif_priv *priv = (struct slipif_priv *)netif->state; while (1) { - p = slipif_input(netif, SLIP_BLOCK); - if (p != NULL) { - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - p = NULL; - } + if (sio_read(priv->sd, &c, 1) > 0) { + slipif_rxbyte_input(netif, c); } } } -#endif /* !NO_SYS */ +#endif /* SLIP_USE_RX_THREAD */ /** * SLIP netif initialization @@ -291,17 +310,20 @@ slipif_loop_thread(void *nf) * ERR_IF is serial line couldn't be opened * * @note netif->num must contain the number of the serial port to open - * (0 by default) + * (0 by default). If netif->state is != NULL, it is interpreted as an + * u8_t pointer pointing to the serial port number instead of netif->num. + * */ err_t slipif_init(struct netif *netif) { struct slipif_priv *priv; + u8_t sio_num; LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num)); /* Allocate private data */ - priv = mem_malloc(sizeof(struct slipif_priv)); + priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv)); if (!priv) { return ERR_MEM; } @@ -312,8 +334,14 @@ slipif_init(struct netif *netif) netif->mtu = SLIP_MAX_SIZE; netif->flags |= NETIF_FLAG_POINTTOPOINT; - /* Try to open the serial port (netif->num contains the port number). */ - priv->sd = sio_open(netif->num); + /* netif->state or netif->num contain the port number */ + if (netif->state != NULL) { + sio_num = *(u8_t*)netif->state; + } else { + sio_num = netif->num; + } + /* Try to open the serial port. */ + priv->sd = sio_open(sio_num); if (!priv->sd) { /* Opening the serial port failed. */ mem_free(priv); @@ -326,18 +354,20 @@ slipif_init(struct netif *netif) priv->state = SLIP_RECV_NORMAL; priv->i = 0; priv->recved = 0; +#if SLIP_RX_FROM_ISR + priv->rxpackets = NULL; +#endif netif->state = priv; - /* initialize the snmp variables and counters inside the struct netif - * ifSpeed: no assumption can be made without knowing more about the - * serial line! - */ - NETIF_INIT_SNMP(netif, snmp_ifType_slip, 0); + /* initialize the snmp variables and counters inside the struct netif */ + NETIF_INIT_SNMP(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd)); +#if SLIP_USE_RX_THREAD /* Create a thread to poll the serial line. */ sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif, SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); +#endif /* SLIP_USE_RX_THREAD */ return ERR_OK; } @@ -349,19 +379,132 @@ slipif_init(struct netif *netif) void slipif_poll(struct netif *netif) { - struct pbuf *p; + u8_t c; struct slipif_priv *priv; LWIP_ASSERT("netif != NULL", (netif != NULL)); LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - priv = netif->state; + priv = (struct slipif_priv *)netif->state; - while ((p = slipif_input(netif, SLIP_DONTBLOCK)) != NULL) { - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } + while (sio_tryread(priv->sd, &c, 1) > 0) { + slipif_rxbyte_input(netif, c); } } +#if SLIP_RX_FROM_ISR +/** + * Feeds the IP layer with incoming packets that were receive + * + * @param netif The lwip network interface structure for this slipif + */ +void +slipif_process_rxqueue(struct netif *netif) +{ + struct slipif_priv *priv; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = (struct slipif_priv *)netif->state; + + SYS_ARCH_PROTECT(old_level); + while (priv->rxpackets != NULL) { + struct pbuf *p = priv->rxpackets; +#if SLIP_RX_QUEUE + /* dequeue packet */ + struct pbuf *q = p; + while ((q->len != q->tot_len) && (q->next != NULL)) { + q = q->next; + } + priv->rxpackets = q->next; + q->next = NULL; +#else /* SLIP_RX_QUEUE */ + priv->rxpackets = NULL; +#endif /* SLIP_RX_QUEUE */ + SYS_ARCH_UNPROTECT(old_level); + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + SYS_ARCH_PROTECT(old_level); + } +} + +/** Like slipif_rxbyte, but queues completed packets. + * + * @param netif The lwip network interface structure for this slipif + * @param data Received serial byte + */ +static void +slipif_rxbyte_enqueue(struct netif *netif, u8_t data) +{ + struct pbuf *p; + struct slipif_priv *priv = (struct slipif_priv *)netif->state; + SYS_ARCH_DECL_PROTECT(old_level); + + p = slipif_rxbyte(netif, data); + if (p != NULL) { + SYS_ARCH_PROTECT(old_level); + if (priv->rxpackets != NULL) { +#if SLIP_RX_QUEUE + /* queue multiple pbufs */ + struct pbuf *q = p; + while(q->next != NULL) { + q = q->next; + } + q->next = p; + } else { +#else /* SLIP_RX_QUEUE */ + pbuf_free(priv->rxpackets); + } + { +#endif /* SLIP_RX_QUEUE */ + priv->rxpackets = p; + } + SYS_ARCH_UNPROTECT(old_level); + } +} + +/** + * Process a received byte, completed packets are put on a queue that is + * fed into IP through slipif_process_rxqueue(). + * + * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + */ +void +slipif_received_byte(struct netif *netif, u8_t data) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + slipif_rxbyte_enqueue(netif, data); +} + +/** + * Process multiple received byte, completed packets are put on a queue that is + * fed into IP through slipif_process_rxqueue(). + * + * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + * @param len Number of received characters + */ +void +slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len) +{ + u8_t i; + u8_t *rxdata = data; + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + for (i = 0; i < len; i++, rxdata++) { + slipif_rxbyte_enqueue(netif, *rxdata); + } +} +#endif /* SLIP_RX_FROM_ISR */ + #endif /* LWIP_HAVE_SLIPIF */ diff --git a/reactos/lib/drivers/lwip/src/rosip.c b/reactos/lib/drivers/lwip/src/rosip.c index 1b60945082c..37700776ddf 100755 --- a/reactos/lib/drivers/lwip/src/rosip.c +++ b/reactos/lib/drivers/lwip/src/rosip.c @@ -1,4 +1,5 @@ #include "lwip/sys.h" +#include "lwip/netif.h" #include "lwip/tcpip.h" #include "rosip.h" diff --git a/reactos/lib/drivers/lwip/src/rostcp.c b/reactos/lib/drivers/lwip/src/rostcp.c index 1eb8920905b..93e7eb2a787 100755 --- a/reactos/lib/drivers/lwip/src/rostcp.c +++ b/reactos/lib/drivers/lwip/src/rostcp.c @@ -1,4 +1,5 @@ #include "lwip/sys.h" +#include "lwip/netif.h" #include "lwip/tcpip.h" #include "rosip.h" diff --git a/reactos/lib/drivers/lwip/test/unit/lwip_unittests.c b/reactos/lib/drivers/lwip/test/unit/lwip_unittests.c index e0931464602..41d1f3612f6 100644 --- a/reactos/lib/drivers/lwip/test/unit/lwip_unittests.c +++ b/reactos/lib/drivers/lwip/test/unit/lwip_unittests.c @@ -4,7 +4,9 @@ #include "tcp/test_tcp.h" #include "tcp/test_tcp_oos.h" #include "core/test_mem.h" +#include "core/test_pbuf.h" #include "etharp/test_etharp.h" +#include "dhcp/test_dhcp.h" #include "lwip/init.h" @@ -19,7 +21,9 @@ int main() tcp_suite, tcp_oos_suite, mem_suite, + pbuf_suite, etharp_suite, + dhcp_suite }; size_t num = sizeof(suites)/sizeof(void*); LWIP_ASSERT("No suites defined", num > 0); @@ -43,4 +47,3 @@ int main() srunner_free(sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } - diff --git a/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.c b/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.c index b28254088f7..ff503db3df9 100644 --- a/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.c +++ b/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.c @@ -36,43 +36,40 @@ tcp_remove_all(void) fail_unless(lwip_stats.memp[MEMP_PBUF_POOL].used == 0); } -/** Create a TCP segment usable for passing to tcp_input - * - IP-addresses, ports, seqno and ackno are taken from pcb - * - seqno and ackno can be altered with an offset - */ -struct pbuf* -tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset, - u32_t ackno_offset, u8_t headerflags) -{ - return tcp_create_segment(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port, - data, data_len, pcb->rcv_nxt + seqno_offset, pcb->snd_nxt + ackno_offset, headerflags); -} - /** Create a TCP segment usable for passing to tcp_input */ -struct pbuf* -tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, +static struct pbuf* +tcp_create_segment_wnd(ip_addr_t* src_ip, ip_addr_t* dst_ip, u16_t src_port, u16_t dst_port, void* data, size_t data_len, - u32_t seqno, u32_t ackno, u8_t headerflags) + u32_t seqno, u32_t ackno, u8_t headerflags, u16_t wnd) { - struct pbuf* p; + struct pbuf *p, *q; struct ip_hdr* iphdr; struct tcp_hdr* tcphdr; u16_t pbuf_len = (u16_t)(sizeof(struct ip_hdr) + sizeof(struct tcp_hdr) + data_len); p = pbuf_alloc(PBUF_RAW, pbuf_len, PBUF_POOL); EXPECT_RETNULL(p != NULL); - EXPECT_RETNULL(p->next == NULL); + /* first pbuf must be big enough to hold the headers */ + EXPECT_RETNULL(p->len >= (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr))); + if (data_len > 0) { + /* first pbuf must be big enough to hold at least 1 data byte, too */ + EXPECT_RETNULL(p->len > (sizeof(struct ip_hdr) + sizeof(struct tcp_hdr))); + } - memset(p->payload, 0, p->len); + for(q = p; q != NULL; q = q->next) { + memset(q->payload, 0, q->len); + } iphdr = p->payload; /* fill IP header */ iphdr->dest.addr = dst_ip->addr; iphdr->src.addr = src_ip->addr; - IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0); + IPH_VHL_SET(iphdr, 4, IP_HLEN / 4); + IPH_TOS_SET(iphdr, 0); IPH_LEN_SET(iphdr, htons(p->tot_len)); IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + /* let p point to TCP header */ pbuf_header(p, -(s16_t)sizeof(struct ip_hdr)); tcphdr = p->payload; @@ -82,21 +79,61 @@ tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, tcphdr->ackno = htonl(ackno); TCPH_HDRLEN_SET(tcphdr, sizeof(struct tcp_hdr)/4); TCPH_FLAGS_SET(tcphdr, headerflags); - tcphdr->wnd = htons(TCP_WND); + tcphdr->wnd = htons(wnd); - /* copy data */ - memcpy((char*)tcphdr + sizeof(struct tcp_hdr), data, data_len); + if (data_len > 0) { + /* let p point to TCP data */ + pbuf_header(p, -(s16_t)sizeof(struct tcp_hdr)); + /* copy data */ + pbuf_take(p, data, data_len); + /* let p point to TCP header again */ + pbuf_header(p, sizeof(struct tcp_hdr)); + } /* calculate checksum */ - tcphdr->chksum = inet_chksum_pseudo(p, src_ip, dst_ip, - IP_PROTO_TCP, p->tot_len); + tcphdr->chksum = inet_chksum_pseudo(p, + IP_PROTO_TCP, p->tot_len, src_ip, dst_ip); pbuf_header(p, sizeof(struct ip_hdr)); return p; } +/** Create a TCP segment usable for passing to tcp_input */ +struct pbuf* +tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, + u16_t src_port, u16_t dst_port, void* data, size_t data_len, + u32_t seqno, u32_t ackno, u8_t headerflags) +{ + return tcp_create_segment_wnd(src_ip, dst_ip, src_port, dst_port, data, + data_len, seqno, ackno, headerflags, TCP_WND); +} + +/** Create a TCP segment usable for passing to tcp_input + * - IP-addresses, ports, seqno and ackno are taken from pcb + * - seqno and ackno can be altered with an offset + */ +struct pbuf* +tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset, + u32_t ackno_offset, u8_t headerflags) +{ + return tcp_create_segment(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port, + data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags); +} + +/** Create a TCP segment usable for passing to tcp_input + * - IP-addresses, ports, seqno and ackno are taken from pcb + * - seqno and ackno can be altered with an offset + * - TCP window can be adjusted + */ +struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len, + u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd) +{ + return tcp_create_segment_wnd(&pcb->remote_ip, &pcb->local_ip, pcb->remote_port, pcb->local_port, + data, data_len, pcb->rcv_nxt + seqno_offset, pcb->lastack + ackno_offset, headerflags, wnd); +} + /** Safely bring a tcp_pcb into the requested state */ void tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, @@ -191,6 +228,8 @@ test_tcp_new_counters_pcb(struct test_tcp_counters* counters) tcp_arg(pcb, counters); tcp_recv(pcb, test_tcp_counters_recv); tcp_err(pcb, test_tcp_counters_err); + pcb->snd_wnd = TCP_WND; + pcb->snd_wnd_max = TCP_WND; } return pcb; } @@ -199,15 +238,66 @@ test_tcp_new_counters_pcb(struct test_tcp_counters* counters) void test_tcp_input(struct pbuf *p, struct netif *inp) { struct ip_hdr *iphdr = (struct ip_hdr*)p->payload; - ip_addr_copy(current_iphdr_dest, iphdr->dest); - ip_addr_copy(current_iphdr_src, iphdr->src); - current_netif = inp; - current_header = iphdr; + /* these lines are a hack, don't use them as an example :-) */ + ip_addr_copy(*ipX_current_dest_addr(), iphdr->dest); + ip_addr_copy(*ipX_current_src_addr(), iphdr->src); + ip_current_netif() = inp; + ip_current_header() = iphdr; + + /* since adding IPv6, p->payload must point to tcp header, not ip header */ + pbuf_header(p, -(s16_t)sizeof(struct ip_hdr)); tcp_input(p, inp); - current_iphdr_dest.addr = 0; - current_iphdr_src.addr = 0; - current_netif = NULL; - current_header = NULL; + ipX_current_dest_addr()->addr = 0; + ipX_current_src_addr()->addr = 0; + ip_current_netif() = NULL; + ip_current_header() = NULL; +} + +static err_t test_tcp_netif_output(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr) +{ + struct test_tcp_txcounters *txcounters = (struct test_tcp_txcounters*)netif->state; + LWIP_UNUSED_ARG(ipaddr); + if (txcounters != NULL) + { + txcounters->num_tx_calls++; + txcounters->num_tx_bytes += p->tot_len; + if (txcounters->copy_tx_packets) { + struct pbuf *p_copy = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + err_t err; + EXPECT(p_copy != NULL); + err = pbuf_copy(p_copy, p); + EXPECT(err == ERR_OK); + if (txcounters->tx_packets == NULL) { + txcounters->tx_packets = p_copy; + } else { + pbuf_cat(txcounters->tx_packets, p_copy); + } + } + } + return ERR_OK; +} + +void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, + ip_addr_t *ip_addr, ip_addr_t *netmask) +{ + struct netif *n; + memset(netif, 0, sizeof(struct netif)); + if (txcounters != NULL) { + memset(txcounters, 0, sizeof(struct test_tcp_txcounters)); + netif->state = txcounters; + } + netif->output = test_tcp_netif_output; + netif->flags |= NETIF_FLAG_UP; + ip_addr_copy(netif->netmask, *netmask); + ip_addr_copy(netif->ip_addr, *ip_addr); + for (n = netif_list; n != NULL; n = n->next) { + if (n == netif) { + return; + } + } + netif->next = NULL; + netif_list = netif; } diff --git a/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.h b/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.h index af546dc6c28..4a72c9358f0 100644 --- a/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.h +++ b/reactos/lib/drivers/lwip/test/unit/tcp/tcp_helper.h @@ -4,6 +4,7 @@ #include "../lwip_check.h" #include "lwip/arch.h" #include "lwip/tcp.h" +#include "lwip/netif.h" /* counters used for test_tcp_counters_* callback functions */ struct test_tcp_counters { @@ -18,6 +19,13 @@ struct test_tcp_counters { u32_t expected_data_len; }; +struct test_tcp_txcounters { + u32_t num_tx_calls; + u32_t num_tx_bytes; + u8_t copy_tx_packets; + struct pbuf *tx_packets; +}; + /* Helper functions */ void tcp_remove_all(void); @@ -26,6 +34,8 @@ struct pbuf* tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip, u32_t seqno, u32_t ackno, u8_t headerflags); struct pbuf* tcp_create_rx_segment(struct tcp_pcb* pcb, void* data, size_t data_len, u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags); +struct pbuf* tcp_create_rx_segment_wnd(struct tcp_pcb* pcb, void* data, size_t data_len, + u32_t seqno_offset, u32_t ackno_offset, u8_t headerflags, u16_t wnd); void tcp_set_state(struct tcp_pcb* pcb, enum tcp_state state, ip_addr_t* local_ip, ip_addr_t* remote_ip, u16_t local_port, u16_t remote_port); void test_tcp_counters_err(void* arg, err_t err); @@ -35,4 +45,8 @@ struct tcp_pcb* test_tcp_new_counters_pcb(struct test_tcp_counters* counters); void test_tcp_input(struct pbuf *p, struct netif *inp); +void test_tcp_init_netif(struct netif *netif, struct test_tcp_txcounters *txcounters, + ip_addr_t *ip_addr, ip_addr_t *netmask); + + #endif diff --git a/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp.c b/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp.c index 0eec3cca725..81720984530 100644 --- a/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp.c +++ b/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp.c @@ -4,15 +4,41 @@ #include "lwip/stats.h" #include "tcp_helper.h" +#ifdef _MSC_VER +#pragma warning(disable: 4307) /* we explicitly wrap around TCP seqnos */ +#endif + #if !LWIP_STATS || !TCP_STATS || !MEMP_STATS #error "This tests needs TCP- and MEMP-statistics enabled" #endif +#if TCP_SND_BUF <= TCP_WND +#error "This tests needs TCP_SND_BUF to be > TCP_WND" +#endif + +static u8_t test_tcp_timer; + +/* our own version of tcp_tmr so we can reset fast/slow timer state */ +static void +test_tcp_tmr(void) +{ + tcp_fasttmr(); + if (++test_tcp_timer & 1) { + tcp_slowtmr(); + } +} /* Setups/teardown functions */ static void tcp_setup(void) { + /* reset iss to default (6510) */ + tcp_ticks = 0; + tcp_ticks = 0 - (tcp_next_iss() - 6510); + tcp_next_iss(); + tcp_ticks = 0; + + test_tcp_timer = 0; tcp_remove_all(); } @@ -20,6 +46,8 @@ static void tcp_teardown(void) { tcp_remove_all(); + netif_list = NULL; + netif_default = NULL; } @@ -50,16 +78,19 @@ START_TEST(test_tcp_recv_inseq) struct tcp_pcb* pcb; struct pbuf* p; char data[] = {1, 2, 3, 4}; - ip_addr_t remote_ip, local_ip; + ip_addr_t remote_ip, local_ip, netmask; u16_t data_len; u16_t remote_port = 0x100, local_port = 0x101; struct netif netif; + struct test_tcp_txcounters txcounters; LWIP_UNUSED_ARG(_i); /* initialize local vars */ memset(&netif, 0, sizeof(netif)); IP4_ADDR(&local_ip, 192, 168, 1, 1); IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); data_len = sizeof(data); /* initialize counter struct */ memset(&counters, 0, sizeof(counters)); @@ -91,6 +122,537 @@ START_TEST(test_tcp_recv_inseq) } END_TEST +/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. + * At the end, send more data. */ +START_TEST(test_tcp_fast_retx_recover) +{ + struct netif netif; + struct test_tcp_txcounters txcounters; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf* p; + char data1[] = { 1, 2, 3, 4}; + char data2[] = { 5, 6, 7, 8}; + char data3[] = { 9, 10, 11, 12}; + char data4[] = {13, 14, 15, 16}; + char data5[] = {17, 18, 19, 20}; + char data6[] = {21, 22, 23, 24}; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + err_t err; + LWIP_UNUSED_ARG(_i); + + /* initialize local vars */ + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); + memset(&counters, 0, sizeof(counters)); + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->mss = TCP_MSS; + /* disable initial congestion window (we don't send a SYN here...) */ + pcb->cwnd = pcb->snd_wnd; + + /* send data1 */ + err = tcp_write(pcb, data1, sizeof(data1), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT_RET(txcounters.num_tx_calls == 1); + EXPECT_RET(txcounters.num_tx_bytes == sizeof(data1) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr)); + memset(&txcounters, 0, sizeof(txcounters)); + /* "recv" ACK for data1 */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 4, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(pcb->unacked == NULL); + /* send data2 */ + err = tcp_write(pcb, data2, sizeof(data2), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT_RET(txcounters.num_tx_calls == 1); + EXPECT_RET(txcounters.num_tx_bytes == sizeof(data2) + sizeof(struct tcp_hdr) + sizeof(struct ip_hdr)); + memset(&txcounters, 0, sizeof(txcounters)); + /* duplicate ACK for data1 (data2 is lost) */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(pcb->dupacks == 1); + /* send data3 */ + err = tcp_write(pcb, data3, sizeof(data3), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* nagle enabled, no tx calls */ + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(txcounters.num_tx_bytes == 0); + memset(&txcounters, 0, sizeof(txcounters)); + /* 2nd duplicate ACK for data1 (data2 and data3 are lost) */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(pcb->dupacks == 2); + /* queue data4, don't send it (unsent-oversize is != 0) */ + err = tcp_write(pcb, data4, sizeof(data4), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + /* 3nd duplicate ACK for data1 (data2 and data3 are lost) -> fast retransmission */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + /*EXPECT_RET(txcounters.num_tx_calls == 1);*/ + EXPECT_RET(pcb->dupacks == 3); + memset(&txcounters, 0, sizeof(txcounters)); + /* TODO: check expected data?*/ + + /* send data5, not output yet */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + /*err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK);*/ + EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(txcounters.num_tx_bytes == 0); + memset(&txcounters, 0, sizeof(txcounters)); + { + int i = 0; + do + { + err = tcp_write(pcb, data6, TCP_MSS, TCP_WRITE_FLAG_COPY); + i++; + }while(err == ERR_OK); + EXPECT_RET(err != ERR_OK); + } + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /*EXPECT_RET(txcounters.num_tx_calls == 0); + EXPECT_RET(txcounters.num_tx_bytes == 0);*/ + memset(&txcounters, 0, sizeof(txcounters)); + + /* send even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + + /* send ACKs for data2 and data3 */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 12, TCP_ACK); + EXPECT_RET(p != NULL); + test_tcp_input(p, &netif); + /*EXPECT_RET(txcounters.num_tx_calls == 0);*/ + + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + /* ...and even more data */ + err = tcp_write(pcb, data5, sizeof(data5), TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + +#if 0 + /* create expected segment */ + p1 = tcp_create_rx_segment(pcb, counters.expected_data, data_len, 0, 0, 0); + EXPECT_RET(p != NULL); + if (p != NULL) { + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT_RET(counters.close_calls == 0); + EXPECT_RET(counters.recv_calls == 1); + EXPECT_RET(counters.recved_bytes == data_len); + EXPECT_RET(counters.err_calls == 0); + } +#endif + /* make sure the pcb is freed */ + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + +static u8_t tx_data[TCP_WND*2]; + +static void +check_seqnos(struct tcp_seg *segs, int num_expected, u32_t *seqnos_expected) +{ + struct tcp_seg *s = segs; + int i; + for (i = 0; i < num_expected; i++, s = s->next) { + EXPECT_RET(s != NULL); + EXPECT(s->tcphdr->seqno == htonl(seqnos_expected[i])); + } + EXPECT(s == NULL); +} + +/** Send data with sequence numbers that wrap around the u32_t range. + * Then, provoke fast retransmission by duplicate ACKs and check that all + * segment lists are still properly sorted. */ +START_TEST(test_tcp_fast_rexmit_wraparound) +{ + struct netif netif; + struct test_tcp_txcounters txcounters; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf* p; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + err_t err; +#define SEQNO1 (0xFFFFFF00 - TCP_MSS) +#define ISS 6510 + u16_t i, sent_total = 0; + u32_t seqnos[] = { + SEQNO1, + SEQNO1 + (1 * TCP_MSS), + SEQNO1 + (2 * TCP_MSS), + SEQNO1 + (3 * TCP_MSS), + SEQNO1 + (4 * TCP_MSS), + SEQNO1 + (5 * TCP_MSS)}; + LWIP_UNUSED_ARG(_i); + + for (i = 0; i < sizeof(tx_data); i++) { + tx_data[i] = (u8_t)i; + } + + /* initialize local vars */ + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); + memset(&counters, 0, sizeof(counters)); + + /* create and initialize the pcb */ + tcp_ticks = SEQNO1 - ISS; + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + EXPECT(pcb->lastack == SEQNO1); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->mss = TCP_MSS; + /* disable initial congestion window (we don't send a SYN here...) */ + pcb->cwnd = 2*TCP_MSS; + + /* send 6 mss-sized segments */ + for (i = 0; i < 6; i++) { + err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + sent_total += TCP_MSS; + } + check_seqnos(pcb->unsent, 6, seqnos); + EXPECT(pcb->unacked == NULL); + err = tcp_output(pcb); + EXPECT(txcounters.num_tx_calls == 2); + EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U)); + memset(&txcounters, 0, sizeof(txcounters)); + + check_seqnos(pcb->unacked, 2, seqnos); + check_seqnos(pcb->unsent, 4, &seqnos[2]); + + /* ACK the first segment */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, TCP_MSS, TCP_ACK); + test_tcp_input(p, &netif); + /* ensure this didn't trigger a retransmission */ + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); + memset(&txcounters, 0, sizeof(txcounters)); + check_seqnos(pcb->unacked, 2, &seqnos[1]); + check_seqnos(pcb->unsent, 3, &seqnos[3]); + + /* 3 dupacks */ + EXPECT(pcb->dupacks == 0); + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + test_tcp_input(p, &netif); + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(pcb->dupacks == 1); + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + test_tcp_input(p, &netif); + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(pcb->dupacks == 2); + /* 3rd dupack -> fast rexmit */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + test_tcp_input(p, &netif); + EXPECT(pcb->dupacks == 3); + EXPECT(txcounters.num_tx_calls == 4); + memset(&txcounters, 0, sizeof(txcounters)); + EXPECT(pcb->unsent == NULL); + check_seqnos(pcb->unacked, 5, &seqnos[1]); + + /* make sure the pcb is freed */ + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + +/** Send data with sequence numbers that wrap around the u32_t range. + * Then, provoke RTO retransmission and check that all + * segment lists are still properly sorted. */ +START_TEST(test_tcp_rto_rexmit_wraparound) +{ + struct netif netif; + struct test_tcp_txcounters txcounters; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + err_t err; +#define SEQNO1 (0xFFFFFF00 - TCP_MSS) +#define ISS 6510 + u16_t i, sent_total = 0; + u32_t seqnos[] = { + SEQNO1, + SEQNO1 + (1 * TCP_MSS), + SEQNO1 + (2 * TCP_MSS), + SEQNO1 + (3 * TCP_MSS), + SEQNO1 + (4 * TCP_MSS), + SEQNO1 + (5 * TCP_MSS)}; + LWIP_UNUSED_ARG(_i); + + for (i = 0; i < sizeof(tx_data); i++) { + tx_data[i] = (u8_t)i; + } + + /* initialize local vars */ + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); + memset(&counters, 0, sizeof(counters)); + + /* create and initialize the pcb */ + tcp_ticks = 0; + tcp_ticks = 0 - tcp_next_iss(); + tcp_ticks = SEQNO1 - tcp_next_iss(); + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + EXPECT(pcb->lastack == SEQNO1); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->mss = TCP_MSS; + /* disable initial congestion window (we don't send a SYN here...) */ + pcb->cwnd = 2*TCP_MSS; + + /* send 6 mss-sized segments */ + for (i = 0; i < 6; i++) { + err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + sent_total += TCP_MSS; + } + check_seqnos(pcb->unsent, 6, seqnos); + EXPECT(pcb->unacked == NULL); + err = tcp_output(pcb); + EXPECT(txcounters.num_tx_calls == 2); + EXPECT(txcounters.num_tx_bytes == 2 * (TCP_MSS + 40U)); + memset(&txcounters, 0, sizeof(txcounters)); + + check_seqnos(pcb->unacked, 2, seqnos); + check_seqnos(pcb->unsent, 4, &seqnos[2]); + + /* call the tcp timer some times */ + for (i = 0; i < 10; i++) { + test_tcp_tmr(); + EXPECT(txcounters.num_tx_calls == 0); + } + /* 11th call to tcp_tmr: RTO rexmit fires */ + test_tcp_tmr(); + EXPECT(txcounters.num_tx_calls == 1); + check_seqnos(pcb->unacked, 1, seqnos); + check_seqnos(pcb->unsent, 5, &seqnos[1]); + + /* fake greater cwnd */ + pcb->cwnd = pcb->snd_wnd; + /* send more data */ + err = tcp_output(pcb); + EXPECT(err == ERR_OK); + /* check queues are sorted */ + EXPECT(pcb->unsent == NULL); + check_seqnos(pcb->unacked, 6, seqnos); + + /* make sure the pcb is freed */ + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} +END_TEST + +/** Provoke fast retransmission by duplicate ACKs and then recover by ACKing all sent data. + * At the end, send more data. */ +static void test_tcp_tx_full_window_lost(u8_t zero_window_probe_from_unsent) +{ + struct netif netif; + struct test_tcp_txcounters txcounters; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + err_t err; + u16_t sent_total, i; + u8_t expected = 0xFE; + + for (i = 0; i < sizeof(tx_data); i++) { + u8_t d = (u8_t)i; + if (d == 0xFE) { + d = 0xF0; + } + tx_data[i] = d; + } + if (zero_window_probe_from_unsent) { + tx_data[TCP_WND] = expected; + } else { + tx_data[0] = expected; + } + + /* initialize local vars */ + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, &txcounters, &local_ip, &netmask); + memset(&counters, 0, sizeof(counters)); + memset(&txcounters, 0, sizeof(txcounters)); + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->mss = TCP_MSS; + /* disable initial congestion window (we don't send a SYN here...) */ + pcb->cwnd = pcb->snd_wnd; + + /* send a full window (minus 1 packets) of TCP data in MSS-sized chunks */ + sent_total = 0; + if ((TCP_WND - TCP_MSS) % TCP_MSS != 0) { + u16_t initial_data_len = (TCP_WND - TCP_MSS) % TCP_MSS; + err = tcp_write(pcb, &tx_data[sent_total], initial_data_len, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == initial_data_len + 40U); + memset(&txcounters, 0, sizeof(txcounters)); + sent_total += initial_data_len; + } + for (; sent_total < (TCP_WND - TCP_MSS); sent_total += TCP_MSS) { + err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); + memset(&txcounters, 0, sizeof(txcounters)); + } + EXPECT(sent_total == (TCP_WND - TCP_MSS)); + + /* now ACK the packet before the first */ + p = tcp_create_rx_segment(pcb, NULL, 0, 0, 0, TCP_ACK); + test_tcp_input(p, &netif); + /* ensure this didn't trigger a retransmission */ + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(txcounters.num_tx_bytes == 0); + + EXPECT(pcb->persist_backoff == 0); + /* send the last packet, now a complete window has been sent */ + err = tcp_write(pcb, &tx_data[sent_total], TCP_MSS, TCP_WRITE_FLAG_COPY); + sent_total += TCP_MSS; + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == TCP_MSS + 40U); + memset(&txcounters, 0, sizeof(txcounters)); + EXPECT(pcb->persist_backoff == 0); + + if (zero_window_probe_from_unsent) { + /* ACK all data but close the TX window */ + p = tcp_create_rx_segment_wnd(pcb, NULL, 0, 0, TCP_WND, TCP_ACK, 0); + test_tcp_input(p, &netif); + /* ensure this didn't trigger any transmission */ + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(txcounters.num_tx_bytes == 0); + EXPECT(pcb->persist_backoff == 1); + } + + /* send one byte more (out of window) -> persist timer starts */ + err = tcp_write(pcb, &tx_data[sent_total], 1, TCP_WRITE_FLAG_COPY); + EXPECT_RET(err == ERR_OK); + err = tcp_output(pcb); + EXPECT_RET(err == ERR_OK); + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(txcounters.num_tx_bytes == 0); + memset(&txcounters, 0, sizeof(txcounters)); + if (!zero_window_probe_from_unsent) { + /* no persist timer unless a zero window announcement has been received */ + EXPECT(pcb->persist_backoff == 0); + } else { + EXPECT(pcb->persist_backoff == 1); + + /* call tcp_timer some more times to let persist timer count up */ + for (i = 0; i < 4; i++) { + test_tcp_tmr(); + EXPECT(txcounters.num_tx_calls == 0); + EXPECT(txcounters.num_tx_bytes == 0); + } + + /* this should trigger the zero-window-probe */ + txcounters.copy_tx_packets = 1; + test_tcp_tmr(); + txcounters.copy_tx_packets = 0; + EXPECT(txcounters.num_tx_calls == 1); + EXPECT(txcounters.num_tx_bytes == 1 + 40U); + EXPECT(txcounters.tx_packets != NULL); + if (txcounters.tx_packets != NULL) { + u8_t sent; + u16_t ret; + ret = pbuf_copy_partial(txcounters.tx_packets, &sent, 1, 40U); + EXPECT(ret == 1); + EXPECT(sent == expected); + } + if (txcounters.tx_packets != NULL) { + pbuf_free(txcounters.tx_packets); + txcounters.tx_packets = NULL; + } + } + + /* make sure the pcb is freed */ + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT_RET(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} + +START_TEST(test_tcp_tx_full_window_lost_from_unsent) +{ + LWIP_UNUSED_ARG(_i); + test_tcp_tx_full_window_lost(1); +} +END_TEST + +START_TEST(test_tcp_tx_full_window_lost_from_unacked) +{ + LWIP_UNUSED_ARG(_i); + test_tcp_tx_full_window_lost(0); +} +END_TEST /** Create the suite including all tests for this module */ Suite * @@ -99,6 +661,11 @@ tcp_suite(void) TFun tests[] = { test_tcp_new_abort, test_tcp_recv_inseq, + test_tcp_fast_retx_recover, + test_tcp_fast_rexmit_wraparound, + test_tcp_rto_rexmit_wraparound, + test_tcp_tx_full_window_lost_from_unacked, + test_tcp_tx_full_window_lost_from_unsent }; return create_suite("TCP", tests, sizeof(tests)/sizeof(TFun), tcp_setup, tcp_teardown); } diff --git a/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c b/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c index 56944e202e2..49deda0919b 100644 --- a/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c +++ b/reactos/lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c @@ -36,6 +36,18 @@ static int tcp_oos_count(struct tcp_pcb* pcb) return num; } +/** Get the numbers of pbufs on the ooseq list */ +static int tcp_oos_pbuf_count(struct tcp_pcb* pcb) +{ + int num = 0; + struct tcp_seg* seg = pcb->ooseq; + while(seg != NULL) { + num += pbuf_clen(seg->p); + seg = seg->next; + } + return num; +} + /** Get the seqno of a segment (by index) on the ooseq list * * @param pcb the pcb to check for ooseq segments @@ -115,6 +127,8 @@ static void tcp_oos_teardown(void) { tcp_remove_all(); + netif_list = NULL; + netif_default = NULL; } @@ -134,7 +148,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - ip_addr_t remote_ip, local_ip; + ip_addr_t remote_ip, local_ip, netmask; u16_t data_len; u16_t remote_port = 0x100, local_port = 0x101; struct netif netif; @@ -144,6 +158,8 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ) memset(&netif, 0, sizeof(netif)); IP4_ADDR(&local_ip, 192, 168, 1, 1); IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); data_len = sizeof(data); /* initialize counter struct */ memset(&counters, 0, sizeof(counters)); @@ -274,7 +290,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - ip_addr_t remote_ip, local_ip; + ip_addr_t remote_ip, local_ip, netmask; u16_t data_len; u16_t remote_port = 0x100, local_port = 0x101; struct netif netif; @@ -284,6 +300,8 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ) memset(&netif, 0, sizeof(netif)); IP4_ADDR(&local_ip, 192, 168, 1, 1); IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); data_len = sizeof(data); /* initialize counter struct */ memset(&counters, 0, sizeof(counters)); @@ -440,16 +458,16 @@ static char data_full_wnd[TCP_WND]; * to simulate overruning the rxwin with ooseq queueing enabled */ START_TEST(test_tcp_recv_ooseq_overrun_rxwin) { +#if !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS int i, k; struct test_tcp_counters counters; struct tcp_pcb* pcb; struct pbuf *pinseq, *p_ovr; - ip_addr_t remote_ip, local_ip; + ip_addr_t remote_ip, local_ip, netmask; u16_t remote_port = 0x100, local_port = 0x101; struct netif netif; int datalen = 0; int datalen2; - LWIP_UNUSED_ARG(_i); for(i = 0; i < sizeof(data_full_wnd); i++) { data_full_wnd[i] = (char)i; @@ -459,6 +477,8 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin) memset(&netif, 0, sizeof(netif)); IP4_ADDR(&local_ip, 192, 168, 1, 1); IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); /* initialize counter struct */ memset(&counters, 0, sizeof(counters)); counters.expected_data_len = TCP_WND; @@ -478,7 +498,7 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin) int count, expected_datalen; struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); - EXPECT(p != NULL); + EXPECT_RET(p != NULL); /* pass the segment to tcp_input */ test_tcp_input(p, &netif); /* check if counters are as expected */ @@ -502,7 +522,7 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin) /* pass in one more segment, cleary overrunning the rxwin */ p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK); - EXPECT(p_ovr != NULL); + EXPECT_RET(p_ovr != NULL); /* pass the segment to tcp_input */ test_tcp_input(p_ovr, &netif); /* check if counters are as expected */ @@ -523,9 +543,389 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin) EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); tcp_abort(pcb); EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +#endif /* !TCP_OOSEQ_MAX_BYTES && !TCP_OOSEQ_MAX_PBUFS */ + LWIP_UNUSED_ARG(_i); } END_TEST +START_TEST(test_tcp_recv_ooseq_max_bytes) +{ +#if TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) + int i, k; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p_ovr; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + int datalen = 0; + int datalen2; + + for(i = 0; i < sizeof(data_full_wnd); i++) { + data_full_wnd[i] = (char)i; + } + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = TCP_WND; + counters.expected_data = data_full_wnd; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->rcv_nxt = 0x8000; + + /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */ + + /* create segments and 'recv' them */ + for(k = 1, i = 1; k < TCP_OOSEQ_MAX_BYTES; k += TCP_MSS, i++) { + int count; + struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[k], + TCP_MSS, k, 0, TCP_ACK); + EXPECT_RET(p != NULL); + EXPECT_RET(p->next == NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + count = tcp_oos_pbuf_count(pcb); + EXPECT_OOSEQ(count == i); + datalen = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen == (i * TCP_MSS)); + } + + /* pass in one more segment, overrunning the limit */ + p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[k+1], 1, k+1, 0, TCP_ACK); + EXPECT_RET(p_ovr != NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p_ovr, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue (ensure the new segment was not accepted) */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1)); + datalen2 = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen2 == ((i-1) * TCP_MSS)); + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +#endif /* TCP_OOSEQ_MAX_BYTES && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */ + LWIP_UNUSED_ARG(_i); +} +END_TEST + +START_TEST(test_tcp_recv_ooseq_max_pbufs) +{ +#if TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_PBUFS < ((TCP_WND / TCP_MSS) + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) + int i; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p_ovr; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + int datalen = 0; + int datalen2; + + for(i = 0; i < sizeof(data_full_wnd); i++) { + data_full_wnd[i] = (char)i; + } + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = TCP_WND; + counters.expected_data = data_full_wnd; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->rcv_nxt = 0x8000; + + /* don't 'recv' the first segment (1 byte) so that all other segments will be ooseq */ + + /* create segments and 'recv' them */ + for(i = 1; i <= TCP_OOSEQ_MAX_PBUFS; i++) { + int count; + struct pbuf *p = tcp_create_rx_segment(pcb, &data_full_wnd[i], + 1, i, 0, TCP_ACK); + EXPECT_RET(p != NULL); + EXPECT_RET(p->next == NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue */ + count = tcp_oos_pbuf_count(pcb); + EXPECT_OOSEQ(count == i); + datalen = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen == i); + } + + /* pass in one more segment, overrunning the limit */ + p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[i+1], 1, i+1, 0, TCP_ACK); + EXPECT_RET(p_ovr != NULL); + /* pass the segment to tcp_input */ + test_tcp_input(p_ovr, &netif); + /* check if counters are as expected */ + EXPECT(counters.close_calls == 0); + EXPECT(counters.recv_calls == 0); + EXPECT(counters.recved_bytes == 0); + EXPECT(counters.err_calls == 0); + /* check ooseq queue (ensure the new segment was not accepted) */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == (i-1)); + datalen2 = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(datalen2 == (i-1)); + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +#endif /* TCP_OOSEQ_MAX_PBUFS && (TCP_OOSEQ_MAX_BYTES < (TCP_WND + 1)) && (PBUF_POOL_BUFSIZE >= (TCP_MSS + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) */ + LWIP_UNUSED_ARG(_i); +} +END_TEST + +static void +check_rx_counters(struct tcp_pcb *pcb, struct test_tcp_counters *counters, u32_t exp_close_calls, u32_t exp_rx_calls, + u32_t exp_rx_bytes, u32_t exp_err_calls, int exp_oos_count, int exp_oos_len) +{ + int oos_len; + EXPECT(counters->close_calls == exp_close_calls); + EXPECT(counters->recv_calls == exp_rx_calls); + EXPECT(counters->recved_bytes == exp_rx_bytes); + EXPECT(counters->err_calls == exp_err_calls); + /* check that pbuf is queued in ooseq */ + EXPECT_OOSEQ(tcp_oos_count(pcb) == exp_oos_count); + oos_len = tcp_oos_tcplen(pcb); + EXPECT_OOSEQ(exp_oos_len == oos_len); +} + +/* this test uses 4 packets: + * - data (len=TCP_MSS) + * - FIN + * - data after FIN (len=1) (invalid) + * - 2nd FIN (invalid) + * + * the parameter 'delay_packet' is a bitmask that choses which on these packets is ooseq + */ +static void test_tcp_recv_ooseq_double_FINs(int delay_packet) +{ + int i, k; + struct test_tcp_counters counters; + struct tcp_pcb* pcb; + struct pbuf *p_normal_fin, *p_data_after_fin, *p, *p_2nd_fin_ooseq; + ip_addr_t remote_ip, local_ip, netmask; + u16_t remote_port = 0x100, local_port = 0x101; + struct netif netif; + u32_t exp_rx_calls = 0, exp_rx_bytes = 0, exp_close_calls = 0, exp_oos_pbufs = 0, exp_oos_tcplen = 0; + int first_dropped = 0xff; + int last_dropped = 0; + + for(i = 0; i < sizeof(data_full_wnd); i++) { + data_full_wnd[i] = (char)i; + } + + /* initialize local vars */ + memset(&netif, 0, sizeof(netif)); + IP4_ADDR(&local_ip, 192, 168, 1, 1); + IP4_ADDR(&remote_ip, 192, 168, 1, 2); + IP4_ADDR(&netmask, 255, 255, 255, 0); + test_tcp_init_netif(&netif, NULL, &local_ip, &netmask); + /* initialize counter struct */ + memset(&counters, 0, sizeof(counters)); + counters.expected_data_len = TCP_WND; + counters.expected_data = data_full_wnd; + + /* create and initialize the pcb */ + pcb = test_tcp_new_counters_pcb(&counters); + EXPECT_RET(pcb != NULL); + tcp_set_state(pcb, ESTABLISHED, &local_ip, &remote_ip, local_port, remote_port); + pcb->rcv_nxt = 0x8000; + + /* create segments */ + p = tcp_create_rx_segment(pcb, &data_full_wnd[0], TCP_MSS, 0, 0, TCP_ACK); + p_normal_fin = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS, 0, TCP_ACK|TCP_FIN); + k = 1; + p_data_after_fin = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS+1], k, TCP_MSS+1, 0, TCP_ACK); + p_2nd_fin_ooseq = tcp_create_rx_segment(pcb, NULL, 0, TCP_MSS+1+k, 0, TCP_ACK|TCP_FIN); + + if(delay_packet & 1) { + /* drop normal data */ + first_dropped = 1; + last_dropped = 1; + } else { + /* send normal data */ + test_tcp_input(p, &netif); + exp_rx_calls++; + exp_rx_bytes += TCP_MSS; + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 2) { + /* drop FIN */ + if(first_dropped > 2) { + first_dropped = 2; + } + last_dropped = 2; + } else { + /* send FIN */ + test_tcp_input(p_normal_fin, &netif); + if (first_dropped < 2) { + /* already dropped packets, this one is ooseq */ + exp_oos_pbufs++; + exp_oos_tcplen++; + } else { + /* inseq */ + exp_close_calls++; + } + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 4) { + /* drop data-after-FIN */ + if(first_dropped > 3) { + first_dropped = 3; + } + last_dropped = 3; + } else { + /* send data-after-FIN */ + test_tcp_input(p_data_after_fin, &netif); + if (first_dropped < 3) { + /* already dropped packets, this one is ooseq */ + if (delay_packet & 2) { + /* correct FIN was ooseq */ + exp_oos_pbufs++; + exp_oos_tcplen += k; + } + } else { + /* inseq: no change */ + } + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 8) { + /* drop 2nd-FIN */ + if(first_dropped > 4) { + first_dropped = 4; + } + last_dropped = 4; + } else { + /* send 2nd-FIN */ + test_tcp_input(p_2nd_fin_ooseq, &netif); + if (first_dropped < 3) { + /* already dropped packets, this one is ooseq */ + if (delay_packet & 2) { + /* correct FIN was ooseq */ + exp_oos_pbufs++; + exp_oos_tcplen++; + } + } else { + /* inseq: no change */ + } + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 1) { + /* dropped normal data before */ + test_tcp_input(p, &netif); + exp_rx_calls++; + exp_rx_bytes += TCP_MSS; + if((delay_packet & 2) == 0) { + /* normal FIN was NOT delayed */ + exp_close_calls++; + exp_oos_pbufs = exp_oos_tcplen = 0; + } + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 2) { + /* dropped normal FIN before */ + test_tcp_input(p_normal_fin, &netif); + exp_close_calls++; + exp_oos_pbufs = exp_oos_tcplen = 0; + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 4) { + /* dropped data-after-FIN before */ + test_tcp_input(p_data_after_fin, &netif); + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + if(delay_packet & 8) { + /* dropped 2nd-FIN before */ + test_tcp_input(p_2nd_fin_ooseq, &netif); + } + /* check if counters are as expected */ + check_rx_counters(pcb, &counters, exp_close_calls, exp_rx_calls, exp_rx_bytes, 0, exp_oos_pbufs, exp_oos_tcplen); + + /* check that ooseq data has been dumped */ + EXPECT(pcb->ooseq == NULL); + + /* make sure the pcb is freed */ + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 1); + tcp_abort(pcb); + EXPECT(lwip_stats.memp[MEMP_TCP_PCB].used == 0); +} + +/** create multiple segments and pass them to tcp_input with the first segment missing + * to simulate overruning the rxwin with ooseq queueing enabled */ +#define FIN_TEST(name, num) \ + START_TEST(name) \ + { \ + LWIP_UNUSED_ARG(_i); \ + test_tcp_recv_ooseq_double_FINs(num); \ + } \ + END_TEST +FIN_TEST(test_tcp_recv_ooseq_double_FIN_0, 0) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_1, 1) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_2, 2) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_3, 3) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_4, 4) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_5, 5) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_6, 6) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_7, 7) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_8, 8) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_9, 9) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_10, 10) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_11, 11) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_12, 12) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_13, 13) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_14, 14) +FIN_TEST(test_tcp_recv_ooseq_double_FIN_15, 15) + /** Create the suite including all tests for this module */ Suite * @@ -535,6 +935,24 @@ tcp_oos_suite(void) test_tcp_recv_ooseq_FIN_OOSEQ, test_tcp_recv_ooseq_FIN_INSEQ, test_tcp_recv_ooseq_overrun_rxwin, + test_tcp_recv_ooseq_max_bytes, + test_tcp_recv_ooseq_max_pbufs, + test_tcp_recv_ooseq_double_FIN_0, + test_tcp_recv_ooseq_double_FIN_1, + test_tcp_recv_ooseq_double_FIN_2, + test_tcp_recv_ooseq_double_FIN_3, + test_tcp_recv_ooseq_double_FIN_4, + test_tcp_recv_ooseq_double_FIN_5, + test_tcp_recv_ooseq_double_FIN_6, + test_tcp_recv_ooseq_double_FIN_7, + test_tcp_recv_ooseq_double_FIN_8, + test_tcp_recv_ooseq_double_FIN_9, + test_tcp_recv_ooseq_double_FIN_10, + test_tcp_recv_ooseq_double_FIN_11, + test_tcp_recv_ooseq_double_FIN_12, + test_tcp_recv_ooseq_double_FIN_13, + test_tcp_recv_ooseq_double_FIN_14, + test_tcp_recv_ooseq_double_FIN_15 }; return create_suite("TCP_OOS", tests, sizeof(tests)/sizeof(TFun), tcp_oos_setup, tcp_oos_teardown); -} +} \ No newline at end of file From ec8ff3a9062b238b84d56a7a36d4976095755419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Mon, 29 Apr 2013 16:17:46 +0000 Subject: [PATCH 06/67] [NTOSKRNL/V86VDM] - Merge the EFLAGS register instead of overwriting it when restoring it from a POPF call. svn path=/trunk/; revision=58892 --- reactos/ntoskrnl/ke/i386/v86vdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/ke/i386/v86vdm.c b/reactos/ntoskrnl/ke/i386/v86vdm.c index 9a0c6e01cdc..8f241bedd50 100644 --- a/reactos/ntoskrnl/ke/i386/v86vdm.c +++ b/reactos/ntoskrnl/ke/i386/v86vdm.c @@ -155,7 +155,7 @@ KiVdmOpcodePOPF(IN PKTRAP_FRAME TrapFrame, V86EFlags |= EFLAGS_V86_MASK; /* Update EFlags in trap frame */ - TrapFrame->EFlags = V86EFlags; + TrapFrame->EFlags |= V86EFlags; /* Check if ESP0 needs to be fixed up */ if (TrapEFlags & EFLAGS_V86_MASK) Ki386AdjustEsp0(TrapFrame); From 6cdfa4a25c895f22667c35127eac67be8f086227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 29 Apr 2013 23:49:52 +0000 Subject: [PATCH 07/67] [HOSTNAME] Unicodify and add localization support. Patch by Lee Schroeder, simplified by me. CORE-7142 #resolve #comment Committed in revision r58893, thanks! [REGEDIT] "Neutralize" common resources. svn path=/trunk/; revision=58893 --- .../cmdutils/hostname/CMakeLists.txt | 4 +- .../applications/cmdutils/hostname/hostname.c | 68 +++++++++++-------- .../cmdutils/hostname/hostname.rc | 14 +++- .../cmdutils/hostname/lang/en-US.rc | 8 +++ .../cmdutils/hostname/lang/fr-FR.rc | 8 +++ .../applications/cmdutils/hostname/resource.h | 8 +++ .../applications/cmdutils/hostname/rsrc.rc | 11 +++ reactos/base/applications/regedit/regedit.rc | 8 +-- 8 files changed, 93 insertions(+), 36 deletions(-) create mode 100644 reactos/base/applications/cmdutils/hostname/lang/en-US.rc create mode 100644 reactos/base/applications/cmdutils/hostname/lang/fr-FR.rc create mode 100644 reactos/base/applications/cmdutils/hostname/resource.h create mode 100644 reactos/base/applications/cmdutils/hostname/rsrc.rc diff --git a/reactos/base/applications/cmdutils/hostname/CMakeLists.txt b/reactos/base/applications/cmdutils/hostname/CMakeLists.txt index d9e9edac79f..fec5032e916 100644 --- a/reactos/base/applications/cmdutils/hostname/CMakeLists.txt +++ b/reactos/base/applications/cmdutils/hostname/CMakeLists.txt @@ -1,6 +1,6 @@ add_executable(hostname hostname.c hostname.rc) -set_module_type(hostname win32cui) -add_importlibs(hostname msvcrt kernel32) +set_module_type(hostname win32cui UNICODE) +add_importlibs(hostname user32 msvcrt kernel32) add_cd_file(TARGET hostname DESTINATION reactos/system32 FOR all) diff --git a/reactos/base/applications/cmdutils/hostname/hostname.c b/reactos/base/applications/cmdutils/hostname/hostname.c index 759015f5d94..4e49c5d4182 100644 --- a/reactos/base/applications/cmdutils/hostname/hostname.c +++ b/reactos/base/applications/cmdutils/hostname/hostname.c @@ -23,38 +23,52 @@ * PROGRAMMER: Emanuele Aliberti (ea@reactos.com) */ -#include -#include -//#include +#include #include #include +#include -int main (int argc, char ** argv) +#include "resource.h" + +int wmain(int argc, WCHAR* argv[]) { - if (1 == argc) - { - TCHAR ComputerName [MAX_COMPUTERNAME_LENGTH + 1]; - DWORD ComputerNameSize = sizeof ComputerName / sizeof ComputerName[0]; + WCHAR Msg[100]; - ZeroMemory (ComputerName, sizeof ComputerName ); - if (GetComputerName(ComputerName, & ComputerNameSize)) - { - printf ("%s\n", ComputerName); - return EXIT_SUCCESS; - } - fprintf (stderr, "%s: Win32 error %lu.\n", - argv[0], GetLastError()); - return EXIT_FAILURE; - }else{ - if (0 == strcmp(argv[1],"-s")) - { - fprintf(stderr,"%s: -s not supported.\n",argv[0]); - return EXIT_FAILURE; - }else{ - printf("Print the current host's name.\n\nhostname\n"); - } - } - return EXIT_SUCCESS; + if (1 == argc) + { + WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1] = L""; + DWORD ComputerNameSize = sizeof(ComputerName) / sizeof(ComputerName[0]); + + if (!GetComputerName(ComputerName, &ComputerNameSize)) + { + /* Fail in case of error */ + LoadStringW(GetModuleHandle(NULL), IDS_ERROR, Msg, 100); + _cwprintf(L"%s %lu.\n", Msg, GetLastError()); + return 1; + } + + /* Print out the computer's name */ + _cwprintf(L"%s\n", ComputerName); + } + else + { + if ((wcsicmp(argv[1], L"-s") == 0) || (wcsicmp(argv[1], L"/s") == 0)) + { + /* The program doesn't allow the user to set the computer's name */ + LoadStringW(GetModuleHandle(NULL), IDS_NOSET, Msg, 100); + _cwprintf(L"%s\n", Msg); + return 1; + } + else + { + /* Let the user know what the program does */ + LoadStringW(GetModuleHandle(NULL), IDS_USAGE, Msg, 100); + _cwprintf(L"\n%s\n\n", Msg); + } + } + + return 0; } + /* EOF */ diff --git a/reactos/base/applications/cmdutils/hostname/hostname.rc b/reactos/base/applications/cmdutils/hostname/hostname.rc index 227ff6a10fe..368c0b8f58e 100644 --- a/reactos/base/applications/cmdutils/hostname/hostname.rc +++ b/reactos/base/applications/cmdutils/hostname/hostname.rc @@ -1,4 +1,12 @@ -#define REACTOS_STR_FILE_DESCRIPTION "Win32 Get local host name\0" -#define REACTOS_STR_INTERNAL_NAME "hostname\0" -#define REACTOS_STR_ORIGINAL_FILENAME "hostname.exe\0" +#include + +#include "resource.h" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +#define REACTOS_STR_FILE_DESCRIPTION "Host name application" +#define REACTOS_STR_INTERNAL_NAME "hostname" +#define REACTOS_STR_ORIGINAL_FILENAME "hostname.exe" #include + +#include "rsrc.rc" diff --git a/reactos/base/applications/cmdutils/hostname/lang/en-US.rc b/reactos/base/applications/cmdutils/hostname/lang/en-US.rc new file mode 100644 index 00000000000..84bc606fa21 --- /dev/null +++ b/reactos/base/applications/cmdutils/hostname/lang/en-US.rc @@ -0,0 +1,8 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE DISCARDABLE +BEGIN + IDS_USAGE, "Print the current host's name.\n\nhostname" + IDS_NOSET, "hostname -s is not supported." + IDS_ERROR, "Win32 error" +END diff --git a/reactos/base/applications/cmdutils/hostname/lang/fr-FR.rc b/reactos/base/applications/cmdutils/hostname/lang/fr-FR.rc new file mode 100644 index 00000000000..751ae691633 --- /dev/null +++ b/reactos/base/applications/cmdutils/hostname/lang/fr-FR.rc @@ -0,0 +1,8 @@ +LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +BEGIN + IDS_USAGE, "Affiche le nom de l'hôte actuel.\n\nhostname" + IDS_NOSET, "hostname -s n'est pas pris en charge." + IDS_ERROR, "Erreur Win32" +END diff --git a/reactos/base/applications/cmdutils/hostname/resource.h b/reactos/base/applications/cmdutils/hostname/resource.h new file mode 100644 index 00000000000..1a17b7b8a2c --- /dev/null +++ b/reactos/base/applications/cmdutils/hostname/resource.h @@ -0,0 +1,8 @@ +#ifndef RESOURCE_H +#define RESOURCE_H + +#define IDS_USAGE 0 +#define IDS_NOSET 1 +#define IDS_ERROR 2 + +#endif /* RESOURCE_H */ diff --git a/reactos/base/applications/cmdutils/hostname/rsrc.rc b/reactos/base/applications/cmdutils/hostname/rsrc.rc new file mode 100644 index 00000000000..5177a1c5183 --- /dev/null +++ b/reactos/base/applications/cmdutils/hostname/rsrc.rc @@ -0,0 +1,11 @@ +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +// UTF-8 +#pragma code_page(65001) + +#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +#endif +#ifdef LANGUAGE_FR_FR + #include "lang/fr-FR.rc" +#endif diff --git a/reactos/base/applications/regedit/regedit.rc b/reactos/base/applications/regedit/regedit.rc index 456ff4d1759..d25727bf783 100644 --- a/reactos/base/applications/regedit/regedit.rc +++ b/reactos/base/applications/regedit/regedit.rc @@ -24,12 +24,12 @@ #include "resource.h" -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Registry Explorer\0" -#define REACTOS_STR_INTERNAL_NAME "regedit\0" -#define REACTOS_STR_ORIGINAL_FILENAME "regedit.exe\0" +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Registry Explorer" +#define REACTOS_STR_INTERNAL_NAME "regedit" +#define REACTOS_STR_ORIGINAL_FILENAME "regedit.exe" #include -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #include "rsrc.rc" From 82cd964e20a8fcc0ca946a0c6f89550bc9ed7d72 Mon Sep 17 00:00:00 2001 From: Ziliang Guo Date: Tue, 30 Apr 2013 02:57:30 +0000 Subject: [PATCH 08/67] [NET] Implementation of pause, continue, and help commands for net service application. Patch by theflash. Core-7131 #resolve svn path=/trunk/; revision=58894 --- .../applications/network/net/CMakeLists.txt | 3 ++ .../applications/network/net/cmdContinue.c | 51 +++++++++++++++++++ .../applications/network/net/cmdHelpMsg.c | 47 +++++++++++++++++ .../base/applications/network/net/cmdPause.c | 50 ++++++++++++++++++ reactos/base/applications/network/net/help.c | 2 +- reactos/base/applications/network/net/main.c | 7 +-- reactos/base/applications/network/net/net.h | 3 ++ 7 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 reactos/base/applications/network/net/cmdContinue.c create mode 100644 reactos/base/applications/network/net/cmdHelpMsg.c create mode 100644 reactos/base/applications/network/net/cmdPause.c diff --git a/reactos/base/applications/network/net/CMakeLists.txt b/reactos/base/applications/network/net/CMakeLists.txt index 279abd3d302..728cb077d02 100644 --- a/reactos/base/applications/network/net/CMakeLists.txt +++ b/reactos/base/applications/network/net/CMakeLists.txt @@ -5,6 +5,9 @@ list(APPEND SOURCE main.c cmdstart.c cmdStop.c + cmdHelpMsg.c + cmdPause.c + cmdContinue.c help.c) add_executable(net ${SOURCE}) diff --git a/reactos/base/applications/network/net/cmdContinue.c b/reactos/base/applications/network/net/cmdContinue.c new file mode 100644 index 00000000000..d8b69c82e6b --- /dev/null +++ b/reactos/base/applications/network/net/cmdContinue.c @@ -0,0 +1,51 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS net command + * FILE: cmdContinue.c + * PURPOSE: + * + * PROGRAMMERS: Aleksandar Andrejevic + */ + +#include "net.h" + +int cmdContinue(int argc, wchar_t *argv[]) +{ + int errorCode = 0; + SC_HANDLE hManager, hService; + SERVICE_STATUS status; + if(argc != 3) + { + puts("Usage: NET CONTINUE "); + return 1; + } + + hManager=OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE); + if(hManager == NULL) + { + printf("[OpenSCManager] Error: %d\n", errorCode = GetLastError()); + return errorCode; + } + + hService = OpenService(hManager, argv[2], SERVICE_PAUSE_CONTINUE); + + if(hService == NULL) + { + printf("[OpenService] Error: %d\n", errorCode=GetLastError()); + CloseServiceHandle(hManager); + return errorCode; + } + + if(!ControlService(hService, SERVICE_CONTROL_CONTINUE, &status)) + { + printf("[ControlService] Error: %d\n", errorCode=GetLastError()); + } + + CloseServiceHandle(hService); + CloseServiceHandle(hManager); + + return errorCode; +} + +/* EOF */ + diff --git a/reactos/base/applications/network/net/cmdHelpMsg.c b/reactos/base/applications/network/net/cmdHelpMsg.c new file mode 100644 index 00000000000..15a66c95724 --- /dev/null +++ b/reactos/base/applications/network/net/cmdHelpMsg.c @@ -0,0 +1,47 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS net command + * FILE: cmdHelpmsg.c + * PURPOSE: + * + * PROGRAMMERS: Aleksandar Andrejevic + */ + +#include "net.h" +#include "stdlib.h" + +int cmdHelpMsg(int argc, wchar_t *argv[]) +{ + wchar_t *endptr; + LPSTR lpBuffer; + if(argc<3) + { + puts("Usage: NET HELPMSG "); + return 1; + } + long errNum=wcstol(argv[2], &endptr, 10); + if(*endptr != 0) + { + puts("Usage: NET HELPMSG "); + return 1; + } + + /* Unicode printing is not supported in ReactOS yet */ + if(FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + errNum, + LANG_USER_DEFAULT, + (LPSTR)&lpBuffer, + 0, + NULL)) + { + printf("\n%s\n", lpBuffer); + LocalFree(lpBuffer); + } + else printf("Unrecognized error code: %ld\n", errNum); + + return 0; +} + +/* EOF */ + diff --git a/reactos/base/applications/network/net/cmdPause.c b/reactos/base/applications/network/net/cmdPause.c new file mode 100644 index 00000000000..2731a605ad7 --- /dev/null +++ b/reactos/base/applications/network/net/cmdPause.c @@ -0,0 +1,50 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS net command + * FILE: cmdPause.c + * PURPOSE: + * + * PROGRAMMERS: Aleksandar Andrejevic + */ + +#include "net.h" + +int cmdPause(int argc, wchar_t *argv[]) +{ + int errorCode=0; + SC_HANDLE hManager, hService; + SERVICE_STATUS status; + if(argc != 3) + { + puts("Usage: NET PAUSE "); + return 1; + } + + hManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE); + if(hManager == NULL) + { + printf("[OpenSCManager] Error: %d\n", errorCode=GetLastError()); + return errorCode; + } + + hService=OpenService(hManager, argv[2], SERVICE_PAUSE_CONTINUE); + if(hService == NULL) + { + printf("[OpenService] Error: %d\n", errorCode=GetLastError()); + CloseServiceHandle(hManager); + return errorCode; + } + + if(!ControlService(hService, SERVICE_CONTROL_PAUSE, &status)) + { + printf("[ControlService] Error: %d\n", errorCode=GetLastError()); + } + + CloseServiceHandle(hService); + CloseServiceHandle(hManager); + + return errorCode; +} + +/* EOF */ + diff --git a/reactos/base/applications/network/net/help.c b/reactos/base/applications/network/net/help.c index 4e33cc2b1bf..089f4a64f20 100644 --- a/reactos/base/applications/network/net/help.c +++ b/reactos/base/applications/network/net/help.c @@ -11,7 +11,7 @@ INT cmdHelp(INT argc, WCHAR **argv) { - if (argc > 3) + if (argc != 3) { return 0; } diff --git a/reactos/base/applications/network/net/main.c b/reactos/base/applications/network/net/main.c index 638a21f3d33..8f226967d2c 100644 --- a/reactos/base/applications/network/net/main.c +++ b/reactos/base/applications/network/net/main.c @@ -21,14 +21,15 @@ COMMAND cmds[] = {L"accounts", unimplemented}, {L"computer", unimplemented}, {L"config", unimplemented}, - {L"continue", unimplemented}, + {L"continue", cmdContinue}, {L"file", unimplemented}, {L"group", unimplemented}, {L"help", cmdHelp}, - {L"helpmsg", unimplemented}, + {L"helpmsg", cmdHelpMsg}, {L"localgroup", unimplemented}, {L"name", unimplemented}, {L"print", unimplemented}, + {L"pause", cmdPause}, {L"send", unimplemented}, {L"session", unimplemented}, {L"share", unimplemented}, @@ -39,7 +40,7 @@ COMMAND cmds[] = {L"use", unimplemented}, {L"user", unimplemented}, {L"view", unimplemented}, - + {NULL, NULL} }; int wmain(int argc, WCHAR **argv) diff --git a/reactos/base/applications/network/net/net.h b/reactos/base/applications/network/net/net.h index f7c11239520..660033f0be2 100644 --- a/reactos/base/applications/network/net/net.h +++ b/reactos/base/applications/network/net/net.h @@ -19,3 +19,6 @@ INT unimplemented(INT argc, WCHAR **argv); INT cmdHelp(INT argc, WCHAR **argv); INT cmdStart(INT argc, WCHAR **argv); INT cmdStop(INT argc, WCHAR **argv); +int cmdHelpMsg(int argc, wchar_t *argv[]); +int cmdPause(int argc, wchar_t *argv[]); +int cmdContinue(int argc, wchar_t *argv[]); From a0d79bf7b9e0fd3a9a3eee47741ec263a2d3cf33 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 30 Apr 2013 08:16:29 +0000 Subject: [PATCH 09/67] [LWIP] - Don't define mem_trim() to realloc() because mem_trim() must never move the buffer pointer - Fix realloc() which was completely broken - Properly handle a TX|RX shutdown svn path=/trunk/; revision=58895 --- .../lib/drivers/lwip/src/include/arch/cc.h | 4 ++- reactos/lib/drivers/lwip/src/rosmem.c | 29 +++++++++++++++- reactos/lib/drivers/lwip/src/rostcp.c | 33 +++++-------------- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/reactos/lib/drivers/lwip/src/include/arch/cc.h b/reactos/lib/drivers/lwip/src/include/arch/cc.h index 91d6b5a27d9..8a6d20066d1 100755 --- a/reactos/lib/drivers/lwip/src/include/arch/cc.h +++ b/reactos/lib/drivers/lwip/src/include/arch/cc.h @@ -15,7 +15,9 @@ free(void *mem); void * realloc(void *mem, size_t size); -#define mem_trim(_m_, _s_) realloc(_m_, _s_) +/* mem_trim() must trim the buffer without relocating it. + * Since we can't do that, we just return the buffer passed in unchanged */ +#define mem_trim(_m_, _s_) (_m_) /* Unsigned int types */ typedef unsigned char u8_t; diff --git a/reactos/lib/drivers/lwip/src/rosmem.c b/reactos/lib/drivers/lwip/src/rosmem.c index 4fdb84d3c8c..e1dccb63f48 100755 --- a/reactos/lib/drivers/lwip/src/rosmem.c +++ b/reactos/lib/drivers/lwip/src/rosmem.c @@ -31,9 +31,36 @@ free(void *mem) ExFreePoolWithTag(mem, LWIP_TAG); } +/* This is only used to trim in lwIP */ void * realloc(void *mem, size_t size) { + void* new_mem; + + /* realloc() with a NULL mem pointer acts like a call to malloc() */ + if (mem == NULL) { + return malloc(size); + } + + /* realloc() with a size 0 acts like a call to free() */ + if (size == 0) { + free(mem); + return NULL; + } + + /* Allocate the new buffer first */ + new_mem = malloc(size); + if (new_mem == NULL) { + /* The old buffer is still intact */ + return NULL; + } + + /* Copy the data over */ + RtlCopyMemory(new_mem, mem, size); + + /* Deallocate the old buffer */ free(mem); - return malloc(size); + + /* Return the newly allocated block */ + return new_mem; } \ No newline at end of file diff --git a/reactos/lib/drivers/lwip/src/rostcp.c b/reactos/lib/drivers/lwip/src/rostcp.c index 93e7eb2a787..b094775ecd8 100755 --- a/reactos/lib/drivers/lwip/src/rostcp.c +++ b/reactos/lib/drivers/lwip/src/rostcp.c @@ -631,18 +631,8 @@ LibTCPShutdownCallback(void *arg) goto done; } - if (pcb->state == CLOSE_WAIT) - { - /* This case actually results in a socket closure later (lwIP bug?) */ - msg->Input.Shutdown.Connection->SocketContext = NULL; - } - msg->Output.Shutdown.Error = tcp_shutdown(pcb, msg->Input.Shutdown.shut_rx, msg->Input.Shutdown.shut_tx); - if (msg->Output.Shutdown.Error) - { - msg->Input.Shutdown.Connection->SocketContext = pcb; - } - else + if (!msg->Output.Shutdown.Error) { if (msg->Input.Shutdown.shut_rx) { @@ -652,6 +642,10 @@ LibTCPShutdownCallback(void *arg) if (msg->Input.Shutdown.shut_tx) msg->Input.Shutdown.Connection->SendShutdown = TRUE; + + /* Shutting down both sides is like a close to LwIP, so clear the context */ + if (msg->Input.Shutdown.shut_rx && msg->Input.Shutdown.shut_tx) + msg->Input.Shutdown.Connection->SocketContext = NULL; } done: @@ -712,6 +706,7 @@ LibTCPCloseCallback(void *arg) case CLOSED: case LISTEN: case SYN_SENT: + case CLOSE_WAIT: msg->Output.Close.Error = tcp_close(pcb); if (!msg->Output.Close.Error && msg->Input.Close.Callback) @@ -719,20 +714,8 @@ LibTCPCloseCallback(void *arg) break; default: - if (msg->Input.Close.Connection->SendShutdown && - msg->Input.Close.Connection->ReceiveShutdown) - { - /* Abort the connection */ - tcp_abort(pcb); - - /* Aborts always succeed */ - msg->Output.Close.Error = ERR_OK; - } - else - { - /* Start the graceful close process (or send RST for pending data) */ - msg->Output.Close.Error = tcp_close(pcb); - } + /* Start the graceful close process (or send RST for pending data) */ + msg->Output.Close.Error = tcp_close(pcb); break; } From 93ce06d95e836ebd341543fd688e6f2a14de3cad Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 30 Apr 2013 09:33:40 +0000 Subject: [PATCH 10/67] [LWIP] - Call tcp_shutdown() two different times for TX|RX shutdown to avoid the tcp_close() problem entirely - Forcefully close the socket in LibTCPCloseCallback (not optimal, but good enough) svn path=/trunk/; revision=58896 --- reactos/lib/drivers/lwip/src/rostcp.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/reactos/lib/drivers/lwip/src/rostcp.c b/reactos/lib/drivers/lwip/src/rostcp.c index b094775ecd8..1e7374828b0 100755 --- a/reactos/lib/drivers/lwip/src/rostcp.c +++ b/reactos/lib/drivers/lwip/src/rostcp.c @@ -631,7 +631,14 @@ LibTCPShutdownCallback(void *arg) goto done; } - msg->Output.Shutdown.Error = tcp_shutdown(pcb, msg->Input.Shutdown.shut_rx, msg->Input.Shutdown.shut_tx); + /* These need to be called separately, otherwise we get a tcp_close() */ + if (msg->Input.Shutdown.shut_rx) { + msg->Output.Shutdown.Error = tcp_shutdown(pcb, TRUE, FALSE); + } + if (msg->Input.Shutdown.shut_tx) { + msg->Output.Shutdown.Error = tcp_shutdown(pcb, FALSE, TRUE); + } + if (!msg->Output.Shutdown.Error) { if (msg->Input.Shutdown.shut_rx) @@ -642,10 +649,6 @@ LibTCPShutdownCallback(void *arg) if (msg->Input.Shutdown.shut_tx) msg->Input.Shutdown.Connection->SendShutdown = TRUE; - - /* Shutting down both sides is like a close to LwIP, so clear the context */ - if (msg->Input.Shutdown.shut_rx && msg->Input.Shutdown.shut_tx) - msg->Input.Shutdown.Connection->SocketContext = NULL; } done: @@ -706,7 +709,6 @@ LibTCPCloseCallback(void *arg) case CLOSED: case LISTEN: case SYN_SENT: - case CLOSE_WAIT: msg->Output.Close.Error = tcp_close(pcb); if (!msg->Output.Close.Error && msg->Input.Close.Callback) @@ -714,8 +716,9 @@ LibTCPCloseCallback(void *arg) break; default: - /* Start the graceful close process (or send RST for pending data) */ - msg->Output.Close.Error = tcp_close(pcb); + /* Abort the socket */ + tcp_abort(pcb); + msg->Output.Close.Error = ERR_OK; break; } From 85c6b0f6b9d0d844bafe79f4cd209b5adb4b7da1 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 1 May 2013 09:10:34 +0000 Subject: [PATCH 11/67] [NTOSKRNL] Patch by Aleksey Bragin (he's not aware yet!): Also implement FsRtlIs*InExpression prologue in FsRtlIsDbcsInExpression (adapted from Aleksey's work on FsRtlIsNameInExpression) Also added support for Dbcs chars in it svn path=/trunk/; revision=58897 --- reactos/ntoskrnl/fsrtl/dbcsname.c | 62 ++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/dbcsname.c b/reactos/ntoskrnl/fsrtl/dbcsname.c index 3eedb32cc5b..b7bf7f0be5a 100644 --- a/reactos/ntoskrnl/fsrtl/dbcsname.c +++ b/reactos/ntoskrnl/fsrtl/dbcsname.c @@ -169,9 +169,67 @@ FsRtlIsDbcsInExpression(IN PANSI_STRING Expression, ASSERT(Expression->Length); ASSERT(!FsRtlDoesDbcsContainWildCards(Name)); - if (Name->Length == 0) + /* Check if we were given strings at all */ + if (!Name->Length || !Expression->Length) { - return (Expression->Length == 0); + /* Return TRUE if both strings are empty, otherwise FALSE */ + if (Name->Length == 0 && Expression->Length == 0) + return TRUE; + else + return FALSE; + } + + /* Check for a shortcut: just one wildcard */ + if (Expression->Length == sizeof(CHAR)) + { + if (Expression->Buffer[0] == '*') + return TRUE; + } + + //ASSERT(FsRtlDoesDbcsContainWildCards(Expression)); + + /* Another shortcut, wildcard followed by some string */ + if (Expression->Buffer[0] == '*') + { + /* Copy Expression to our local variable */ + ANSI_STRING IntExpression = *Expression; + + /* Skip the first char */ + IntExpression.Buffer++; + IntExpression.Length -= sizeof(CHAR); + + /* Continue only if the rest of the expression does NOT contain + any more wildcards */ + if (!FsRtlDoesDbcsContainWildCards(&IntExpression)) + { + /* Check for a degenerate case */ + if (Name->Length < (Expression->Length - sizeof(CHAR))) + return FALSE; + + /* Calculate position */ + NamePosition = (Name->Length - IntExpression.Length) / sizeof(CHAR); + + /* Check whether we are breaking a two chars char (DBCS) */ + if (NlsMbOemCodePageTag) + { + MatchingChars = 0; + + while (MatchingChars < NamePosition) + { + /* Check if current char is DBCS lead char, if so, jump by two chars */ + MatchingChars += FsRtlIsLeadDbcsCharacter(Name->Buffer[MatchingChars]) ? 2 : 1; + } + + /* If so, deny */ + if (MatchingChars > NamePosition) + return FALSE; + } + + /* Compare */ + return RtlEqualMemory(IntExpression.Buffer, + (Name->Buffer + NamePosition), + IntExpression.Length); + } } while (NamePosition < Name->Length && ExpressionPosition < Expression->Length) From 7ca3c9d2a7a6ad77abe5a2754bbe4c29de0c1787 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 1 May 2013 10:00:06 +0000 Subject: [PATCH 12/67] [NET] * Fix MSVC build. svn path=/trunk/; revision=58898 --- reactos/base/applications/network/net/cmdHelpMsg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/reactos/base/applications/network/net/cmdHelpMsg.c b/reactos/base/applications/network/net/cmdHelpMsg.c index 15a66c95724..5a2e5596a39 100644 --- a/reactos/base/applications/network/net/cmdHelpMsg.c +++ b/reactos/base/applications/network/net/cmdHelpMsg.c @@ -14,12 +14,14 @@ int cmdHelpMsg(int argc, wchar_t *argv[]) { wchar_t *endptr; LPSTR lpBuffer; + long errNum; + if(argc<3) { puts("Usage: NET HELPMSG "); return 1; } - long errNum=wcstol(argv[2], &endptr, 10); + errNum = wcstol(argv[2], &endptr, 10); if(*endptr != 0) { puts("Usage: NET HELPMSG "); From 1f1a1a93238b49ab198552c668c3b4716a095858 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 1 May 2013 10:54:02 +0000 Subject: [PATCH 13/67] [NTOSKRNL] Make post stack overflow functions use the same (unimplemented) helper function svn path=/trunk/; revision=58899 --- reactos/ntoskrnl/fsrtl/stackovf.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/stackovf.c b/reactos/ntoskrnl/fsrtl/stackovf.c index 5d0b4296ff2..14abfc0032a 100644 --- a/reactos/ntoskrnl/fsrtl/stackovf.c +++ b/reactos/ntoskrnl/fsrtl/stackovf.c @@ -12,6 +12,18 @@ #define NDEBUG #include +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +FsRtlpPostStackOverflow(IN PVOID Context, + IN PKEVENT Event, + IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine, + IN BOOLEAN IsPaging) +{ + UNIMPLEMENTED; +} + /* PUBLIC FUNCTIONS **********************************************************/ /*++ @@ -37,7 +49,7 @@ FsRtlPostPagingFileStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine) { - UNIMPLEMENTED; + FsRtlpPostStackOverflow(Context, Event, StackOverflowRoutine, TRUE); } /*++ @@ -63,7 +75,7 @@ FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine) { - KeBugCheck(FILE_SYSTEM); + FsRtlpPostStackOverflow(Context, Event, StackOverflowRoutine, FALSE); } /* EOF */ From c4682b16cb2a6b7e6dee59746175a45e3ff1a2b8 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 1 May 2013 13:44:24 +0000 Subject: [PATCH 14/67] [INCLUDE] Add missing LSA_TOKEN_INFORMATION_NULL and LSA_TOKEN_INFORMATION_V1 types. svn path=/trunk/; revision=58900 --- reactos/include/psdk/ntsecpkg.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/reactos/include/psdk/ntsecpkg.h b/reactos/include/psdk/ntsecpkg.h index b83d364544b..5996fad524e 100644 --- a/reactos/include/psdk/ntsecpkg.h +++ b/reactos/include/psdk/ntsecpkg.h @@ -60,6 +60,23 @@ typedef enum _SECPKG_NAME_TYPE { } SECPKG_NAME_TYPE; /* struct definitions for SSP/AP */ +typedef struct _LSA_TOKEN_INFORMATION_NULL +{ + LARGE_INTEGER ExpirationTime; + PTOKEN_GROUPS Groups; +} LSA_TOKEN_INFORMATION_NULL, *PLSA_TOKEN_INFORMATION_NULL; + +typedef struct _LSA_TOKEN_INFORMATION_V1 +{ + LARGE_INTEGER ExpirationTime; + TOKEN_USER User; + PTOKEN_GROUPS Groups; + TOKEN_PRIMARY_GROUP PrimaryGroup; + PTOKEN_PRIVILEGES Privileges; + TOKEN_OWNER Owner; + TOKEN_DEFAULT_DACL DefaultDacl; +} LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1; + typedef struct _SECPKG_PRIMARY_CRED { LUID LogonId; UNICODE_STRING DownlevelName; From 279b9507fd778098d1e305d36790c98a40cd11e4 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 1 May 2013 16:00:36 +0000 Subject: [PATCH 15/67] [IEFRAME] * Fix the Home button label. Brought to you by Andre Guibert de Bruet. CORE-7144 #resolve #comment Thanks ! svn path=/trunk/; revision=58901 --- reactos/dll/win32/ieframe/ieframe.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/ieframe/ieframe.rc b/reactos/dll/win32/ieframe/ieframe.rc index 129a2d7540f..1697ccf4b58 100644 --- a/reactos/dll/win32/ieframe/ieframe.rc +++ b/reactos/dll/win32/ieframe/ieframe.rc @@ -64,7 +64,7 @@ STRINGTABLE IDS_TB_FORWARD "Forward" IDS_TB_STOP "Stop" IDS_TB_REFRESH "Refresh" - IDS_TB_HOME "#msgctxt#home page#Home" + IDS_TB_HOME "Home" IDS_TB_PRINT "Print..." } From 44099efad544e29ef2a6fe883d709730195211cd Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 1 May 2013 20:53:15 +0000 Subject: [PATCH 16/67] [NTOSKRNL] Implement post stack overflow functions (i.e. FsRtlPostStackOverflow() and FsRtlPostPagingFileStackOverflow()) svn path=/trunk/; revision=58906 --- reactos/ntoskrnl/fsrtl/fsrtlpc.c | 3 +- reactos/ntoskrnl/fsrtl/stackovf.c | 166 +++++++++++++++++++++++++++++- 2 files changed, 164 insertions(+), 5 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/fsrtlpc.c b/reactos/ntoskrnl/fsrtl/fsrtlpc.c index 02e9919f5eb..b3e50070b5a 100644 --- a/reactos/ntoskrnl/fsrtl/fsrtlpc.c +++ b/reactos/ntoskrnl/fsrtl/fsrtlpc.c @@ -16,6 +16,7 @@ PERESOURCE FsRtlPagingIoResources; ULONG FsRtlPagingIoResourceSelector; +NTSTATUS NTAPI INIT_FUNCTION FsRtlInitializeWorkerThread(); static UCHAR LegalAnsiCharacterArray[] = { @@ -183,7 +184,7 @@ FsRtlInitSystem(VOID) ExInitializeResource(&FsRtlPagingIoResources[i]); } - return TRUE; + return NT_SUCCESS(FsRtlInitializeWorkerThread()); } /* PUBLIC FUNCTIONS **********************************************************/ diff --git a/reactos/ntoskrnl/fsrtl/stackovf.c b/reactos/ntoskrnl/fsrtl/stackovf.c index 14abfc0032a..7b0b4cff464 100644 --- a/reactos/ntoskrnl/fsrtl/stackovf.c +++ b/reactos/ntoskrnl/fsrtl/stackovf.c @@ -3,7 +3,7 @@ * LICENSE: GPL - See COPYING in the top level directory * FILE: ntoskrnl/fsrtl/stackovf.c * PURPOSE: Provides Stack Overflow support for File System Drivers - * PROGRAMMERS: None. + * PROGRAMMERS: Pierre Schweitzer (pierre@reactos.org) */ /* INCLUDES ******************************************************************/ @@ -12,8 +12,65 @@ #define NDEBUG #include +/* GLOBALS *******************************************************************/ + +/* We have one queue for paging files, one queue for normal files + * Queue 0 is for non-paging files + * Queue 1 is for paging files + * Don't add new/change current queues unless you know what you do + * Most of the code relies on the fact that we have two queues in that order + */ +#define FSRTLP_MAX_QUEUES 2 + +typedef struct _STACK_OVERFLOW_WORK_ITEM +{ + + WORK_QUEUE_ITEM WorkItem; + PFSRTL_STACK_OVERFLOW_ROUTINE Routine; + PVOID Context; + PKEVENT Event; +} STACK_OVERFLOW_WORK_ITEM, *PSTACK_OVERFLOW_WORK_ITEM; + +KEVENT StackOverflowFallbackSerialEvent; +STACK_OVERFLOW_WORK_ITEM StackOverflowFallback; +KQUEUE FsRtlWorkerQueues[FSRTLP_MAX_QUEUES]; + /* PRIVATE FUNCTIONS *********************************************************/ +/* + * @implemented + */ +VOID +NTAPI +FsRtlStackOverflowRead(IN PVOID Context) +{ + PSTACK_OVERFLOW_WORK_ITEM WorkItem; + + WorkItem = (PSTACK_OVERFLOW_WORK_ITEM)Context; + + /* Put us as top IRP for current thread */ + IoSetTopLevelIrp((PIRP)FSRTL_FSP_TOP_LEVEL_IRP); + /* And call FsRtlSORoutine */ + WorkItem->Routine(WorkItem->Context, WorkItem->Event); + + /* If we were using fallback workitem, don't free it, just reset event */ + if (WorkItem == &StackOverflowFallback) + { + KeSetEvent(&StackOverflowFallbackSerialEvent, 0, FALSE); + } + /* Otherwise, free the work item */ + else + { + ExFreePoolWithTag(WorkItem, 'Fsrs'); + } + + /* Reset top level */ + IoSetTopLevelIrp(NULL); +} + +/* + * @implemented + */ VOID NTAPI FsRtlpPostStackOverflow(IN PVOID Context, @@ -21,14 +78,115 @@ FsRtlpPostStackOverflow(IN PVOID Context, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine, IN BOOLEAN IsPaging) { - UNIMPLEMENTED; + PSTACK_OVERFLOW_WORK_ITEM WorkItem; + + /* Try to allocate a work item */ + WorkItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(STACK_OVERFLOW_WORK_ITEM), 'FSrs'); + if (WorkItem == NULL) + { + /* If we failed, and we are not a paging file, just raise an error */ + if (!IsPaging) + { + RtlRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); + } + + /* Otherwise, wait for fallback workitem to be available and use it */ + KeWaitForSingleObject(&StackOverflowFallbackSerialEvent, Executive, KernelMode, FALSE, NULL); + WorkItem = &StackOverflowFallback; + } + + /* Initialize work item */ + WorkItem->Context = Context; + WorkItem->Event = Event; + WorkItem->Routine = StackOverflowRoutine; + ExInitializeWorkItem(&WorkItem->WorkItem, FsRtlStackOverflowRead, WorkItem); + + /* And queue it in the appropriate queue (paging or not?) */ + KeInsertQueue(&FsRtlWorkerQueues[IsPaging], &WorkItem->WorkItem.List); +} + +/* + * @implemented + */ +VOID +NTAPI +FsRtlWorkerThread(IN PVOID StartContext) +{ + KIRQL Irql; + PLIST_ENTRY Entry; + PWORK_QUEUE_ITEM WorkItem; + ULONG QueueId = (ULONG)StartContext; + + /* Set our priority according to the queue we're dealing with */ + KeSetPriorityThread(&PsGetCurrentThread()->Tcb, LOW_REALTIME_PRIORITY + QueueId); + + /* Loop for events */ + for (;;) + { + /* Look for next event */ + Entry = KeRemoveQueue(&FsRtlWorkerQueues[QueueId], KernelMode, NULL); + WorkItem = CONTAINING_RECORD(Entry, WORK_QUEUE_ITEM, List); + + /* Call its routine (here: FsRtlStackOverflowRead) */ + WorkItem->WorkerRoutine(WorkItem->Parameter); + + /* Check we're still at passive level or bugcheck */ + Irql = KeGetCurrentIrql(); + if (Irql != PASSIVE_LEVEL) + { + KeBugCheckEx(IRQL_NOT_LESS_OR_EQUAL, (ULONG_PTR)WorkItem->WorkerRoutine, + (ULONG_PTR)Irql, (ULONG_PTR)WorkItem->WorkerRoutine, + (ULONG_PTR)WorkItem); + } + } +} + +/* + * @implemented + */ +NTSTATUS +NTAPI +INIT_FUNCTION +FsRtlInitializeWorkerThread() +{ + ULONG i; + NTSTATUS Status; + HANDLE ThreadHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + + /* Initialize each queue we have */ + for (i = 0; i < FSRTLP_MAX_QUEUES; ++i) + { + InitializeObjectAttributes(&ObjectAttributes, + NULL, + 0, + NULL, + NULL); + + /* Initialize the queue and its associated thread and pass it the queue ID */ + KeInitializeQueue(&FsRtlWorkerQueues[i], 0); + Status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, &ObjectAttributes, + 0, 0, FsRtlWorkerThread, (PVOID)i); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Don't leak handle */ + ZwClose(ThreadHandle); + } + + /* Also initialize our fallback event, set it to ensure it's already usable */ + KeInitializeEvent(&StackOverflowFallbackSerialEvent, SynchronizationEvent, TRUE); + + return Status; } /* PUBLIC FUNCTIONS **********************************************************/ /*++ * @name FsRtlPostPagingFileStackOverflow - * @unimplemented NT 4.0 + * @implemented NT 5.2 * * The FsRtlPostPagingFileStackOverflow routine * @@ -54,7 +212,7 @@ FsRtlPostPagingFileStackOverflow(IN PVOID Context, /*++ * @name FsRtlPostStackOverflow - * @unimplemented NT 4.0 + * @implemented NT 5.2 * * The FsRtlPostStackOverflow routine * From 9aff77470af0d63f93c562c6d391f7e6669b3f43 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 1 May 2013 21:29:49 +0000 Subject: [PATCH 17/67] [LSASRV] Implement logon token creation code. svn path=/trunk/; revision=58907 --- reactos/dll/win32/lsasrv/authpackage.c | 162 +++++++++++++++++++++++-- reactos/dll/win32/lsasrv/lsasrv.h | 1 + 2 files changed, 154 insertions(+), 9 deletions(-) diff --git a/reactos/dll/win32/lsasrv/authpackage.c b/reactos/dll/win32/lsasrv/authpackage.c index 04a3c32f569..a5af21fedee 100644 --- a/reactos/dll/win32/lsasrv/authpackage.c +++ b/reactos/dll/win32/lsasrv/authpackage.c @@ -18,6 +18,17 @@ typedef enum _LSA_TOKEN_INFORMATION_TYPE LsaTokenInformationV1 } LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE; +typedef struct _LSA_TOKEN_INFORMATION_V1 +{ + LARGE_INTEGER ExpirationTime; + TOKEN_USER User; + PTOKEN_GROUPS Groups; + TOKEN_PRIMARY_GROUP PrimaryGroup; + PTOKEN_PRIVILEGES Privileges; + TOKEN_OWNER Owner; + TOKEN_DEFAULT_DACL DefaultDacl; +} LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1; + typedef PVOID PLSA_CLIENT_REQUEST; typedef PVOID (NTAPI *PLSA_ALLOCATE_LSA_HEAP)(ULONG); @@ -283,6 +294,26 @@ LsapGetAuthenticationPackage(IN ULONG PackageId) } +static +NTSTATUS +NTAPI +LsapCreateLogonSession(IN PLUID LogonId) +{ + TRACE("()\n"); + return STATUS_SUCCESS; +} + + +static +NTSTATUS +NTAPI +LsapDeleteLogonSession(IN PLUID LogonId) +{ + TRACE("()\n"); + return STATUS_SUCCESS; +} + + static PVOID NTAPI @@ -404,8 +435,8 @@ LsapInitAuthPackages(VOID) PackageId = 0; /* Initialize the dispatch table */ - DispatchTable.CreateLogonSession = NULL; - DispatchTable.DeleteLogonSession = NULL; + DispatchTable.CreateLogonSession = &LsapCreateLogonSession; + DispatchTable.DeleteLogonSession = &LsapDeleteLogonSession; DispatchTable.AddCredential = NULL; DispatchTable.GetCredentials = NULL; DispatchTable.DeleteCredential = NULL; @@ -531,16 +562,19 @@ LsapLogonUser(PLSA_API_MSG RequestMsg, PLSAP_LOGON_CONTEXT LogonContext) { PAUTH_PACKAGE Package; - ULONG PackageId; - NTSTATUS Status; - + OBJECT_ATTRIBUTES ObjectAttributes; + SECURITY_QUALITY_OF_SERVICE Qos; LSA_TOKEN_INFORMATION_TYPE TokenInformationType; PVOID TokenInformation = NULL; + PLSA_TOKEN_INFORMATION_V1 TokenInfo1 = NULL; PUNICODE_STRING AccountName = NULL; PUNICODE_STRING AuthenticatingAuthority = NULL; PUNICODE_STRING MachineName = NULL; - PVOID LocalAuthInfo = NULL; + HANDLE TokenHandle = NULL; + ULONG i; + ULONG PackageId; + NTSTATUS Status; TRACE("(%p %p)\n", RequestMsg, LogonContext); @@ -556,7 +590,7 @@ LsapLogonUser(PLSA_API_MSG RequestMsg, if (RequestMsg->LogonUser.Request.AuthenticationInformationLength > 0) { - /* Allocat the local authentication info buffer */ + /* Allocate the local authentication info buffer */ LocalAuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, RequestMsg->LogonUser.Request.AuthenticationInformationLength); @@ -633,21 +667,131 @@ LsapLogonUser(PLSA_API_MSG RequestMsg, &AuthenticatingAuthority); } + if (!NT_SUCCESS(Status)) + { + TRACE("LsaApLogonUser/Ex/2 failed (Status 0x%08lx)\n", Status); + goto done; + } + + if (TokenInformationType == LsaTokenInformationV1) + { + TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; + + Qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); + Qos.ImpersonationLevel = SecurityImpersonation; + Qos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; + Qos.EffectiveOnly = FALSE; + + ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); + ObjectAttributes.RootDirectory = NULL; + ObjectAttributes.ObjectName = NULL; + ObjectAttributes.Attributes = 0; + ObjectAttributes.SecurityDescriptor = NULL; + ObjectAttributes.SecurityQualityOfService = &Qos; + + /* Create the logon token */ + Status = NtCreateToken(&TokenHandle, + TOKEN_ALL_ACCESS, + &ObjectAttributes, + TokenPrimary, + &RequestMsg->LogonUser.Reply.LogonId, + &TokenInfo1->ExpirationTime, + &TokenInfo1->User, + TokenInfo1->Groups, + TokenInfo1->Privileges, + &TokenInfo1->Owner, + &TokenInfo1->PrimaryGroup, + &TokenInfo1->DefaultDacl, + &RequestMsg->LogonUser.Request.SourceContext); + if (!NT_SUCCESS(Status)) + { + TRACE("NtCreateToken failed (Status 0x%08lx)\n", Status); + goto done; + } + } + else + { + FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); + Status = STATUS_NOT_IMPLEMENTED; + goto done; + } + + /* Duplicate the token handle into the client process */ + Status = NtDuplicateObject(NtCurrentProcess(), + TokenHandle, + LogonContext->ClientProcessHandle, + &RequestMsg->LogonUser.Reply.Token, + 0, + 0, + DUPLICATE_SAME_ACCESS | DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_CLOSE_SOURCE); + if (!NT_SUCCESS(Status)) + { + TRACE("NtDuplicateObject failed (Status 0x%08lx)\n", Status); + goto done; + } + + TokenHandle = NULL; + +done: + if (!NT_SUCCESS(Status)) + { + if (TokenHandle != NULL) + NtClose(TokenHandle); + } + /* Free the local authentication info buffer */ if (LocalAuthInfo != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo); if (TokenInformation != NULL) { + if (TokenInformationType == LsaTokenInformationV1) + { + TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; + if (TokenInfo1 != NULL) + { + if (TokenInfo1->User.User.Sid != NULL) + LsapFreeHeap(TokenInfo1->User.User.Sid); + + if (TokenInfo1->Groups != NULL) + { + for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) + { + if (TokenInfo1->Groups->Groups[i].Sid != NULL) + LsapFreeHeap(TokenInfo1->Groups->Groups[i].Sid); + } + + LsapFreeHeap(TokenInfo1->Groups); + } + + if (TokenInfo1->PrimaryGroup.PrimaryGroup != NULL) + LsapFreeHeap(TokenInfo1->PrimaryGroup.PrimaryGroup); + + if (TokenInfo1->Privileges != NULL) + LsapFreeHeap(TokenInfo1->Privileges); + + if (TokenInfo1->Owner.Owner != NULL) + LsapFreeHeap(TokenInfo1->Owner.Owner); + + if (TokenInfo1->DefaultDacl.DefaultDacl != NULL) + LsapFreeHeap(TokenInfo1->DefaultDacl.DefaultDacl); + + LsapFreeHeap(TokenInfo1); + } + } + else + { + FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); + } } - if (AuthenticatingAuthority != NULL) + if (AccountName != NULL) { } - if (AccountName != NULL) + if (AuthenticatingAuthority != NULL) { } diff --git a/reactos/dll/win32/lsasrv/lsasrv.h b/reactos/dll/win32/lsasrv/lsasrv.h index b4d048cd8a7..029b1fe64eb 100644 --- a/reactos/dll/win32/lsasrv/lsasrv.h +++ b/reactos/dll/win32/lsasrv/lsasrv.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include From 96970e7413072ee2859b9655f7841debb8588307 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 1 May 2013 21:54:40 +0000 Subject: [PATCH 18/67] [NET] Clean-up the new functions. This should have been done by the author of the patch! svn path=/trunk/; revision=58908 --- .../applications/network/net/cmdContinue.c | 53 +++++++++++-------- .../applications/network/net/cmdHelpMsg.c | 36 +++++++------ .../base/applications/network/net/cmdPause.c | 51 ++++++++++-------- reactos/base/applications/network/net/net.h | 8 +-- 4 files changed, 83 insertions(+), 65 deletions(-) diff --git a/reactos/base/applications/network/net/cmdContinue.c b/reactos/base/applications/network/net/cmdContinue.c index d8b69c82e6b..7f23fa5777a 100644 --- a/reactos/base/applications/network/net/cmdContinue.c +++ b/reactos/base/applications/network/net/cmdContinue.c @@ -9,42 +9,49 @@ #include "net.h" -int cmdContinue(int argc, wchar_t *argv[]) +INT cmdContinue(INT argc, WCHAR **argv) { - int errorCode = 0; - SC_HANDLE hManager, hService; + SC_HANDLE hManager = NULL; + SC_HANDLE hService = NULL; SERVICE_STATUS status; - if(argc != 3) + INT nError = 0; + + if (argc != 3) { puts("Usage: NET CONTINUE "); return 1; } - hManager=OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE); - if(hManager == NULL) + hManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE); + if (hManager == NULL) { - printf("[OpenSCManager] Error: %d\n", errorCode = GetLastError()); - return errorCode; + printf("[OpenSCManager] Error: %ld\n", GetLastError()); + nError = 1; + goto done; } - + hService = OpenService(hManager, argv[2], SERVICE_PAUSE_CONTINUE); - - if(hService == NULL) + if (hService == NULL) { - printf("[OpenService] Error: %d\n", errorCode=GetLastError()); + printf("[OpenService] Error: %ld\n", GetLastError()); + nError = 1; + goto done; + } + + if (!ControlService(hService, SERVICE_CONTROL_CONTINUE, &status)) + { + printf("[ControlService] Error: %ld\n", GetLastError()); + nError = 1; + } + +done: + if (hService != NULL) + CloseServiceHandle(hService); + + if (hManager != NULL) CloseServiceHandle(hManager); - return errorCode; - } - if(!ControlService(hService, SERVICE_CONTROL_CONTINUE, &status)) - { - printf("[ControlService] Error: %d\n", errorCode=GetLastError()); - } - - CloseServiceHandle(hService); - CloseServiceHandle(hManager); - - return errorCode; + return nError; } /* EOF */ diff --git a/reactos/base/applications/network/net/cmdHelpMsg.c b/reactos/base/applications/network/net/cmdHelpMsg.c index 5a2e5596a39..57e893998cf 100644 --- a/reactos/base/applications/network/net/cmdHelpMsg.c +++ b/reactos/base/applications/network/net/cmdHelpMsg.c @@ -10,38 +10,42 @@ #include "net.h" #include "stdlib.h" -int cmdHelpMsg(int argc, wchar_t *argv[]) +INT cmdHelpMsg(INT argc, WCHAR **argv) { - wchar_t *endptr; - LPSTR lpBuffer; - long errNum; + LPWSTR endptr; + LPWSTR lpBuffer; + LONG errNum; - if(argc<3) + if (argc < 3) { puts("Usage: NET HELPMSG "); return 1; } + errNum = wcstol(argv[2], &endptr, 10); - if(*endptr != 0) + if (*endptr != 0) { puts("Usage: NET HELPMSG "); return 1; } /* Unicode printing is not supported in ReactOS yet */ - if(FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - errNum, - LANG_USER_DEFAULT, - (LPSTR)&lpBuffer, - 0, - NULL)) + if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + errNum, + LANG_USER_DEFAULT, + (LPWSTR)&lpBuffer, + 0, + NULL)) { - printf("\n%s\n", lpBuffer); + printf("\n%S\n", lpBuffer); LocalFree(lpBuffer); } - else printf("Unrecognized error code: %ld\n", errNum); - + else + { + printf("Unrecognized error code: %ld\n", errNum); + } + return 0; } diff --git a/reactos/base/applications/network/net/cmdPause.c b/reactos/base/applications/network/net/cmdPause.c index 2731a605ad7..02278939c98 100644 --- a/reactos/base/applications/network/net/cmdPause.c +++ b/reactos/base/applications/network/net/cmdPause.c @@ -9,41 +9,48 @@ #include "net.h" -int cmdPause(int argc, wchar_t *argv[]) +INT cmdPause(INT argc, WCHAR **argv) { - int errorCode=0; - SC_HANDLE hManager, hService; + SC_HANDLE hManager = NULL; + SC_HANDLE hService = NULL; SERVICE_STATUS status; - if(argc != 3) + INT nError = 0; + + if (argc != 3) { puts("Usage: NET PAUSE "); return 1; } hManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE); - if(hManager == NULL) + if (hManager == NULL) { - printf("[OpenSCManager] Error: %d\n", errorCode=GetLastError()); - return errorCode; + printf("[OpenSCManager] Error: %ld\n", GetLastError()); + nError = 1; + goto done; } - - hService=OpenService(hManager, argv[2], SERVICE_PAUSE_CONTINUE); - if(hService == NULL) + + hService = OpenService(hManager, argv[2], SERVICE_PAUSE_CONTINUE); + if (hService == NULL) { - printf("[OpenService] Error: %d\n", errorCode=GetLastError()); + printf("[OpenService] Error: %ld\n", GetLastError()); + nError = 1; + goto done; + } + + if (!ControlService(hService, SERVICE_CONTROL_PAUSE, &status)) + { + printf("[ControlService] Error: %ld\n", GetLastError()); + } + +done: + if (hService != NULL) + CloseServiceHandle(hService); + + if (hManager != NULL) CloseServiceHandle(hManager); - return errorCode; - } - - if(!ControlService(hService, SERVICE_CONTROL_PAUSE, &status)) - { - printf("[ControlService] Error: %d\n", errorCode=GetLastError()); - } - CloseServiceHandle(hService); - CloseServiceHandle(hManager); - - return errorCode; + return nError; } /* EOF */ diff --git a/reactos/base/applications/network/net/net.h b/reactos/base/applications/network/net/net.h index 660033f0be2..7c8ea0d25d7 100644 --- a/reactos/base/applications/network/net/net.h +++ b/reactos/base/applications/network/net/net.h @@ -4,7 +4,7 @@ * FILE: * PURPOSE: * - * PROGRAMMERS: Magnus Olsen (greatlord@reactos.org) + * PROGRAMMERS: Magnus Olsen (greatlord@reactos.org) */ #include @@ -16,9 +16,9 @@ VOID help(VOID); INT unimplemented(INT argc, WCHAR **argv); +INT cmdContinue(INT argc, WCHAR **argv); INT cmdHelp(INT argc, WCHAR **argv); +INT cmdHelpMsg(INT argc, WCHAR **argv); +INT cmdPause(INT argc, WCHAR **argv); INT cmdStart(INT argc, WCHAR **argv); INT cmdStop(INT argc, WCHAR **argv); -int cmdHelpMsg(int argc, wchar_t *argv[]); -int cmdPause(int argc, wchar_t *argv[]); -int cmdContinue(int argc, wchar_t *argv[]); From d955789246d93348035f67c003bed9279ced6290 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Thu, 2 May 2013 08:04:12 +0000 Subject: [PATCH 19/67] [NTOSKRNL] This is C, use VOID Spotted by Thomas Faber svn path=/trunk/; revision=58910 --- reactos/ntoskrnl/fsrtl/fsrtlpc.c | 2 +- reactos/ntoskrnl/fsrtl/stackovf.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/fsrtlpc.c b/reactos/ntoskrnl/fsrtl/fsrtlpc.c index b3e50070b5a..b5a68a4075e 100644 --- a/reactos/ntoskrnl/fsrtl/fsrtlpc.c +++ b/reactos/ntoskrnl/fsrtl/fsrtlpc.c @@ -16,7 +16,7 @@ PERESOURCE FsRtlPagingIoResources; ULONG FsRtlPagingIoResourceSelector; -NTSTATUS NTAPI INIT_FUNCTION FsRtlInitializeWorkerThread(); +NTSTATUS NTAPI INIT_FUNCTION FsRtlInitializeWorkerThread(VOID); static UCHAR LegalAnsiCharacterArray[] = { diff --git a/reactos/ntoskrnl/fsrtl/stackovf.c b/reactos/ntoskrnl/fsrtl/stackovf.c index 7b0b4cff464..076121f8831 100644 --- a/reactos/ntoskrnl/fsrtl/stackovf.c +++ b/reactos/ntoskrnl/fsrtl/stackovf.c @@ -147,7 +147,7 @@ FsRtlWorkerThread(IN PVOID StartContext) NTSTATUS NTAPI INIT_FUNCTION -FsRtlInitializeWorkerThread() +FsRtlInitializeWorkerThread(VOID) { ULONG i; NTSTATUS Status; From b3a3a9d7ac966727ebca1168c1f61c43d903a7a5 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Thu, 2 May 2013 14:21:18 +0000 Subject: [PATCH 20/67] [CRT] * Annotate memory.h. svn path=/trunk/; revision=58911 --- reactos/include/crt/memory.h | 108 ++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 13 deletions(-) diff --git a/reactos/include/crt/memory.h b/reactos/include/crt/memory.h index 78be8083c61..237b727b8f5 100644 --- a/reactos/include/crt/memory.h +++ b/reactos/include/crt/memory.h @@ -20,21 +20,103 @@ extern "C" { #ifndef _CRT_MEMORY_DEFINED #define _CRT_MEMORY_DEFINED - _CRTIMP void *__cdecl _memccpy(void *_Dst,const void *_Src,int _Val,size_t _MaxCount); - _CONST_RETURN void *__cdecl memchr(const void *_Buf ,int _Val,size_t _MaxCount); - _CRTIMP int __cdecl _memicmp(const void *_Buf1,const void *_Buf2,size_t _Size); - _CRTIMP int __cdecl _memicmp_l(const void *_Buf1,const void *_Buf2,size_t _Size,_locale_t _Locale); - int __cdecl memcmp(const void *_Buf1,const void *_Buf2,size_t _Size); - void *__cdecl memcpy(void *_Dst,const void *_Src,size_t _Size); - void *__cdecl memset(void *_Dst,int _Val,size_t _Size); -#ifndef NO_OLDNAMES - _CRTIMP void *__cdecl memccpy(void *_Dst,const void *_Src,int _Val,size_t _Size); - _CRTIMP int __cdecl memicmp(const void *_Buf1,const void *_Buf2,size_t _Size); -#endif -#endif + _CRTIMP + void* + __cdecl + _memccpy( + _Out_writes_bytes_opt_(_MaxCount) void *_Dst, + _In_ const void *_Src, + _In_ int _Val, + _In_ size_t _MaxCount); + + _Check_return_ + _CONST_RETURN + void* + __cdecl + memchr( + _In_reads_bytes_opt_(_MaxCount) const void *_Buf, + _In_ int _Val, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _memicmp( + _In_reads_bytes_opt_(_Size) const void *_Buf1, + _In_reads_bytes_opt_(_Size) const void *_Buf2, + _In_ size_t _Size); + + _Check_return_ + _CRTIMP + int + __cdecl + _memicmp_l( + _In_reads_bytes_opt_(_Size) const void *_Buf1, + _In_reads_bytes_opt_(_Size) const void *_Buf2, + _In_ size_t _Size, + _In_opt_ _locale_t _Locale); + + _Check_return_ + int + __cdecl + memcmp( + _In_reads_bytes_opt_(_Size) const void *_Buf1, + _In_reads_bytes_opt_(_Size) const void *_Buf2, + _In_ size_t _Size); + + _Post_equal_to_(_Dst) + _At_buffer_((unsigned char*)_Dst, + _Iter_, + _MaxCount, + _Post_satisfies_(((unsigned char*)_Dst)[_Iter_] == ((unsigned char*)_Src)[_Iter_])) + _CRT_INSECURE_DEPRECATE_MEMORY(memcpy_s) + void* + __cdecl + memcpy( + _Out_writes_bytes_all_(_MaxCount) void *_Dst, + _In_reads_bytes_(_MaxCount) const void *_Src, + _In_ size_t _MaxCount); + + _Post_equal_to_(_Dst) + _At_buffer_((unsigned char*)_Dst, + _Iter_, + _Size, + _Post_satisfies_(((unsigned char*)_Dst)[_Iter_] == _Val)) + void* + __cdecl + memset( + _Out_writes_bytes_all_(_Size) void *_Dst, + _In_ int _Val, + _In_ size_t _Size); + +#ifndef NO_OLDNAMES + + _CRTIMP + void* + __cdecl + memccpy( + _Out_writes_bytes_opt_(_Size) void *_Dst, + _In_reads_bytes_opt_(_Size) const void *_Src, + _In_ int _Val, + _In_ size_t _Size); + + _Check_return_ + _CRTIMP + int + __cdecl + memicmp( + _In_reads_bytes_opt_(_Size) const void *_Buf1, + _In_reads_bytes_opt_(_Size) const void *_Buf2, + _In_ size_t _Size); + +#endif /* NO_OLDNAMES */ + +#endif /* _CRT_MEMORY_DEFINED */ #ifdef __cplusplus } #endif -#endif + +#endif /* _INC_MEMORY */ From f93d55e8a940ee4a63606395807fb60316478082 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Thu, 2 May 2013 17:09:34 +0000 Subject: [PATCH 21/67] [CRT] * Annotate tchar.h. svn path=/trunk/; revision=58912 --- reactos/include/crt/tchar.h | 542 ++++++++++++++++++++++++++++++++---- 1 file changed, 483 insertions(+), 59 deletions(-) diff --git a/reactos/include/crt/tchar.h b/reactos/include/crt/tchar.h index d7c31478341..d246b00e4c4 100644 --- a/reactos/include/crt/tchar.h +++ b/reactos/include/crt/tchar.h @@ -855,65 +855,489 @@ extern "C" { #else /* !_MB_MAP_DIRECT */ - _CRTIMP _CONST_RETURN char *__cdecl _tcschr(const char *_Str,unsigned int _Val); - _CRTIMP size_t __cdecl _tcscspn(const char *_Str,const char *_Control); - _CRTIMP char *__cdecl _tcsncat(char *_Dst,const char *_Src,size_t _MaxCount); - _CRTIMP char *__cdecl _tcsncat_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); - _CRTIMP char *__cdecl _tcsncpy(char *_Dst,const char *_Src,size_t _MaxCount); - _CRTIMP char *__cdecl _tcsncpy_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); - _CRTIMP _CONST_RETURN char *__cdecl _tcspbrk(const char *_Str,const char *_Control); - _CRTIMP _CONST_RETURN char *__cdecl _tcsrchr(const char *_Str,unsigned int _Ch); - _CRTIMP size_t __cdecl _tcsspn(const char *_Str,const char *_Control); - _CRTIMP _CONST_RETURN char *__cdecl _tcsstr(const char *_Str,const char *_Substr); - _CRTIMP char *__cdecl _tcstok(char *_Str,const char *_Delim); - _CRTIMP char *__cdecl _tcstok_l(char *_Str,const char *_Delim,_locale_t _Locale); - _CRTIMP char *__cdecl _tcsnset(char *_Str,unsigned int _Val,size_t _MaxCount); - _CRTIMP char *__cdecl _tcsrev(char *_Str); - _CRTIMP char *__cdecl _tcsset(char *_Str,unsigned int _Val); - _CRTIMP char *__cdecl _tcsset_l(char *_Str,unsigned int _Val,_locale_t _Locale); - _CRTIMP int __cdecl _tcscmp(const char *_Str1,const char *_Str); - _CRTIMP int __cdecl _tcsicmp(const char *_Str1,const char *_Str2); - _CRTIMP int __cdecl _tcsicmp_l(const char *_Str1,const char *_Str2,_locale_t _Locale); - _CRTIMP int __cdecl _tcsnccmp(const char *_Str1,const char *_Str2,size_t _MaxCount); - _CRTIMP int __cdecl _tcsncmp(const char *_Str1,const char *_Str2,size_t _MaxCount); - _CRTIMP int __cdecl _tcsncicmp(const char *_Str1,const char *_Str2,size_t _MaxCount); - _CRTIMP int __cdecl _tcsncicmp_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); - _CRTIMP int __cdecl _tcsnicmp(const char *_Str1,const char *_Str2,size_t _MaxCount); - _CRTIMP int __cdecl _tcsnicmp_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); - _CRTIMP int __cdecl _tcscoll(const char *_Str1,const char *_Str2); - _CRTIMP int __cdecl _tcscoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale); - _CRTIMP int __cdecl _tcsicoll(const char *_Str1,const char *_Str2); - _CRTIMP int __cdecl _tcsicoll_l(const char *_Str1,const char *_Str2,_locale_t _Locale); - _CRTIMP int __cdecl _tcsnccoll(const char *_Str1,const char *_Str2,size_t _MaxCount); - _CRTIMP int __cdecl _tcsnccoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); - _CRTIMP int __cdecl _tcsncoll(const char *_Str1,const char *_Str2,size_t _MaxCount); - _CRTIMP int __cdecl _tcsncoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); - _CRTIMP int __cdecl _tcsncicoll(const char *_Str1,const char *_Str2,size_t _MaxCount); - _CRTIMP int __cdecl _tcsncicoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); - _CRTIMP int __cdecl _tcsnicoll(const char *_Str1,const char *_Str2,size_t _MaxCount); - _CRTIMP int __cdecl _tcsnicoll_l(const char *_Str1,const char *_Str2,size_t _MaxCount,_locale_t _Locale); - _CRTIMP size_t __cdecl _tcsclen(const char *_Str); - _CRTIMP size_t __cdecl _tcscnlen(const char *_Str,size_t _MaxCount); - _CRTIMP size_t __cdecl _tcsclen_l(const char *_Str,_locale_t _Locale); - _CRTIMP size_t __cdecl _tcscnlen_l(const char *_Str,size_t _MaxCount,_locale_t _Locale); - _CRTIMP char *__cdecl _tcsnccat(char *_Dst,const char *_Src,size_t _MaxCount); - _CRTIMP char *__cdecl _tcsnccat_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); - _CRTIMP char *__cdecl _tcsnccpy(char *_Dst,const char *_Src,size_t _MaxCount); - _CRTIMP char *__cdecl _tcsnccpy_l(char *_Dst,const char *_Src,size_t _MaxCount,_locale_t _Locale); - _CRTIMP char *__cdecl _tcsncset(char *_Str,unsigned int _Val,size_t _MaxCount); - _CRTIMP char *__cdecl _tcsdec(const char *_Start,const char *_Pos); - _CRTIMP char *__cdecl _tcsinc(const char *_Ptr); - _CRTIMP size_t __cdecl _tcsnbcnt(const char *_Str,size_t _MaxCount); - _CRTIMP size_t __cdecl _tcsnccnt(const char *_Str,size_t _MaxCount); - _CRTIMP unsigned int __cdecl _tcsnextc (const char *_Str); - _CRTIMP char *__cdecl _tcsninc(const char *_Ptr,size_t _Count); - _CRTIMP char *__cdecl _tcsspnp(const char *_Str1,const char *_Str2); - _CRTIMP char *__cdecl _tcslwr(char *_Str); - _CRTIMP char *__cdecl _tcslwr_l(char *_Str,_locale_t _Locale); - _CRTIMP char *__cdecl _tcsupr(char *_Str); - _CRTIMP char *__cdecl _tcsupr_l(char *_Str,_locale_t _Locale); - _CRTIMP size_t __cdecl _tclen(const char *_Str); - _CRTIMP void __cdecl _tccpy(char *_DstCh,const char *_SrcCh); + _Check_return_ + _CRTIMP + _CONST_RETURN + char* + __cdecl + _tcschr( + _In_z_ const char *_Str, + _In_ unsigned int _Val); + + _Check_return_ + _CRTIMP + size_t + __cdecl + _tcscspn( + _In_z_ const char *_Str, + _In_z_ const char *_Control); + + _CRTIMP + char* + __cdecl + _tcsncat( + _Inout_updates_z_(_MaxCount) char *_Dst, + _In_z_ const char *_Src, + _In_ size_t _MaxCount); + + _CRTIMP + char* + __cdecl + _tcsncat_l( + _Inout_updates_z_(_MaxCount) char *_Dst, + _In_z_ const char *_Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _CRTIMP + char* + __cdecl + _tcsncpy( + _Out_writes_(_MaxCount) _Post_maybez_ char *_Dst, + _In_z_ const char *_Src, + _In_ size_t _MaxCount); + + _CRTIMP + char* + __cdecl + _tcsncpy_l( + _Out_writes_(_MaxCount) _Post_maybez_ char *_Dst, + _In_z_ const char *_Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + _CONST_RETURN + char* + __cdecl + _tcspbrk( + _In_z_ const char *_Str, + _In_z_ const char *_Control); + + _Check_return_ + _CRTIMP + _CONST_RETURN + char* + __cdecl + _tcsrchr( + _In_z_ const char *_Str, + _In_ unsigned int _Ch); + + _Check_return_ + _CRTIMP + size_t + __cdecl + _tcsspn( + _In_z_ const char *_Str, + _In_z_ const char *_Control); + + _Check_return_ + _CRTIMP + _CONST_RETURN + char* + __cdecl + _tcsstr( + _In_z_ const char *_Str, + _In_z_ const char *_Substr); + + _Check_return_ + _CRTIMP + char* + __cdecl + _tcstok( + _Inout_opt_ char *_Str, + _In_z_ const char *_Delim); + + _Check_return_ + _CRTIMP + char* + __cdecl + _tcstok_l( + _Inout_opt_ char *_Str, + _In_z_ const char *_Delim, + _In_opt_ _locale_t _Locale); + + _CRTIMP + char* + __cdecl + _tcsnset( + _Inout_z_ char *_Str, + _In_ unsigned int _Val, + _In_ size_t _MaxCount); + + _CRTIMP + char* + __cdecl + _tcsrev( + _Inout_z_ char *_Str); + + _CRTIMP + char* + __cdecl + _tcsset( + _Inout_z_ char *_Str, + _In_ unsigned int _Val); + + _CRTIMP + char* + __cdecl + _tcsset_l( + _Inout_z_ char *_Str, + _In_ unsigned int _Val, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcscmp( + _In_z_ const char *_Str1, + _In_z_ const char *_Str); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsicmp( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsicmp_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsnccmp( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsncmp( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsncicmp( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsncicmp_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsnicmp( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsnicmp_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcscoll( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcscoll_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsicoll( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsicoll_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsnccoll( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsnccoll_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsncoll( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsncoll_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsncicoll( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsncicoll_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsnicoll( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + int + __cdecl + _tcsnicoll_l( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + size_t + __cdecl + _tcsclen( + _In_z_ const char *_Str); + + _Check_return_ + _CRTIMP + size_t + __cdecl + _tcscnlen( + _In_z_ const char *_Str, + _In_ size_t _MaxCount); + + _Check_return_ + _CRTIMP + size_t + __cdecl + _tcsclen_l( + _In_z_ const char *_Str, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + size_t + __cdecl + _tcscnlen_l( + _In_z_ const char *_Str, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _CRTIMP + char* + __cdecl + _tcsnccat( + _Inout_ char *_Dst, + _In_z_ const char *_Src, + _In_ size_t _MaxCount); + + _CRTIMP + char* + __cdecl + _tcsnccat_l( + _Inout_ char *_Dst, + _In_z_ const char *_Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _CRTIMP + char* + __cdecl + _tcsnccpy( + _Out_writes_(_MaxCount) _Post_maybez_ char *_Dst, + _In_z_ const char *_Src, + _In_ size_t _MaxCount); + + _CRTIMP + char* + __cdecl + _tcsnccpy_l( + _Out_writes_(_MaxCount) _Post_maybez_ char *_Dst, + _In_z_ const char *_Src, + _In_ size_t _MaxCount, + _In_opt_ _locale_t _Locale); + + _CRTIMP + char* + __cdecl + _tcsncset( + _Inout_updates_z_(_MaxCount) char *_Str, + _In_ unsigned int _Val, + _In_ size_t _MaxCount); + + _CRTIMP + char* + __cdecl + _tcsdec( + _In_reads_z_(_Pos-_Start + 1) const char *_Start, + _In_z_ const char *_Pos); + + _CRTIMP + char* + __cdecl + _tcsinc( + _In_z_ const char *_Ptr); + + _CRTIMP + size_t + __cdecl + _tcsnbcnt( + _In_reads_(_MaxCount) _Pre_z_ const char *_Str, + _In_ size_t _MaxCount); + + _CRTIMP + size_t + __cdecl + _tcsnccnt( + _In_reads_(_MaxCount) _Pre_z_ const char *_Str, + _In_ size_t _MaxCount); + + _CRTIMP + unsigned int + __cdecl + _tcsnextc( + _In_z_ const char *_Str); + + _CRTIMP + char* + __cdecl + _tcsninc( + _In_reads_(_Count) _Pre_z_ const char *_Ptr, + _In_ size_t _Count); + + _CRTIMP + char* + __cdecl + _tcsspnp( + _In_z_ const char *_Str1, + _In_z_ const char *_Str2); + + _CRTIMP + char* + __cdecl + _tcslwr( + _Inout_ char *_Str); + + _CRTIMP + char* + __cdecl + _tcslwr_l( + _Inout_ char *_Str, + _In_opt_ _locale_t _Locale); + + _CRTIMP + char* + __cdecl + _tcsupr( + _Inout_ char *_Str); + + _CRTIMP + char* + __cdecl + _tcsupr_l( + _Inout_ char *_Str, + _In_opt_ _locale_t _Locale); + + _Check_return_ + _CRTIMP + size_t + __cdecl + _tclen( + _In_z_ const char *_Str); + + _CRTIMP + void + __cdecl + _tccpy( + _Pre_notnull_ _Post_z_ char *_DstCh, + _In_z_ const char *_SrcCh); #ifdef __cplusplus #ifndef _CPP_TCHAR_INLINES_DEFINED From 816d5dc335d33101078cf0d1d3596ab66bd50f99 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Fri, 3 May 2013 09:57:19 +0000 Subject: [PATCH 22/67] [WIN32SS] * Plug a leak in IntGdiAddFontResource(). Original fix by Katayama Hirofumi MZ with one more instance covered by Timo Kreuzer. * Return 0 instead of status in the file mapping failure path. By Timo Kreuzer. svn path=/trunk/; revision=58913 --- reactos/win32ss/gdi/ntgdi/freetype.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/reactos/win32ss/gdi/ntgdi/freetype.c b/reactos/win32ss/gdi/ntgdi/freetype.c index abcf6b17bc0..9b0405032e6 100644 --- a/reactos/win32ss/gdi/ntgdi/freetype.c +++ b/reactos/win32ss/gdi/ntgdi/freetype.c @@ -346,7 +346,8 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) if (!NT_SUCCESS(Status)) { DPRINT("Could not map file: %wZ\n", FileName); - return Status; + ObDereferenceObject(SectionObject); + return 0; } IntLockFreeType; @@ -357,6 +358,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) 0, &Face); IntUnLockFreeType; + ObDereferenceObject(SectionObject); if (Error) { @@ -364,7 +366,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) DPRINT("Unknown font file format\n"); else DPRINT("Error reading font file (error code: %u)\n", Error); - ObDereferenceObject(SectionObject); return 0; } @@ -372,7 +373,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) if (!Entry) { FT_Done_Face(Face); - ObDereferenceObject(SectionObject); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; } @@ -381,7 +381,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) if (FontGDI == NULL) { FT_Done_Face(Face); - ObDereferenceObject(SectionObject); ExFreePoolWithTag(Entry, TAG_FONT); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; @@ -392,7 +391,6 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics) { EngFreeMem(FontGDI); FT_Done_Face(Face); - ObDereferenceObject(SectionObject); ExFreePoolWithTag(Entry, TAG_FONT); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; From 3d8186b866627706e4ee45c2cc34add980311884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Fri, 3 May 2013 16:44:31 +0000 Subject: [PATCH 23/67] [ADVAPI32] - SEH-ize access to the data buffer in RegSetValueExW. Fixes winetest crash svn path=/trunk/; revision=58914 --- reactos/dll/win32/advapi32/reg/reg.c | 37 +++++++++++++++++----------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/reactos/dll/win32/advapi32/reg/reg.c b/reactos/dll/win32/advapi32/reg/reg.c index 64e87b26186..de15bf5f7d7 100644 --- a/reactos/dll/win32/advapi32/reg/reg.c +++ b/reactos/dll/win32/advapi32/reg/reg.c @@ -14,6 +14,7 @@ /* INCLUDES *****************************************************************/ #include +#include WINE_DEFAULT_DEBUG_CHANNEL(reg); /* DEFINES ******************************************************************/ @@ -4952,10 +4953,29 @@ RegSetValueExW(HKEY hKey, DWORD cbData) { UNICODE_STRING ValueName; - PUNICODE_STRING pValueName; HANDLE KeyHandle; NTSTATUS Status; + if (is_string(dwType) && (cbData != 0)) + { + PWSTR pwsData = (PWSTR)lpData; + + _SEH2_TRY + { + if((pwsData[cbData / sizeof(WCHAR) - 1] != L'\0') && + (pwsData[cbData / sizeof(WCHAR)] == L'\0')) + { + /* Increment length if last character is not zero and next is zero */ + cbData += sizeof(WCHAR); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(return ERROR_NOACCESS); + } + _SEH2_END; + } + Status = MapDefaultKey(&KeyHandle, hKey); if (!NT_SUCCESS(Status)) @@ -4964,22 +4984,9 @@ RegSetValueExW(HKEY hKey, } RtlInitUnicodeString(&ValueName, lpValueName); - pValueName = &ValueName; - - if (is_string(dwType) && (cbData != 0)) - { - PWSTR pwsData = (PWSTR)lpData; - - if((pwsData[cbData / sizeof(WCHAR) - 1] != L'\0') && - (pwsData[cbData / sizeof(WCHAR)] == L'\0')) - { - /* Increment length if last character is not zero and next is zero */ - cbData += sizeof(WCHAR); - } - } Status = NtSetValueKey(KeyHandle, - pValueName, + &ValueName, 0, dwType, (PVOID)lpData, From 703a1db75e44594690620b919055161f90b72b03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Fri, 3 May 2013 18:28:34 +0000 Subject: [PATCH 24/67] [PSDK] * Add complete definition of KEY_INFORMATION_CLASS [DDK] * Add KEY_NAME_INFORMATION structure declaration svn path=/trunk/; revision=58915 --- reactos/include/ddk/ntddk.h | 27 +++++++++++++++++++++++++++ reactos/include/psdk/winternl.h | 14 ++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/reactos/include/ddk/ntddk.h b/reactos/include/ddk/ntddk.h index 9576d3f43b9..def98262c22 100644 --- a/reactos/include/ddk/ntddk.h +++ b/reactos/include/ddk/ntddk.h @@ -5836,6 +5836,33 @@ FsRtlIsTotalDeviceFailure( _In_ NTSTATUS Status); #endif +/* Output parameters of ZwQueryKey */ + +typedef struct _KEY_NAME_INFORMATION { + ULONG NameLength; + WCHAR Name[1]; +} KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION; + +typedef struct _KEY_CACHED_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG SubKeys; + ULONG MaxNameLen; + ULONG Values; + ULONG MaxValueNameLen; + ULONG MaxValueDataLen; + ULONG NameLength; +} KEY_CACHED_INFORMATION, *PKEY_CACHED_INFORMATION; + +typedef struct _KEY_VIRTUALIZATION_INFORMATION { + ULONG VirtualizationCandidate :1; + ULONG VirtualizationEnabled :1; + ULONG VirtualTarget :1; + ULONG VirtualStore :1; + ULONG VirtualSource :1; + ULONG Reserved :27; +} KEY_VIRTUALIZATION_INFORMATION, *PKEY_VIRTUALIZATION_INFORMATION; + #ifdef __cplusplus } #endif diff --git a/reactos/include/psdk/winternl.h b/reactos/include/psdk/winternl.h index 9e0f96ae257..cf857874ab0 100644 --- a/reactos/include/psdk/winternl.h +++ b/reactos/include/psdk/winternl.h @@ -632,10 +632,16 @@ typedef enum _FSINFOCLASS { FileFsMaximumInformation } FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; -typedef enum _KEY_INFORMATION_CLASS { - KeyBasicInformation, - KeyNodeInformation, - KeyFullInformation +typedef enum _KEY_INFORMATION_CLASS { + KeyBasicInformation = 0, + KeyNodeInformation = 1, + KeyFullInformation = 2, + KeyNameInformation = 3, + KeyCachedInformation = 4, + KeyFlagsInformation = 5, + KeyVirtualizationInformation = 6, + KeyHandleTagsInformation = 7, + MaxKeyInfoClass = 8 } KEY_INFORMATION_CLASS; typedef enum _KEY_VALUE_INFORMATION_CLASS { From ec1a8a5a635e49080f8bfa434a9ae4de177564a9 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Fri, 3 May 2013 19:31:03 +0000 Subject: [PATCH 25/67] [NTOSKRNL] Prevent potential double free in loop. Fixes CID 732510 svn path=/trunk/; revision=58916 --- reactos/ntoskrnl/io/iomgr/error.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/reactos/ntoskrnl/io/iomgr/error.c b/reactos/ntoskrnl/io/iomgr/error.c index 07197ff39b4..0c7c14ec926 100644 --- a/reactos/ntoskrnl/io/iomgr/error.c +++ b/reactos/ntoskrnl/io/iomgr/error.c @@ -367,7 +367,11 @@ IopLogWorker(IN PVOID Parameter) DeviceNameLength += sizeof(WCHAR); /* Free the buffer if we had one */ - if (PoolObjectNameInfo) ExFreePool(PoolObjectNameInfo); + if (PoolObjectNameInfo) + { + ExFreePool(PoolObjectNameInfo); + PoolObjectNameInfo = NULL; + } /* Go to the next string buffer position */ ErrorMessage->EntryData.NumberOfStrings++; @@ -428,7 +432,7 @@ IopLogWorker(IN PVOID Parameter) break; } - /* Derefernece the device object */ + /* Dereference the device object */ if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject); if (DriverObject) ObDereferenceObject(LogEntry->DriverObject); From 66675db02ba86d48ab640b4c3276c36e1e432ff9 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sat, 4 May 2013 08:10:58 +0000 Subject: [PATCH 26/67] [WININET_WINETEST] - Hackfix hanging test. There's no benefit in having testbot take longer. ROSTESTS-73 #comment Temporary timeout added in r58917 to prevent hanging. svn path=/trunk/; revision=58917 --- rostests/winetests/wininet/http.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rostests/winetests/wininet/http.c b/rostests/winetests/wininet/http.c index 6be48a357bb..5a4abffe3af 100644 --- a/rostests/winetests/wininet/http.c +++ b/rostests/winetests/wininet/http.c @@ -2269,7 +2269,11 @@ static void test_conn_close(int port) SET_EXPECT(INTERNET_STATUS_CONNECTION_CLOSED); SET_EXPECT(INTERNET_STATUS_REQUEST_COMPLETE); SetEvent(conn_close_event); +#ifdef ROSTESTS_73_FIXED WaitForSingleObject(hCompleteEvent, INFINITE); +#else /* ROSTESTS_73_FIXED */ + ok(WaitForSingleObject(hCompleteEvent, 5000) == WAIT_OBJECT_0, "Wait timed out\n"); +#endif /* ROSTESTS_73_FIXED */ ok(req_error == ERROR_SUCCESS, "req_error = %u\n", req_error); CHECK_NOTIFIED(INTERNET_STATUS_CLOSING_CONNECTION); CHECK_NOTIFIED(INTERNET_STATUS_CONNECTION_CLOSED); From c15b763fbc2463a514dd7fcce04f2d0aad11f50f Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sat, 4 May 2013 08:39:05 +0000 Subject: [PATCH 27/67] [ATL] - Simplify CComObject code. Fix warnings. Patch by Katayama Hirofumi MZ. CORE-7105 #resolve svn path=/trunk/; revision=58918 --- reactos/lib/atl/atlcom.h | 44 ++++++++++++++------------------------- reactos/lib/atl/statreg.h | 1 + 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/reactos/lib/atl/atlcom.h b/reactos/lib/atl/atlcom.h index b787ec6d8a7..b46c5577dc8 100644 --- a/reactos/lib/atl/atlcom.h +++ b/reactos/lib/atl/atlcom.h @@ -2,6 +2,7 @@ * ReactOS ATL * * Copyright 2009 Andrew Hill + * Copyright 2013 Katayama Hirofumi MZ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -134,39 +135,28 @@ public: virtual ~CComObject() { - CComObject *pThis; - - pThis = reinterpret_cast *>(this); - pThis->FinalRelease(); + this->FinalRelease(); _pAtlModule->Unlock(); } STDMETHOD_(ULONG, AddRef)() { - CComObject *pThis; - - pThis = reinterpret_cast *>(this); - return pThis->InternalAddRef(); + return this->InternalAddRef(); } STDMETHOD_(ULONG, Release)() { - CComObject *pThis; - ULONG l; + ULONG newRefCount; - pThis = reinterpret_cast *>(this); - l = pThis->InternalRelease(); - if (l == 0) + newRefCount = this->InternalRelease(); + if (newRefCount == 0) delete this; - return l; + return newRefCount; } STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject) { - CComObject *pThis; - - pThis = reinterpret_cast *>(this); - return pThis->_InternalQueryInterface(iid, ppvObject); + return this->_InternalQueryInterface(iid, ppvObject); } static HRESULT WINAPI CreateInstance(CComObject **pp) @@ -283,11 +273,9 @@ public: STDMETHOD_(ULONG, AddRef)() { - CComObjectCached *pThis; ULONG newRefCount; - pThis = reinterpret_cast*>(this); - newRefCount = pThis->InternalAddRef(); + newRefCount = this->InternalAddRef(); if (newRefCount == 2) _pAtlModule->Lock(); return newRefCount; @@ -295,11 +283,9 @@ public: STDMETHOD_(ULONG, Release)() { - CComObjectCached *pThis; ULONG newRefCount; - pThis = reinterpret_cast*>(this); - newRefCount = pThis->InternalRelease(); + newRefCount = this->InternalRelease(); if (newRefCount == 0) delete this; else if (newRefCount == 1) @@ -309,10 +295,7 @@ public: STDMETHOD(QueryInterface)(REFIID iid, void **ppvObject) { - CComObjectCached *pThis; - - pThis = reinterpret_cast*>(this); - return pThis->_InternalQueryInterface(iid, ppvObject); + return this->_InternalQueryInterface(iid, ppvObject); } }; @@ -436,6 +419,11 @@ class CComClassFactory : { public: _ATL_CREATORFUNC *m_pfnCreateInstance; + + virtual ~CComClassFactory() + { + } + public: STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void **ppvObj) { diff --git a/reactos/lib/atl/statreg.h b/reactos/lib/atl/statreg.h index 6ae3187e5aa..33f219a4779 100644 --- a/reactos/lib/atl/statreg.h +++ b/reactos/lib/atl/statreg.h @@ -63,6 +63,7 @@ public: hResult = ClearReplacements(); ATLASSERT(SUCCEEDED(hResult)); + (void)hResult; } HRESULT STDMETHODCALLTYPE QueryInterface(const IID & /* riid */, void ** /* ppvObject */ ) From 2f8130c2284e991bdb8565bb164121261d305da4 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 4 May 2013 09:23:52 +0000 Subject: [PATCH 28/67] [KERNEL32] Parameters of RtlAcquirePrivilege are not booleans svn path=/trunk/; revision=58919 --- reactos/dll/win32/kernel32/client/job.c | 2 +- reactos/dll/win32/kernel32/client/utils.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/job.c b/reactos/dll/win32/kernel32/client/job.c index e5a20c0bca6..cdefe6149cb 100644 --- a/reactos/dll/win32/kernel32/client/job.c +++ b/reactos/dll/win32/kernel32/client/job.c @@ -291,7 +291,7 @@ SetInformationJobObject(IN HANDLE hJob, if (LocalInfo.BasicLimitInformation.LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET) { - Status = RtlAcquirePrivilege(&Privilege, TRUE, FALSE, &State); + Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State); } } diff --git a/reactos/dll/win32/kernel32/client/utils.c b/reactos/dll/win32/kernel32/client/utils.c index 3cf44f0e591..089bda3f709 100644 --- a/reactos/dll/win32/kernel32/client/utils.c +++ b/reactos/dll/win32/kernel32/client/utils.c @@ -627,7 +627,7 @@ BasepIsRealtimeAllowed(IN BOOLEAN Keep) PVOID State; NTSTATUS Status; - Status = RtlAcquirePrivilege(&Privilege, TRUE, FALSE, &State); + Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State); if (!NT_SUCCESS(Status)) return NULL; if (Keep) From 857fc1d093ea59c308c0ed6a7e86343a2fb3effb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 May 2013 14:04:35 +0000 Subject: [PATCH 29/67] Code reorganization only. svn path=/trunk/; revision=58920 --- reactos/dll/ntdll/csr/connect.c | 278 ++++++++++++++++---------------- 1 file changed, 139 insertions(+), 139 deletions(-) diff --git a/reactos/dll/ntdll/csr/connect.c b/reactos/dll/ntdll/csr/connect.c index 41ce5264677..a7bf85a32a4 100644 --- a/reactos/dll/ntdll/csr/connect.c +++ b/reactos/dll/ntdll/csr/connect.c @@ -30,145 +30,6 @@ PCSR_SERVER_API_ROUTINE CsrServerApiRoutine; /* FUNCTIONS ******************************************************************/ -/* - * @implemented - */ -HANDLE -NTAPI -CsrGetProcessId(VOID) -{ - return CsrProcessId; -} - -/* - * @implemented - */ -NTSTATUS -NTAPI -CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, - IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, - IN CSR_API_NUMBER ApiNumber, - IN ULONG DataLength) -{ - NTSTATUS Status; - ULONG PointerCount; - PULONG_PTR OffsetPointer; - - /* Fill out the Port Message Header */ - ApiMessage->Header.u2.ZeroInit = 0; - ApiMessage->Header.u1.s1.TotalLength = - FIELD_OFFSET(CSR_API_MESSAGE, Data) + DataLength; - ApiMessage->Header.u1.s1.DataLength = - ApiMessage->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); - - /* Fill out the CSR Header */ - ApiMessage->ApiNumber = ApiNumber; - ApiMessage->CsrCaptureData = NULL; - - DPRINT("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n", - ApiNumber, - ApiMessage->Header.u1.s1.DataLength, - ApiMessage->Header.u1.s1.TotalLength); - - /* Check if we are already inside a CSR Server */ - if (!InsideCsrProcess) - { - /* Check if we got a Capture Buffer */ - if (CaptureBuffer) - { - /* - * We have to convert from our local (client) view - * to the remote (server) view. - */ - ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER) - ((ULONG_PTR)CaptureBuffer + CsrPortMemoryDelta); - - /* Lock the buffer. */ - CaptureBuffer->BufferEnd = NULL; - - /* - * Each client pointer inside the CSR message is converted into - * a server pointer, and each pointer to these message pointers - * is converted into an offset. - */ - PointerCount = CaptureBuffer->PointerCount; - OffsetPointer = CaptureBuffer->PointerOffsetsArray; - while (PointerCount--) - { - if (*OffsetPointer != 0) - { - *(PULONG_PTR)*OffsetPointer += CsrPortMemoryDelta; - *OffsetPointer -= (ULONG_PTR)ApiMessage; - } - ++OffsetPointer; - } - } - - /* Send the LPC Message */ - Status = NtRequestWaitReplyPort(CsrApiPort, - &ApiMessage->Header, - &ApiMessage->Header); - - /* Check if we got a Capture Buffer */ - if (CaptureBuffer) - { - /* - * We have to convert back from the remote (server) view - * to our local (client) view. - */ - ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER) - ((ULONG_PTR)ApiMessage->CsrCaptureData - CsrPortMemoryDelta); - - /* - * Convert back the offsets into pointers to CSR message - * pointers, and convert back these message server pointers - * into client pointers. - */ - PointerCount = CaptureBuffer->PointerCount; - OffsetPointer = CaptureBuffer->PointerOffsetsArray; - while (PointerCount--) - { - if (*OffsetPointer != 0) - { - *OffsetPointer += (ULONG_PTR)ApiMessage; - *(PULONG_PTR)*OffsetPointer -= CsrPortMemoryDelta; - } - ++OffsetPointer; - } - } - - /* Check for success */ - if (!NT_SUCCESS(Status)) - { - /* We failed. Overwrite the return value with the failure. */ - DPRINT1("LPC Failed: %lx\n", Status); - ApiMessage->Status = Status; - } - } - else - { - /* This is a server-to-server call. Save our CID and do a direct call. */ - DPRINT1("Next gen server-to-server call\n"); - - /* We check this equality inside CsrValidateMessageBuffer */ - ApiMessage->Header.ClientId = NtCurrentTeb()->ClientId; - - Status = CsrServerApiRoutine(&ApiMessage->Header, - &ApiMessage->Header); - - /* Check for success */ - if (!NT_SUCCESS(Status)) - { - /* We failed. Overwrite the return value with the failure. */ - ApiMessage->Status = Status; - } - } - - /* Return the CSR Result */ - DPRINT("Got back: 0x%lx\n", ApiMessage->Status); - return ApiMessage->Status; -} - NTSTATUS NTAPI CsrpConnectToServer(IN PWSTR ObjectDirectory) @@ -460,4 +321,143 @@ CsrClientConnectToServer(IN PWSTR ObjectDirectory, return Status; } +/* + * @implemented + */ +NTSTATUS +NTAPI +CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, + IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, + IN CSR_API_NUMBER ApiNumber, + IN ULONG DataLength) +{ + NTSTATUS Status; + ULONG PointerCount; + PULONG_PTR OffsetPointer; + + /* Fill out the Port Message Header */ + ApiMessage->Header.u2.ZeroInit = 0; + ApiMessage->Header.u1.s1.TotalLength = + FIELD_OFFSET(CSR_API_MESSAGE, Data) + DataLength; + ApiMessage->Header.u1.s1.DataLength = + ApiMessage->Header.u1.s1.TotalLength - sizeof(PORT_MESSAGE); + + /* Fill out the CSR Header */ + ApiMessage->ApiNumber = ApiNumber; + ApiMessage->CsrCaptureData = NULL; + + DPRINT("API: %lx, u1.s1.DataLength: %x, u1.s1.TotalLength: %x\n", + ApiNumber, + ApiMessage->Header.u1.s1.DataLength, + ApiMessage->Header.u1.s1.TotalLength); + + /* Check if we are already inside a CSR Server */ + if (!InsideCsrProcess) + { + /* Check if we got a Capture Buffer */ + if (CaptureBuffer) + { + /* + * We have to convert from our local (client) view + * to the remote (server) view. + */ + ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER) + ((ULONG_PTR)CaptureBuffer + CsrPortMemoryDelta); + + /* Lock the buffer. */ + CaptureBuffer->BufferEnd = NULL; + + /* + * Each client pointer inside the CSR message is converted into + * a server pointer, and each pointer to these message pointers + * is converted into an offset. + */ + PointerCount = CaptureBuffer->PointerCount; + OffsetPointer = CaptureBuffer->PointerOffsetsArray; + while (PointerCount--) + { + if (*OffsetPointer != 0) + { + *(PULONG_PTR)*OffsetPointer += CsrPortMemoryDelta; + *OffsetPointer -= (ULONG_PTR)ApiMessage; + } + ++OffsetPointer; + } + } + + /* Send the LPC Message */ + Status = NtRequestWaitReplyPort(CsrApiPort, + &ApiMessage->Header, + &ApiMessage->Header); + + /* Check if we got a Capture Buffer */ + if (CaptureBuffer) + { + /* + * We have to convert back from the remote (server) view + * to our local (client) view. + */ + ApiMessage->CsrCaptureData = (PCSR_CAPTURE_BUFFER) + ((ULONG_PTR)ApiMessage->CsrCaptureData - CsrPortMemoryDelta); + + /* + * Convert back the offsets into pointers to CSR message + * pointers, and convert back these message server pointers + * into client pointers. + */ + PointerCount = CaptureBuffer->PointerCount; + OffsetPointer = CaptureBuffer->PointerOffsetsArray; + while (PointerCount--) + { + if (*OffsetPointer != 0) + { + *OffsetPointer += (ULONG_PTR)ApiMessage; + *(PULONG_PTR)*OffsetPointer -= CsrPortMemoryDelta; + } + ++OffsetPointer; + } + } + + /* Check for success */ + if (!NT_SUCCESS(Status)) + { + /* We failed. Overwrite the return value with the failure. */ + DPRINT1("LPC Failed: %lx\n", Status); + ApiMessage->Status = Status; + } + } + else + { + /* This is a server-to-server call. Save our CID and do a direct call. */ + DPRINT1("Next gen server-to-server call\n"); + + /* We check this equality inside CsrValidateMessageBuffer */ + ApiMessage->Header.ClientId = NtCurrentTeb()->ClientId; + + Status = CsrServerApiRoutine(&ApiMessage->Header, + &ApiMessage->Header); + + /* Check for success */ + if (!NT_SUCCESS(Status)) + { + /* We failed. Overwrite the return value with the failure. */ + ApiMessage->Status = Status; + } + } + + /* Return the CSR Result */ + DPRINT("Got back: 0x%lx\n", ApiMessage->Status); + return ApiMessage->Status; +} + +/* + * @implemented + */ +HANDLE +NTAPI +CsrGetProcessId(VOID) +{ + return CsrProcessId; +} + /* EOF */ From 51bd04ab2a6ccb9b76f6bec4abd042c2ff0eb25f Mon Sep 17 00:00:00 2001 From: Olaf Siejka Date: Sat, 4 May 2013 14:18:45 +0000 Subject: [PATCH 30/67] [TRANSLATION] - turkish translation update by Erdem Ersoy: CORE-7133; - czech translation update by Radek Liska: CORE-6953; - added polish translation of hostname; svn path=/trunk/; revision=58921 --- .../cmdutils/hostname/lang/cs-CZ.rc | 13 ++ .../cmdutils/hostname/lang/pl-PL.rc | 8 ++ .../applications/cmdutils/hostname/rsrc.rc | 6 + .../applications/cmdutils/reg/lang/cs-CZ.rc | 21 +++ .../base/applications/cmdutils/reg/rsrc.rc | 3 + .../base/applications/dxdiag/lang/tr-TR.rc | 128 +++++++++--------- .../base/applications/kbswitch/lang/tr-TR.rc | 11 ++ reactos/base/applications/kbswitch/rsrc.rc | 3 + .../network/wlanconf/lang/cs-CZ.rc | 44 ++++++ .../applications/network/wlanconf/wlanconf.rc | 3 + .../base/applications/regedit/lang/cs-CZ.rc | 10 +- reactos/dll/cpl/desk/lang/cs-CZ.rc | 4 +- reactos/dll/win32/msgina/lang/cs-CZ.rc | 36 ++--- 13 files changed, 201 insertions(+), 89 deletions(-) create mode 100644 reactos/base/applications/cmdutils/hostname/lang/cs-CZ.rc create mode 100644 reactos/base/applications/cmdutils/hostname/lang/pl-PL.rc create mode 100644 reactos/base/applications/cmdutils/reg/lang/cs-CZ.rc create mode 100644 reactos/base/applications/kbswitch/lang/tr-TR.rc create mode 100644 reactos/base/applications/network/wlanconf/lang/cs-CZ.rc diff --git a/reactos/base/applications/cmdutils/hostname/lang/cs-CZ.rc b/reactos/base/applications/cmdutils/hostname/lang/cs-CZ.rc new file mode 100644 index 00000000000..f9e673b6490 --- /dev/null +++ b/reactos/base/applications/cmdutils/hostname/lang/cs-CZ.rc @@ -0,0 +1,13 @@ +/* FILE: base/applications/cmdutils/hostname/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * UPDATED: 2013-05-01 + */ + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +BEGIN + IDS_USAGE, "Vypíše souÄasný název hostitele.\n\nhostname" + IDS_NOSET, "hostname -s není podporováno." + IDS_ERROR, "Win32 chyba" +END diff --git a/reactos/base/applications/cmdutils/hostname/lang/pl-PL.rc b/reactos/base/applications/cmdutils/hostname/lang/pl-PL.rc new file mode 100644 index 00000000000..237bbc92ece --- /dev/null +++ b/reactos/base/applications/cmdutils/hostname/lang/pl-PL.rc @@ -0,0 +1,8 @@ +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +BEGIN + IDS_USAGE, "Wyœwietla obecn¹ nazwê komputera.\n\nhostname" + IDS_NOSET, "Opcja hostname -s nie jest wspierana." + IDS_ERROR, "B³¹d Win32" +END diff --git a/reactos/base/applications/cmdutils/hostname/rsrc.rc b/reactos/base/applications/cmdutils/hostname/rsrc.rc index 5177a1c5183..8af49ff75bb 100644 --- a/reactos/base/applications/cmdutils/hostname/rsrc.rc +++ b/reactos/base/applications/cmdutils/hostname/rsrc.rc @@ -3,9 +3,15 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // UTF-8 #pragma code_page(65001) +#ifdef LANGUAGE_CS_CZ + #include "lang/cs-CZ.rc" +#endif #ifdef LANGUAGE_EN_US #include "lang/en-US.rc" #endif #ifdef LANGUAGE_FR_FR #include "lang/fr-FR.rc" #endif +#ifdef LANGUAGE_PL_PL + #include "lang/pl-PL.rc" +#endif diff --git a/reactos/base/applications/cmdutils/reg/lang/cs-CZ.rc b/reactos/base/applications/cmdutils/reg/lang/cs-CZ.rc new file mode 100644 index 00000000000..7fe0da91d96 --- /dev/null +++ b/reactos/base/applications/cmdutils/reg/lang/cs-CZ.rc @@ -0,0 +1,21 @@ +/* FILE: base/applications/cmdutils/reg/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * UPDATED: 2013-05-01 + */ + +#include "reg.h" + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +STRINGTABLE +{ + STRING_USAGE, "Syntaxe tohoto příkazu:\n\nREG [ ADD | DELETE | QUERY ]\nREG operace /?\n" + STRING_ADD_USAGE, "REG ADD název_klíÄe [/v název_hodnoty | /ve] [/t type] [/s oddÄ›lovaÄ] [/d data] [/f]\n" + STRING_DELETE_USAGE, "REG DELETE název_klíÄe [/v název_hodnoty | /ve | /va] [/f]\n" + STRING_QUERY_USAGE, "REG QUERY název_klíÄe [/v název_hodnoty | /ve] [/s]\n" + STRING_SUCCESS, "Operace byla úspěšnÄ› dokonÄena\n" + STRING_INVALID_KEY, "Chyba: Neplatný název klíÄe\n" + STRING_INVALID_CMDLINE, "Chyba: Neplatné parametry příkazové řádky\n" + STRING_NO_REMOTE, "Chyba: Nelze pÅ™idat klíÄe na vzdálený stroj\n" + STRING_CANNOT_FIND, "Chyba: Systém nenalezl zadaný klÃ­Ä nebo hodnotu registru\n" +} diff --git a/reactos/base/applications/cmdutils/reg/rsrc.rc b/reactos/base/applications/cmdutils/reg/rsrc.rc index 1543c1d9881..04574a4d7ec 100644 --- a/reactos/base/applications/cmdutils/reg/rsrc.rc +++ b/reactos/base/applications/cmdutils/reg/rsrc.rc @@ -3,6 +3,9 @@ #ifdef LANGUAGE_BG_BG #include "lang/bg-BG.rc" #endif +#ifdef LANGUAGE_CS_CZ + #include "lang/cs-CZ.rc" +#endif #ifdef LANGUAGE_DA_DK #include "lang/da-DK.rc" #endif diff --git a/reactos/base/applications/dxdiag/lang/tr-TR.rc b/reactos/base/applications/dxdiag/lang/tr-TR.rc index 672194f6502..a5ac796ebb9 100644 --- a/reactos/base/applications/dxdiag/lang/tr-TR.rc +++ b/reactos/base/applications/dxdiag/lang/tr-TR.rc @@ -1,5 +1,5 @@ /* - * Çeviri: Arda Tanrıkulu + * Çeviri: Arda Tanrıkulu (ardatanrikulu@gmail.com), Erdem Ersoy (erdemersoy@live.com) */ LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT @@ -12,7 +12,7 @@ FONT 8, "MS Shell Dlg" BEGIN CONTROL "Tab1",IDC_TAB_CONTROL,"SysTabControl32",WS_TABSTOP,2,2,474,250 PUSHBUTTON "&Yardım", IDC_BUTTON_HELP, 2, 261, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP - DEFPUSHBUTTON "S&onraki Sayfa", IDC_BUTTON_NEXT, 257, 261, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP + DEFPUSHBUTTON "&Sonraki Bölüm", IDC_BUTTON_NEXT, 257, 261, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP PUSHBUTTON "&Tüm Bilgileri Kaydet...", IDC_BUTTON_SAVE_INFO, 311, 261, 110, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP PUSHBUTTON "&Çıkış", IDC_BUTTON_EXIT, 425, 261, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP END @@ -21,19 +21,19 @@ IDD_SYSTEM_DIALOG DIALOGEX DISCARDABLE 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN - LTEXT "Bu araç, sisteminizde yüklü ReactX bileÅŸenleri ve sürücüleri hakkında detaylı bilgi raporlar. İşlevselliÄŸi sınamanızı, sorunları tanımanızı en iyi ÅŸekilde çalışmak için sistem yapılandırmanızı deÄŸiÅŸtirmenizi saÄŸlar.", -1, 10, 10, 443, 17 - LTEXT "Hangi alanın soruna neden olduÄŸunu biliyorsanız, yukarıda uygun sekmeyi tıklatın. Aksi halde, sırayla her sayfaya gitmek için aÅŸağıdaki ""Sonraki Sayfa"" düğmesini kullanabilirsiniz.", -1, 10, 30, 443, 25 - GROUPBOX "Sistem Bilgisi", -1, 10, 55, 443, 130, SS_RIGHT - LTEXT "Geçerli Tarih/Saat:", -1, 70, 70, 80, 10, SS_RIGHT - LTEXT "Bilgisayar Adı:", -1, 70, 80, 80, 10, SS_RIGHT - LTEXT "İşletim Sistemi:", -1, 70, 90, 80, 10, SS_RIGHT + LTEXT "Bu araç, dizgenizde yüklü ReactX bileÅŸenleri ve sürücüleri hakkında ayrıntılı bilgi yazanaklar.", -1, 10, 10, 443, 17 + LTEXT "Soruna hangi bölümün neden olduÄŸunu biliyorsanız, yukarıdaki uygun sekmeyi tıklatınız. Bilmiyorsanız sırayla her bölüme gitmek için aÅŸağıdaki ""Sonraki Bölüm"" düğmesini kullanabilirsiniz.", -1, 10, 30, 443, 25 + GROUPBOX "Bilgisayar Bilgisi", -1, 10, 55, 443, 130, SS_RIGHT + LTEXT "Geçerli Zaman:", -1, 70, 70, 80, 10, SS_RIGHT + LTEXT "Ad:", -1, 70, 80, 80, 10, SS_RIGHT + LTEXT "İşletim Dizgesi:", -1, 70, 90, 80, 10, SS_RIGHT LTEXT "Dil:", -1, 70, 100, 80, 10, SS_RIGHT - LTEXT "Sistem Üreticisi:", -1, 70, 110, 80, 10, SS_RIGHT - LTEXT "Sistem Modeli:", -1, 70, 120, 80, 10, SS_RIGHT + LTEXT "Üretici:", -1, 70, 110, 80, 10, SS_RIGHT + LTEXT "Biçim:", -1, 70, 120, 80, 10, SS_RIGHT LTEXT "BIOS:", -1, 70, 130, 80, 10, SS_RIGHT LTEXT "İşlemci:", -1, 70, 140, 80, 10, SS_RIGHT LTEXT "Bellek:", -1, 70, 150, 80, 10, SS_RIGHT - LTEXT "Sayfa Dosyası:", -1, 70, 160, 80, 10, SS_RIGHT + LTEXT "Disk BelleÄŸi:", -1, 70, 160, 80, 10, SS_RIGHT LTEXT "ReactX Sürümü:", -1, 70, 170, 80, 10, SS_RIGHT LTEXT "", IDC_STATIC_TIME, 155, 70, 195, 10, SS_LEFT LTEXT "", IDC_STATIC_COMPUTER, 155, 80, 195, 10, SS_LEFT @@ -55,11 +55,11 @@ BEGIN GROUPBOX "Aygıt", -1, 10, 10, 250, 100 RTEXT "Ad:", -1, 20, 25, 70, 10 RTEXT "Üretici:", -1, 20, 35, 70, 10 - RTEXT "Yonga türü:", -1, 20, 45, 70, 10 - RTEXT "DAC türü:", -1, 20, 55, 70, 10 - RTEXT "Yaklaşık Top. Bellek:", -1, 20, 65, 70, 10 - RTEXT "Geçerli Görüntü Modu:", -1, 20, 75, 70, 10 - RTEXT "Monitör:", -1, 20, 85, 70, 10 + RTEXT "Yonga Türü:", -1, 20, 45, 70, 10 + RTEXT "DAC Türü:", -1, 20, 55, 70, 10 + RTEXT "Yaklaşık Toplam Bellek:", -1, 20, 65, 70, 10 + RTEXT "Geçerli Görüntü SeçeneÄŸi:", -1, 20, 75, 70, 10 + RTEXT "Göstergeç:", -1, 20, 85, 70, 10 LTEXT "", IDC_STATIC_ADAPTER_ID, 95, 25, 150, 10 LTEXT "", IDC_STATIC_ADAPTER_VENDOR, 95, 35, 150, 10 LTEXT "", IDC_STATIC_ADAPTER_CHIP, 95, 45, 150, 10 @@ -71,8 +71,8 @@ BEGIN GROUPBOX "Sürücüler", -1, 270, 10, 190, 100 RTEXT "Ana Sürücü:", -1, 275, 25, 55, 10 RTEXT "Sürüm:", -1, 275, 35, 55, 10 - RTEXT "Tarih:", -1, 275, 45, 55, 10 - RTEXT "WHQL Logolu:", -1, 275, 55, 55, 10 + RTEXT "Zaman:", -1, 275, 45, 55, 10 + RTEXT "WHQL İmleÄŸi:", -1, 275, 55, 55, 10 RTEXT "Mini VDD:", -1, 275, 65, 55, 10 RTEXT " vvdddVDD:", -1, 275, 75, 55, 10 RTEXT "DDI Sürümü:", -1, 275, 85, 55, 10 @@ -85,17 +85,17 @@ BEGIN LTEXT "", IDC_STATIC_ADAPTER_DDI, 335, 85, 100, 10 GROUPBOX "ReactX Özellikleri", -1, 10, 115, 450, 60 - RTEXT "DirectDraw Hızlandırması:", -1, 15, 130, 110, 12 - RTEXT "Direct3D Hızlandırması:", -1, 15, 145, 110, 12 + RTEXT "ReactDraw Hızlandırması:", -1, 15, 130, 110, 12 + RTEXT "React3D Hızlandırması:", -1, 15, 145, 110, 12 RTEXT "AGP Doku Hızlandırması:", -1, 15, 160, 110, 12 LTEXT "", IDC_STATIC_DDSTATE, 130, 130, 40, 10 LTEXT "", IDC_STATIC_D3DSTATE, 130, 145, 40, 10 LTEXT "", IDC_STATIC_AGPSTATE, 130, 160, 40, 10 - PUSHBUTTON "Enable", IDC_BUTTON_DDRAW, 170, 124, 60, 14, WS_DISABLED - PUSHBUTTON "Enable", IDC_BUTTON_D3D, 170, 140, 60, 14, WS_DISABLED - PUSHBUTTON "Enable", IDC_BUTTON_AGP, 170, 156, 60, 14, WS_DISABLED - PUSHBUTTON "DirectDra&w Sınaması Yap", IDC_BUTTON_TESTDD, 250, 124, 80, 14 - PUSHBUTTON "Dire&ct3D Sınaması Yap", IDC_BUTTON_TEST3D, 250, 140, 80, 14 + PUSHBUTTON "EtkinleÅŸtir", IDC_BUTTON_DDRAW, 170, 124, 60, 14, WS_DISABLED + PUSHBUTTON "EtkinleÅŸtir", IDC_BUTTON_D3D, 170, 140, 60, 14, WS_DISABLED + PUSHBUTTON "EtkinleÅŸtir", IDC_BUTTON_AGP, 170, 156, 60, 14, WS_DISABLED + PUSHBUTTON "&ReactDraw'ı Sına", IDC_BUTTON_TESTDD, 250, 124, 80, 14 + PUSHBUTTON "R&eact3D'yi Sına", IDC_BUTTON_TEST3D, 250, 140, 80, 14 GROUPBOX "Notlar", -1, 10, 180, 450, 40 EDITTEXT IDC_TEXT_INFO, 20, 192, 432, 20, WS_DISABLED | WS_TABSTOP @@ -108,11 +108,11 @@ FONT 8, "MS Shell Dlg" BEGIN GROUPBOX "Aygıt", -1, 10, 10, 250, 100 RTEXT "Ad:", -1, 20, 25, 70, 10 - RTEXT "Aygıt tanıtıcı:", -1, 20, 35, 70, 10 + RTEXT "Aygıt KimliÄŸi:", -1, 20, 35, 70, 10 RTEXT "Üretici KimliÄŸi:", -1, 20, 45, 70, 10 RTEXT "Ürün KimliÄŸi:", -1, 20, 55, 70, 10 RTEXT "Tür:", -1, 20, 65, 70, 10 - RTEXT "Varsayılan aygıt:", -1, 20, 75, 70, 10 + RTEXT "Varsayılan Aygıt:", -1, 20, 75, 70, 10 LTEXT "", IDC_STATIC_DSOUND_NAME, 95, 25, 150, 10 LTEXT "", IDC_STATIC_DSOUND_DEVICEID, 95, 35, 150, 10 LTEXT "", IDC_STATIC_DSOUND_VENDORID, 95, 45, 150, 10 @@ -122,9 +122,9 @@ BEGIN GROUPBOX "Sürücü", -1, 270, 10, 190, 100 RTEXT "Ad:", -1, 275, 25, 55, 10 RTEXT "Sürüm:", -1, 275, 35, 55, 10 - RTEXT "Tarih:", -1, 275, 45, 55, 10 - RTEXT "WHQL Logolu:", -1, 275, 55, 55, 10 - RTEXT "DiÄŸer Dosyalar:", -1, 275, 65, 55, 10 + RTEXT "Zaman:", -1, 275, 45, 55, 10 + RTEXT "WHQL İmleÄŸi:", -1, 275, 55, 55, 10 + RTEXT "DiÄŸer Kütükler:", -1, 275, 65, 55, 10 RTEXT "SaÄŸlayıcı:", -1, 275, 75, 55, 10 LTEXT "", IDC_STATIC_DSOUND_DRIVER, 335, 25, 100, 10 LTEXT "", IDC_STATIC_DSOUND_VERSION, 335, 35, 100, 10 @@ -134,8 +134,8 @@ BEGIN LTEXT "", IDC_STATIC_ADAPTER_PROVIDER, 335, 75, 100, 10 GROUPBOX "ReactX Özellikleri", -1, 10, 115, 450, 60 CONTROL "", IDC_SLIDER_DSOUND, "msctls_trackbar32", TBS_BOTTOM | TBS_AUTOTICKS | WS_TABSTOP, 120, 135, 80, 17 - RTEXT "Donanım Ses\nHızlandırma Düzeyi:", -1, 20, 135, 90, 20 - PUSHBUTTON "DirectSo&und'u Sına", IDC_BUTTON_TESTDSOUND, 270, 134, 80, 14 + RTEXT "Donanım İvmesi:", -1, 20, 135, 90, 20 + PUSHBUTTON "&ReactSound'u Sına", IDC_BUTTON_TESTDSOUND, 270, 134, 80, 14 GROUPBOX "Notlar", -1, 10, 180, 450, 40 EDITTEXT IDC_TEXT_DSOUNDINFO, 20, 192, 432, 20, WS_DISABLED | WS_TABSTOP END @@ -151,7 +151,7 @@ IDD_INPUT_DIALOG DIALOGEX DISCARDABLE 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "DirectInput Aygıtları", -1, 10, 10, 452, 80 + GROUPBOX "ReactInput Aygıtları", -1, 10, 10, 452, 80 CONTROL "", IDC_LIST_DEVICE, "SysListView32", LVS_REPORT | WS_CHILD | WS_BORDER | WS_TABSTOP, 20, 22, 432, 60 GROUPBOX "GiriÅŸle İlgili Aygıtlar", -1, 10, 100, 452, 60 CONTROL "", IDC_TREE_PORT, "SysTreeView32", TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 20, 112, 432, 40, 0x00000200 @@ -163,7 +163,7 @@ IDD_NETWORK_DIALOG DIALOGEX DISCARDABLE 0, 0, 462, 220 STYLE DS_SHELLFONT | DS_CONTROL | WS_CHILD | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN - GROUPBOX "Kayıtlı DirectPlay Hizmet SaÄŸlayıcıları", -1, 10, 10, 452, 80 + GROUPBOX "Kayıtlı ReactPlay Hizmet SaÄŸlayıcıları", -1, 10, 10, 452, 80 CONTROL "", IDC_LIST_PROVIDER, "SysListView32", LVS_REPORT | WS_CHILD | WS_BORDER | WS_TABSTOP, 20, 22, 432, 60 END @@ -176,54 +176,54 @@ END STRINGTABLE DISCARDABLE BEGIN IDS_MAIN_DIALOG "ReactX Tanı Aracı" - IDS_SYSTEM_DIALOG "Sistem" + IDS_SYSTEM_DIALOG "Dizge" IDS_DISPLAY_DIALOG "Görüntü" IDS_SOUND_DIALOG "Ses" - IDS_MUSIC_DIALOG "Müzik" + IDS_MUSIC_DIALOG "Mûsiki" IDS_INPUT_DIALOG "GiriÅŸ" IDS_NETWORK_DIALOG "AÄŸ" IDS_HELP_DIALOG "Yardım" - IDS_FORMAT_MB "%I64uMB RAM" - IDS_FORMAT_SWAP "%I64u MB kullanılan, %I64u MB kullanılabilir" + IDS_FORMAT_MB "%I64u MB RAM" + IDS_FORMAT_SWAP "%I64u MB kullanıldı, %I64u MB kullanılabilir" IDS_FORMAT_UNIPROC "%s (%u CPU)" - IDS_FORMAT_MPPROC "%s (%u CPUlar)" + IDS_FORMAT_MPPROC "%s (%u CPU)" IDS_VERSION_UNKNOWN "Bilinmeyen Sürüm" IDS_DEVICE_STATUS_ATTACHED "BaÄŸlı" IDS_DEVICE_STATUS_MISSING "BaÄŸlı deÄŸil" IDS_DEVICE_STATUS_UNKNOWN "Bilinmiyor" - IDS_DEVICE_NAME "Aygıt adı" + IDS_DEVICE_NAME "Aygıt Adı" IDS_DEVICE_STATUS "Durum" IDS_DEVICE_CONTROLLER "Denetleyici KimliÄŸi" IDS_DEVICE_MANUFACTURER "Üretici KimliÄŸi" - IDS_DEVICE_PRODUCT "Ürüm KimliÄŸi" - IDS_DEVICE_FORCEFEEDBACK "Force Feedback Sürücü" - IDS_NOT_APPLICABLE "Kullanılamaz" + IDS_DEVICE_PRODUCT "Ürün KimliÄŸi" + IDS_DEVICE_FORCEFEEDBACK "Güç Geribildirimli Sürücüsü" + IDS_NOT_APPLICABLE "Uygulanamaz" IDS_OPTION_YES "Evet" IDS_DIRECTPLAY_COL_NAME1 "Ad" - IDS_DIRECTPLAY_COL_NAME2 "Kayıt" - IDS_DIRECTPLAY_COL_NAME3 "Dosya" + IDS_DIRECTPLAY_COL_NAME2 "DeÄŸer" + IDS_DIRECTPLAY_COL_NAME3 "Kütük" IDS_DIRECTPLAY_COL_NAME4 "Sürüm" - IDS_DIRECTPLAY8_MODEMSP "DirectPlay8-Modem Servis SaÄŸlayıcısı" - IDS_DIRECTPLAY8_SERIALSP "DirectPlay8 Seri Servis SaÄŸlayıcısı" - IDS_DIRECTPLAY8_IPXSP "DirectPlay8 IPX Servis SaÄŸlayıcısı" - IDS_DIRECTPLAY8_TCPSP "DirectPlay8-TCP/IP Servis SaÄŸlayıcısı" - IDS_DIRECTPLAY_TCPCONN "DirectPlay için Internet TCP/IP BaÄŸlantısı" - IDS_DIRECTPLAY_IPXCONN "DirectPlay için IPX BaÄŸlantısı" - IDS_DIRECTPLAY_MODEMCONN "DirectPlay için Modem BaÄŸlantısı" - IDS_DIRECTPLAY_SERIALCONN "DirectPlay için Seri BaÄŸlantı" + IDS_DIRECTPLAY8_MODEMSP "ReactPlay8 Çevirge Hizmeti SaÄŸlayıcısı" + IDS_DIRECTPLAY8_SERIALSP "ReactPlay8 Dizi Hizmeti SaÄŸlayıcısı" + IDS_DIRECTPLAY8_IPXSP "ReactPlay8 IPX Hizmeti SaÄŸlayıcısı" + IDS_DIRECTPLAY8_TCPSP "ReactPlay8 TCP/IP Hizmeti SaÄŸlayıcısı" + IDS_DIRECTPLAY_TCPCONN "ReactPlay için GenelaÄŸ TCP/IP BaÄŸlantısı" + IDS_DIRECTPLAY_IPXCONN "ReactPlay için IPX BaÄŸlantısı" + IDS_DIRECTPLAY_MODEMCONN "ReactPlay için Çeivrge BaÄŸlantısı" + IDS_DIRECTPLAY_SERIALCONN "ReactPlay için Dizi BaÄŸlantısı" IDS_REG_SUCCESS "Tamam" IDS_REG_FAIL "Hata" - IDS_DDTEST_ERROR "Test baÅŸarısız oldu!" - IDS_DDTEST_DESCRIPTION "DirectDraw arayüz sınaması baÅŸlatılacak. Devam?" - IDS_DDPRIMARY_DESCRIPTION "Bu sınama DirectDraw'u birincil yüzeye yazmak için kullanacak. Siyah ve beyaz dikdörtgenler çizilecek. Devam?" - IDS_DDPRIMARY_RESULT "Siyah ve beyaz dikdörtgenler gördünüz mü?" - IDS_DDOFFSCREEN_DESCRIPTION "Bu sınama DirectDraw'u ekranüstü arabelleÄŸi kullanacak. Hareket eden beyaz dikdörtgen göreceksiniz. Devam?" - IDS_DDOFFSCREEN_RESULT "Hareket eden beyaz dikdörtgen gördünüz mü?" - IDS_DDFULLSCREEN_DESCRIPTION "Bu sınama DirectDraw ile tam ekran yazım yapacak. Hareket eden beyaz dikdörtgen göreceksiniz. Devam?" - IDS_DDFULLSCREEN_RESULT "Tam ekran modunda hareket eden beyaz dikdörtgen gördünüz mü?" + IDS_DDTEST_ERROR "Sınama baÅŸarısız oldu." + IDS_DDTEST_DESCRIPTION "ReactDraw arayüz sınaması baÅŸlatılacak. Sürdürülsün mü?" + IDS_DDPRIMARY_DESCRIPTION "Bu sınama, ReactDraw'ı birincil yüzeye çizmek için kullanacak. Ekrana ak ve kara dikdörtgenler çizilecek. Sürdürülsün mü?" + IDS_DDPRIMARY_RESULT "Ekranda ak ve kara dikdörtgenler gördünüz mü?" + IDS_DDOFFSCREEN_DESCRIPTION "Bu sınama, ReactDraw'ı ekran dışı arabelleÄŸe çizmek için kullanacak. Ekranda devinen bir ak dikdörtgen göreceksiniz. Sürdürülsün mü?" + IDS_DDOFFSCREEN_RESULT "Ekranda devinen bir ak dikdörtgen gördünüz mü?" + IDS_DDFULLSCREEN_DESCRIPTION "Bu sınama, ReactDraw'ı tam ekranda çizmek için kullanacak. Tam ekranda devinen bir ak dikdörtgen göreceksiniz. Sürdürülsün mü?" + IDS_DDFULLSCREEN_RESULT "Tam ekranda devinen bir ak dikdörtgen gördünüz mü?" IDS_FORMAT_ADAPTER_MEM "%u MB" - IDS_FORMAT_ADAPTER_MODE "%04u x %04u (%u bit)(%uHz)" + IDS_FORMAT_ADAPTER_MODE "%04u x %04u (%u ikillik) (%uHz)" IDS_OPTION_NO "Hayır" - IDS_D3DTEST_DESCRIPTION "Direct3D arayüz sınaması baÅŸlatılacak. Devam?" - IDS_D3DTEST_D3Dx "Bu sınama donanım hızlandırmalı Direct3D %u arayüzünü kullanacak." + IDS_D3DTEST_DESCRIPTION "React3D arayüz sınaması baÅŸlatılacak. Sürdürülsün mü?" + IDS_D3DTEST_D3Dx "Bu sınama, donanım hızlandırmalı React3D %u arayüzünü kullanacak." END diff --git a/reactos/base/applications/kbswitch/lang/tr-TR.rc b/reactos/base/applications/kbswitch/lang/tr-TR.rc new file mode 100644 index 00000000000..a9f5e137449 --- /dev/null +++ b/reactos/base/applications/kbswitch/lang/tr-TR.rc @@ -0,0 +1,11 @@ +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +IDR_POPUP MENU +BEGIN + POPUP "popup" + BEGIN + MENUITEM "&YeÄŸlemeler...", ID_PREFERENCES + MENUITEM SEPARATOR + MENUITEM "&Çıkış", ID_EXIT + END +END diff --git a/reactos/base/applications/kbswitch/rsrc.rc b/reactos/base/applications/kbswitch/rsrc.rc index fa5a261ff71..4b98916b99b 100644 --- a/reactos/base/applications/kbswitch/rsrc.rc +++ b/reactos/base/applications/kbswitch/rsrc.rc @@ -52,6 +52,9 @@ #ifdef LANGUAGE_SV_SE #include "lang/sv-SE.rc" #endif +#ifdef LANGUAGE_TR_TR + #include "lang/tr-TR.rc" +#endif #ifdef LANGUAGE_UK_UA #include "lang/uk-UA.rc" #endif diff --git a/reactos/base/applications/network/wlanconf/lang/cs-CZ.rc b/reactos/base/applications/network/wlanconf/lang/cs-CZ.rc new file mode 100644 index 00000000000..1dd1f9cdbfc --- /dev/null +++ b/reactos/base/applications/network/wlanconf/lang/cs-CZ.rc @@ -0,0 +1,44 @@ +/* FILE: base/applications/network/wlanconf/lang/cs-CZ.rc + * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) + * UPDATED: 2013-02-15 + */ + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +BEGIN +IDS_USAGE, "\nNakonfiguruje bezdrátový síťový adaptér (WLAN).\n\n\ +WLANCONF [-c SSID [-w WEP] [-a]] [-d] [-s]\n\n\ +\t-c SSID\t\tPÅ™ipojí se k zadanému SSID.\n\ +\t-w WEP\t\tSpecifikuje použitý WEP klíÄ.\n\ +\t-a\t\tSpecifikuje, že cílová síť je v režimu ad hoc.\n\ +\t-d\t\tOdpojí se od souÄasného AP (přístupového bodu).\n\ +\t-s\t\tProhledá a zobrazí seznam přístupových bodů v dosahu.\n\ +SpuÅ¡tÄ›ní bez parametrů vypíše informace o souÄasném bezdrátovém pÅ™ipojení.\n" +/* === */ +IDS_NO_NETWORK, "Nebyly nalezeny žádné sítÄ›\n" +IDS_NO_WLAN_ADAPTER, "V systému nebyl nalezen WLAN adaptér\n" +IDS_SUCCESS, "Operace byla úspěšnÄ› dokonÄena.\n" +IDS_WLAN_DISCONNECT, "\nWLAN odpojen\n" +/* === */ +IDS_MSG_WEP_ENABLED, "WEP zapnuto: %s\n" +IDS_MSG_NETWORK_MODE, "Režim sítÄ›: %s\n" +IDS_MSG_CURRENT_WIRELESS, "\nAktuální informace o bezdrátové konfiguraci:\n\n" +IDS_MSG_ENCRYPTED, "ZaÅ¡ifrováno: %s\n" +IDS_MSG_NETWORK_TYPE, "Typ sítÄ›: %s\n" +IDS_MSG_RSSI, "RSSI: %i dBm\n" +IDS_MSG_SUPPORT_RATE, "Podporované rychlosti (Mbps): " +IDS_MSG_TRANSMISSION_POWER, "PÅ™enosový výkon: %d mW\n" +IDS_MSG_ANTENNA_COUNT, "PoÄet antén: %d\n" +IDS_MSG_TRANSMIT_ANTENNA, "Vysílací anténa: %d\n" +IDS_MSG_TRANSMIT_ANTENNA_ANY, "Vysílací anténa: jakákoliv\n" +IDS_MSG_RECEIVE_ANTENNA, "PÅ™ijímací anténa: %d\n" +IDS_MSG_RECEIVE_ANTENNA_ANY, "PÅ™ijímací anténa: jakákoliv\n" +IDS_MSG_FRAGMENT_THRESHOLD, "Hranice fragmentace: %d bajtů\n" +IDS_MSG_RTS_THRESHOLD, "Hranice RTS: %d bajtů\n" +/* === */ +IDS_YES, "Ano" +IDS_NO, "Ne" +IDS_ADHOC, "Ad hoc" +IDS_INFRASTRUCTURE, "Infrastruktura" +END diff --git a/reactos/base/applications/network/wlanconf/wlanconf.rc b/reactos/base/applications/network/wlanconf/wlanconf.rc index 63f0bd519c6..bc310bf4354 100644 --- a/reactos/base/applications/network/wlanconf/wlanconf.rc +++ b/reactos/base/applications/network/wlanconf/wlanconf.rc @@ -19,6 +19,9 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #ifdef LANGUAGE_EN_US #include "lang/en-US.rc" #endif +#ifdef LANGUAGE_CS_CZ + #include "lang/cs-CZ.rc" +#endif #ifdef LANGUAGE_IT_IT #include "lang/it-IT.rc" #endif diff --git a/reactos/base/applications/regedit/lang/cs-CZ.rc b/reactos/base/applications/regedit/lang/cs-CZ.rc index ffece4dde81..f271fa426e2 100644 --- a/reactos/base/applications/regedit/lang/cs-CZ.rc +++ b/reactos/base/applications/regedit/lang/cs-CZ.rc @@ -376,7 +376,7 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_BINARY_EMPTY "(binární položka nulové hodnoty)" + IDS_BINARY_EMPTY "(binární položka nulové hodnoty)" IDS_DEFAULT_VALUE_NAME "(Výchozí)" IDS_VALUE_NOT_SET "(Hodnota nezadána)" IDS_UNKNOWN_TYPE "Neznámý typ: (0x%lx)" @@ -434,10 +434,10 @@ END STRINGTABLE DISCARDABLE BEGIN - IDS_IMPORT_PROMPT "Adding information can unintentionally change or delete values and cause components to stop working correctly.\nIf you do not trust the source of this information in '%s', do not add it to registry.\n\nAre you sure you want to continue?" - IDS_IMPORT_OK "The keys and values contained in '%s' have been successfully added to the registry." - IDS_IMPORT_ERROR "Cannot import '%s': Error opening the file. There may be a disk, file system error or file may not exist." - IDS_EXPORT_ERROR "Cannot export '%s': Error creating or writing to the file. There may be a disk or file system error." + IDS_IMPORT_PROMPT "PÅ™idáváním informací můžete neúmyslnÄ› zmÄ›nit nebo odstranit hodnoty a způsobit, že komponenty pÅ™estanou správnÄ› fungovat\nPokud nevěříte zdroji tÄ›chto informací v '%s', nepÅ™idávejte je do registru.\n\nOpravdu chcete pokraÄovat?" + IDS_IMPORT_OK "KlíÄe a hodnoty z '%s' byly úspěšnÄ› pÅ™idány do registru." + IDS_IMPORT_ERROR "Nelze importovat '%s': Chyba pÅ™i otevírání souboru. DoÅ¡lo k chybÄ› disku nebo souborového systému, nebo soubor neexistuje." + IDS_EXPORT_ERROR "Nelze exportovat '%s': Chyba pÅ™i vytváření Äi psaní do souboru. DoÅ¡lo k chybÄ› disku nebo souborového systému." END STRINGTABLE DISCARDABLE diff --git a/reactos/dll/cpl/desk/lang/cs-CZ.rc b/reactos/dll/cpl/desk/lang/cs-CZ.rc index 0b000619f03..0559ceb8a23 100644 --- a/reactos/dll/cpl/desk/lang/cs-CZ.rc +++ b/reactos/dll/cpl/desk/lang/cs-CZ.rc @@ -61,7 +61,7 @@ BEGIN COMBOBOX IDC_APPEARANCE_VISUAL_STYLE, 7, 140, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP LTEXT "Schéma", IDC_STATIC, 7, 160, 64, 7 COMBOBOX IDC_APPEARANCE_COLORSCHEME, 7, 170, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Size", IDC_STATIC, 7, 190, 64, 7 + LTEXT "Velikost", IDC_STATIC, 7, 190, 64, 7 COMBOBOX IDC_APPEARANCE_SIZE, 7, 200, 134, 90, CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_SORT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "&Efekty...", IDC_APPEARANCE_EFFECTS, 182, 150, 56, 15 PUSHBUTTON "UpÅ™esnit", IDC_APPEARANCE_ADVANCED, 182, 170, 56, 15 @@ -239,7 +239,7 @@ BEGIN IDS_MESSBOX "Okno zprávy" IDS_MESSTEXT "Text zprávy" IDS_BUTTEXT "OK" - IDS_CLASSIC_THEME "Classic Theme" + IDS_CLASSIC_THEME "Klasické téma" END STRINGTABLE DISCARDABLE diff --git a/reactos/dll/win32/msgina/lang/cs-CZ.rc b/reactos/dll/win32/msgina/lang/cs-CZ.rc index 022643ace94..93d9f938352 100644 --- a/reactos/dll/win32/msgina/lang/cs-CZ.rc +++ b/reactos/dll/win32/msgina/lang/cs-CZ.rc @@ -1,7 +1,6 @@ -/* - * FILE: dll/win32/msgina/lang/cs-CZ.rc +/* FILE: dll/win32/msgina/lang/cs-CZ.rc * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com) - * UPDATED: 2008-06-24 + * UPDATED: 2013-02-17 */ LANGUAGE LANG_CZECH, SUBLANG_DEFAULT @@ -45,9 +44,9 @@ CAPTION "BezpeÄnost" FONT 8,"MS Shell Dlg",400,0,1 BEGIN CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 - GROUPBOX "Logon Information",IDC_STATIC,7,61,261,52 - LTEXT "",IDC_LOGONMSG,15,73,245,18 - LTEXT "",IDC_LOGONDATE,15,94,245,8 + GROUPBOX "PÅ™ihlaÅ¡ovací údaje",IDC_STATIC,7,61,261,52 + LTEXT "",IDC_LOGONMSG,15,73,245,18 + LTEXT "",IDC_LOGONDATE,15,94,245,8 CTEXT "Co chcete udÄ›lat?",IDC_STATIC,10,119,255,8 PUSHBUTTON "Uzamknout poÄítaÄ",IDC_LOCK,10,135,70,14 PUSHBUTTON "Odhlásit",IDC_LOGOFF,90,135,70,14 @@ -58,31 +57,31 @@ END IDD_LOCKED_DLG DIALOGEX 0,0,275,121 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP -CAPTION "Computer Locked" +CAPTION "PoÄítaÄ je uzamÄen" FONT 8,"MS Shell Dlg",400,0,1 BEGIN CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 ICON IDI_LOCKICON,-1,7,59,20,20 - LTEXT "This computer is in use and has been locked.",IDC_STATIC,37,61,231,8 - LTEXT "Message",IDC_LOCKMSG,37,75,231,26 - LTEXT "Press Ctrl-Alt-Del to unlock this computer.",IDC_STATIC,37,106,231,8 + LTEXT "Tento poÄítaÄ je momentálnÄ› používán a byl uzamÄen.",IDC_STATIC,37,61,231,8 + LTEXT "Zpráva",IDC_LOCKMSG,37,75,231,26 + LTEXT "Stisknutím kláves Ctrl-Alt-Del odemknete poÄítaÄ.",IDC_STATIC,37,106,231,8 END IDD_UNLOCK_DLG DIALOGEX 0,0,275,179 STYLE NOT WS_VISIBLE | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP -CAPTION "Unlock Computer" +CAPTION "Odemknout poÄítaÄ" FONT 8,"MS Shell Dlg",400,0,1 BEGIN CONTROL IDI_ROSLOGO,IDC_ROSLOGO,"Static",SS_BITMAP,0,0,275,54 ICON IDI_LOCKICON,-1,7,59,20,20 - LTEXT "This computer is in use and has been locked.",IDC_STATIC,36,61,232,8 - LTEXT "Message",IDC_LOCKMSG,36,75,232,26 - LTEXT "Username:",IDC_STATIC,36,107,40,8 + LTEXT "Tento poÄítaÄ je momentálnÄ› používán a byl uzamÄen.",IDC_STATIC,36,61,232,8 + LTEXT "Zpráva",IDC_LOCKMSG,36,75,232,26 + LTEXT "Uživatelské jméno:",IDC_STATIC,36,107,40,8 EDITTEXT IDC_USERNAME,84,104,119,14,ES_AUTOHSCROLL - LTEXT "Password:",IDC_STATIC,36,125,42,8 + LTEXT "Heslo:",IDC_STATIC,36,125,42,8 EDITTEXT IDC_PASSWORD,84,123,119,14,ES_AUTOHSCROLL | ES_PASSWORD PUSHBUTTON "OK",IDOK,80,154,50,14,BS_DEFPUSHBUTTON - PUSHBUTTON "Cancel",IDCANCEL,144,154,50,14 + PUSHBUTTON "Storno",IDCANCEL,144,154,50,14 END STRINGTABLE @@ -93,6 +92,7 @@ BEGIN IDS_ASKFORUSER "Uživatelské jméno: " IDS_ASKFORPASSWORD "Heslo: " IDS_FORCELOGOFF "SouÄasný uživatel bude odhlášen a vÅ¡echna jeho neuložená data ztracena. PokraÄovat?" - IDS_LOCKMSG "Only %s or an Administrator can unlock this computer." - IDS_LOGONDATE "Logon date: %s %s" + IDS_LOCKMSG "Pouze %s nebo Administrátor může odemknout tento poÄítaÄ." + IDS_LOGONMSG "Jste pÅ™ihlášeni jako %s." + IDS_LOGONDATE "Datum pÅ™ihlášení: %s %s" END From 2e660923f1a660646c1daa09f220a5de8a6137f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 May 2013 14:27:09 +0000 Subject: [PATCH 31/67] [CSRSRV] - Code simplification. - Remove unneeded casts. - Fix comments. svn path=/trunk/; revision=58922 --- reactos/subsystems/win32/csrsrv/api.c | 8 ++++---- reactos/subsystems/win32/csrsrv/thredsup.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/reactos/subsystems/win32/csrsrv/api.c b/reactos/subsystems/win32/csrsrv/api.c index 5bb6b7645c2..9bea5027753 100644 --- a/reactos/subsystems/win32/csrsrv/api.c +++ b/reactos/subsystems/win32/csrsrv/api.c @@ -63,7 +63,7 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, { /* We are beyond the Maximum Server ID */ DPRINT1("CSRSS: %lx is invalid ServerDllIndex (%08x)\n", ServerId, ServerDll); - ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION; + ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION; return STATUS_ILLEGAL_FUNCTION; } else @@ -82,7 +82,7 @@ CsrCallServerFromServer(IN PCSR_API_MESSAGE ReceiveMsg, ((ServerDll->NameTable) && (ServerDll->NameTable[ApiId])) ? ServerDll->NameTable[ApiId] : "*** UNKNOWN ***", &ServerDll->Name); // DbgBreakPoint(); - ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION; + ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION; return STATUS_ILLEGAL_FUNCTION; } } @@ -155,7 +155,7 @@ CsrApiHandleConnectionRequest(IN PCSR_API_MESSAGE ApiMessage) if (CsrProcess) { /* Reference the Process */ - CsrLockedReferenceProcess(CsrThread->Process); + CsrLockedReferenceProcess(CsrProcess); /* Release the lock */ CsrReleaseProcessLock(); @@ -432,7 +432,7 @@ CsrApiRequestThread(IN PVOID Parameter) } else { - /* A bizare "success" code, just try again */ + /* A strange "success" code, just try again */ DPRINT1("NtReplyWaitReceivePort returned \"success\" status 0x%x\n", Status); continue; } diff --git a/reactos/subsystems/win32/csrsrv/thredsup.c b/reactos/subsystems/win32/csrsrv/thredsup.c index 168218558e9..2ed743a9c3f 100644 --- a/reactos/subsystems/win32/csrsrv/thredsup.c +++ b/reactos/subsystems/win32/csrsrv/thredsup.c @@ -958,10 +958,10 @@ CsrLockThreadByClientId(IN HANDLE Tid, /* Start Loop */ while (NextEntry != &CsrThreadHashTable[i]) { - /* Get the Process */ + /* Get the Thread */ CurrentThread = CONTAINING_RECORD(NextEntry, CSR_THREAD, HashLinks); - /* Check for PID Match */ + /* Check for TID Match */ if ((CurrentThread->ClientId.UniqueThread == Tid) && (CurrentThread->Flags & CsrThreadTerminated) == 0) { From be14e6b7ceb79fa858064b0d7ce87d63f56622c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 May 2013 14:29:51 +0000 Subject: [PATCH 32/67] Code formatting only svn path=/trunk/; revision=58923 --- reactos/subsystems/win/basesrv/dosdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/subsystems/win/basesrv/dosdev.c b/reactos/subsystems/win/basesrv/dosdev.c index 9444ad92274..148c2ea4f87 100644 --- a/reactos/subsystems/win/basesrv/dosdev.c +++ b/reactos/subsystems/win/basesrv/dosdev.c @@ -137,9 +137,9 @@ CSR_API(BaseSrvDefineDosDevice) _SEH2_LEAVE; RequestLinkTarget = &DefineDosDeviceRequest->TargetName; - lpBuffer = (PWSTR) RtlAllocateHeap(BaseSrvHeap, - HEAP_ZERO_MEMORY, - RequestDeviceName.MaximumLength + 5 * sizeof(WCHAR)); + lpBuffer = (PWSTR)RtlAllocateHeap(BaseSrvHeap, + HEAP_ZERO_MEMORY, + RequestDeviceName.MaximumLength + 5 * sizeof(WCHAR)); if (!lpBuffer) { DPRINT1("Failed to allocate memory\n"); From 3b0611bcc9ef9d4422778b4ab7f7daf494f9807b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Sat, 4 May 2013 15:26:48 +0000 Subject: [PATCH 33/67] [NTDLL_APITEST] * Add tests for NtProtectVirtualMemory svn path=/trunk/; revision=58924 --- rostests/apitests/ntdll/CMakeLists.txt | 1 + .../apitests/ntdll/NtProtectVirtualMemory.c | 102 ++++++++++++++++++ rostests/apitests/ntdll/testlist.c | 2 + 3 files changed, 105 insertions(+) create mode 100644 rostests/apitests/ntdll/NtProtectVirtualMemory.c diff --git a/rostests/apitests/ntdll/CMakeLists.txt b/rostests/apitests/ntdll/CMakeLists.txt index dd78b59121a..7e51573c5c6 100644 --- a/rostests/apitests/ntdll/CMakeLists.txt +++ b/rostests/apitests/ntdll/CMakeLists.txt @@ -4,6 +4,7 @@ list(APPEND SOURCE NtAllocateVirtualMemory.c NtFreeVirtualMemory.c NtMapViewOfSection.c + NtProtectVirtualMemory.c NtQuerySystemEnvironmentValue.c RtlBitmap.c RtlDetermineDosPathNameType.c diff --git a/rostests/apitests/ntdll/NtProtectVirtualMemory.c b/rostests/apitests/ntdll/NtProtectVirtualMemory.c new file mode 100644 index 00000000000..b32c66c101d --- /dev/null +++ b/rostests/apitests/ntdll/NtProtectVirtualMemory.c @@ -0,0 +1,102 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for the NtProtectVirtualMemory API + */ + +#define WIN32_NO_STATUS +#include +#include +#include +#include + +#define StartSeh status = STATUS_SUCCESS; _SEH2_TRY +#define EndSeh(ExpectedStatus) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { status = _SEH2_GetExceptionCode(); } _SEH2_END; ok(status == ExpectedStatus, "Exception %lx, expected %lx\n", status, ExpectedStatus) + +START_TEST(NtProtectVirtualMemory) +{ + ULONG* allocationStart = NULL; + NTSTATUS status; + SIZE_T allocationSize; + ULONG oldProtection; + + /* Reserve a page */ + allocationSize = PAGE_SIZE; + status = NtAllocateVirtualMemory(NtCurrentProcess(), + (void**)&allocationStart, + 0, + &allocationSize, + MEM_RESERVE, + PAGE_NOACCESS); + ok(NT_SUCCESS(status), "Reserving memory failed\n"); + + /* Commit the page (RW) */ + status = NtAllocateVirtualMemory(NtCurrentProcess(), + (void**)&allocationStart, + 0, + &allocationSize, + MEM_COMMIT, + PAGE_READWRITE); + ok(NT_SUCCESS(status), "Commiting memory failed\n"); + + /* Try writing it */ + StartSeh + { + *allocationStart = 0xFF; + } EndSeh(STATUS_SUCCESS); + + /* Try reading it */ + StartSeh + { + ok(*allocationStart == 0xFF, "Memory was not written\n"); + } EndSeh(STATUS_SUCCESS); + + /* Set it as read only */ + status = NtProtectVirtualMemory(NtCurrentProcess(), + (void**)&allocationStart, + &allocationSize, + PAGE_READONLY, + &oldProtection); + ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n"); + ok(oldProtection == PAGE_READWRITE, "Expected PAGE_READWRITE, got %08x.\n", oldProtection); + + /* Try writing it */ + StartSeh + { + *allocationStart = 0xAA; + } EndSeh(STATUS_ACCESS_VIOLATION); + + /* Try reading it */ + StartSeh + { + ok(*allocationStart == 0xFF, "read-only memory were changed.\n"); + } EndSeh(STATUS_SUCCESS); + + /* Set it as no access */ + status = NtProtectVirtualMemory(NtCurrentProcess(), + (void**)&allocationStart, + &allocationSize, + PAGE_NOACCESS, + &oldProtection); + ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n"); + ok(oldProtection == PAGE_READONLY, "Expected PAGE_READONLY, got %08x.\n", oldProtection); + + /* Try writing it */ + StartSeh + { + *allocationStart = 0xAA; + } EndSeh(STATUS_ACCESS_VIOLATION); + + /* Try reading it */ + StartSeh + { + ok(*allocationStart == 0, "Test should not go as far as this.\n"); + } EndSeh(STATUS_ACCESS_VIOLATION); + + /* Free memory */ + status = NtFreeVirtualMemory(NtCurrentProcess(), + (void**)&allocationStart, + &allocationSize, + MEM_RELEASE); + ok(NT_SUCCESS(status), "Failed freeing memory.\n"); +} \ No newline at end of file diff --git a/rostests/apitests/ntdll/testlist.c b/rostests/apitests/ntdll/testlist.c index b8a6c9e8e45..56e15ab1b23 100644 --- a/rostests/apitests/ntdll/testlist.c +++ b/rostests/apitests/ntdll/testlist.c @@ -7,6 +7,7 @@ extern void func_LdrEnumResources(void); extern void func_NtAllocateVirtualMemory(void); extern void func_NtFreeVirtualMemory(void); extern void func_NtMapViewOfSection(void); +extern void func_NtProtectVirtualMemory(void); extern void func_NtQuerySystemEnvironmentValue(void); extern void func_NtSystemInformation(void); extern void func_RtlBitmap(void); @@ -28,6 +29,7 @@ const struct test winetest_testlist[] = { "NtAllocateVirtualMemory", func_NtAllocateVirtualMemory }, { "NtFreeVirtualMemory", func_NtFreeVirtualMemory }, { "NtMapViewOfSection", func_NtMapViewOfSection }, + { "NtProtectVirtualMemory", func_NtProtectVirtualMemory }, { "NtQuerySystemEnvironmentValue", func_NtQuerySystemEnvironmentValue }, { "NtSystemInformation", func_NtSystemInformation }, { "RtlBitmapApi", func_RtlBitmap }, From 9c6d52c545e5894f28f62ac2feb0831596dc54c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 May 2013 15:31:19 +0000 Subject: [PATCH 34/67] [CONSRV] Be sure to use our local heap instead of the current application heap, to store the console title. To simplify the code, I introduced helper functions based on well-known Rtl functions. svn path=/trunk/; revision=58925 --- reactos/win32ss/user/consrv/console.c | 49 +++++++++++++++++++++------ 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/reactos/win32ss/user/consrv/console.c b/reactos/win32ss/user/consrv/console.c index 4a5c2528b09..263cd64e24b 100644 --- a/reactos/win32ss/user/consrv/console.c +++ b/reactos/win32ss/user/consrv/console.c @@ -51,6 +51,35 @@ static RTL_RESOURCE ListLock; #define ConSrvUnlockConsoleList() \ RtlReleaseResource(&ListLock) +// Adapted from reactos/lib/rtl/unicode.c, RtlCreateUnicodeString line 2180 +BOOLEAN +ConsoleCreateUnicodeString(IN OUT PUNICODE_STRING UniDest, + IN PCWSTR Source) +{ + SIZE_T Size = (wcslen(Source) + 1) * sizeof(WCHAR); + if (Size > MAXUSHORT) return FALSE; + + UniDest->Buffer = RtlAllocateHeap(ConSrvHeap, HEAP_ZERO_MEMORY, Size); + if (UniDest->Buffer == NULL) return FALSE; + + RtlCopyMemory(UniDest->Buffer, Source, Size); + UniDest->MaximumLength = (USHORT)Size; + UniDest->Length = (USHORT)Size - sizeof(WCHAR); + + return TRUE; +} + +// Adapted from reactos/lib/rtl/unicode.c, RtlFreeUnicodeString line 431 +VOID +ConsoleFreeUnicodeString(IN PUNICODE_STRING UnicodeString) +{ + if (UnicodeString->Buffer) + { + RtlFreeHeap(ConSrvHeap, 0, UnicodeString->Buffer); + RtlZeroMemory(UnicodeString, sizeof(UNICODE_STRING)); + } +} + /* PRIVATE FUNCTIONS **********************************************************/ @@ -612,21 +641,21 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, Console->HistoryNoDup = ConsoleInfo.HistoryNoDup; /* Initialize the console title */ - RtlCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo.ConsoleTitle); + ConsoleCreateUnicodeString(&Console->OriginalTitle, ConsoleInfo.ConsoleTitle); if (ConsoleInfo.ConsoleTitle[0] == L'\0') { if (LoadStringW(ConSrvDllInstance, IDS_CONSOLE_TITLE, Title, sizeof(Title) / sizeof(Title[0]))) { - RtlCreateUnicodeString(&Console->Title, Title); + ConsoleCreateUnicodeString(&Console->Title, Title); } else { - RtlCreateUnicodeString(&Console->Title, L"ReactOS Console"); + ConsoleCreateUnicodeString(&Console->Title, L"ReactOS Console"); } } else { - RtlCreateUnicodeString(&Console->Title, ConsoleInfo.ConsoleTitle); + ConsoleCreateUnicodeString(&Console->Title, ConsoleInfo.ConsoleTitle); } /* Lock the console until its initialization is finished */ @@ -674,8 +703,8 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, if (!NT_SUCCESS(Status)) { DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status); - RtlFreeUnicodeString(&Console->Title); - RtlFreeUnicodeString(&Console->OriginalTitle); + ConsoleFreeUnicodeString(&Console->OriginalTitle); + ConsoleFreeUnicodeString(&Console->Title); ConioDeleteScreenBuffer(NewBuffer); CloseHandle(Console->InputBuffer.ActiveEvent); // LeaveCriticalSection(&Console->Lock); @@ -812,8 +841,8 @@ ConSrvDeleteConsole(PCONSOLE Console) // CloseHandle(Console->InputBuffer.ActiveEvent); if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent); - RtlFreeUnicodeString(&Console->OriginalTitle); - RtlFreeUnicodeString(&Console->Title); + ConsoleFreeUnicodeString(&Console->OriginalTitle); + ConsoleFreeUnicodeString(&Console->Title); DPRINT("ConSrvDeleteConsole - Unlocking\n"); LeaveCriticalSection(&Console->Lock); @@ -1183,11 +1212,11 @@ CSR_API(SrvSetConsoleTitle) } /* Allocate a new buffer to hold the new title (NULL-terminated) */ - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, TitleRequest->Length + sizeof(WCHAR)); + Buffer = RtlAllocateHeap(ConSrvHeap, 0, TitleRequest->Length + sizeof(WCHAR)); if (Buffer) { /* Free the old title */ - RtlFreeUnicodeString(&Console->Title); + ConsoleFreeUnicodeString(&Console->Title); /* Copy title to console */ Console->Title.Buffer = Buffer; From 554df0ecbf49e911bfeb3e42c67f93716c3d619e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 May 2013 19:28:36 +0000 Subject: [PATCH 35/67] [CONSRV] Hack: To try to uncover a heap corruption in CONSRV, use our own heap instead of the (default) CSR heap, so that we won't corrupt it and obtain strange bugs thrown by memory allocation in csrsrv. Thanks to Aleksandar Andrejevic, aka. [TheFlash] for having seen that. See CORE-7157 for more information. svn path=/trunk/; revision=58926 --- reactos/win32ss/user/consrv/init.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/reactos/win32ss/user/consrv/init.c b/reactos/win32ss/user/consrv/init.c index 6aa0067fe64..640f76f67a0 100644 --- a/reactos/win32ss/user/consrv/init.c +++ b/reactos/win32ss/user/consrv/init.c @@ -481,7 +481,11 @@ ConSrvDisconnect(PCSR_PROCESS Process) CSR_SERVER_DLL_INIT(ConServerDllInitialization) { /* Initialize the memory */ - ConSrvHeap = RtlGetProcessHeap(); + // HACK: To try to uncover a heap corruption in CONSRV, use our own heap + // instead of the CSR heap, so that we won't corrupt it. + // ConSrvHeap = RtlGetProcessHeap(); + ConSrvHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL); + if (!ConSrvHeap) return STATUS_NO_MEMORY; ConSrvInitConsoleSupport(); From 5ffb258f8a7eeed6145ed82b8a859a3c0518df74 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 4 May 2013 20:21:39 +0000 Subject: [PATCH 36/67] [FUSION] * Sync with Wine 1.5.26. svn path=/trunk/; revision=58927 --- reactos/dll/win32/fusion/CMakeLists.txt | 3 +- reactos/dll/win32/fusion/asmcache.c | 152 +++++++++++++++++++----- reactos/dll/win32/fusion/asmenum.c | 137 ++++++++++++++------- reactos/dll/win32/fusion/asmname.c | 97 +++++++++++---- reactos/dll/win32/fusion/assembly.c | 125 ++++++++++++------- reactos/dll/win32/fusion/fusion.c | 67 ++++++----- reactos/dll/win32/fusion/fusion.spec | 2 +- reactos/dll/win32/fusion/fusion_main.c | 51 -------- reactos/dll/win32/fusion/fusionpriv.h | 4 +- reactos/include/psdk/corerror.h | 1 + reactos/include/psdk/fusion.idl | 4 +- reactos/media/doc/README.WINE | 2 +- 12 files changed, 417 insertions(+), 228 deletions(-) delete mode 100644 reactos/dll/win32/fusion/fusion_main.c diff --git a/reactos/dll/win32/fusion/CMakeLists.txt b/reactos/dll/win32/fusion/CMakeLists.txt index 82f671844ba..7e19b1e14e1 100644 --- a/reactos/dll/win32/fusion/CMakeLists.txt +++ b/reactos/dll/win32/fusion/CMakeLists.txt @@ -10,7 +10,6 @@ list(APPEND SOURCE asmname.c assembly.c fusion.c - fusion_main.c version.rc ${CMAKE_CURRENT_BINARY_DIR}/fusion_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/fusion.def) @@ -18,7 +17,7 @@ list(APPEND SOURCE add_library(fusion SHARED ${SOURCE}) set_module_type(fusion win32dll) target_link_libraries(fusion wine uuid) -add_importlibs(fusion shlwapi advapi32 dbghelp user32 msvcrt kernel32 ntdll) +add_importlibs(fusion advapi32 dbghelp shlwapi user32 msvcrt kernel32 ntdll) add_cd_file(TARGET fusion DESTINATION reactos/Microsoft.NET/Framework/v1.0.3705 FOR all) add_cd_file(TARGET fusion DESTINATION reactos/Microsoft.NET/Framework/v1.1.4322 FOR all) add_cd_file(TARGET fusion DESTINATION reactos/Microsoft.NET/Framework/v2.0.50727 FOR all) diff --git a/reactos/dll/win32/fusion/asmcache.c b/reactos/dll/win32/fusion/asmcache.c index df89800dc41..2b02390f497 100644 --- a/reactos/dll/win32/fusion/asmcache.c +++ b/reactos/dll/win32/fusion/asmcache.c @@ -98,32 +98,48 @@ static BOOL create_full_path(LPCWSTR path) return ret; } -static BOOL get_assembly_directory(LPWSTR dir, DWORD size, BYTE architecture) +static BOOL get_assembly_directory(LPWSTR dir, DWORD size, const char *version, PEKIND architecture) { + static const WCHAR dotnet[] = {'\\','M','i','c','r','o','s','o','f','t','.','N','E','T','\\',0}; static const WCHAR gac[] = {'\\','a','s','s','e','m','b','l','y','\\','G','A','C',0}; - static const WCHAR msil[] = {'_','M','S','I','L',0}; static const WCHAR x86[] = {'_','3','2',0}; static const WCHAR amd64[] = {'_','6','4',0}; + DWORD len = GetWindowsDirectoryW(dir, size); - GetWindowsDirectoryW(dir, size); - strcatW(dir, gac); - + if (!strcmp(version, "v4.0.30319")) + { + strcpyW(dir + len, dotnet); + len += sizeof(dotnet)/sizeof(WCHAR) -1; + strcpyW(dir + len, gac + 1); + len += sizeof(gac)/sizeof(WCHAR) - 2; + } + else + { + strcpyW(dir + len, gac); + len += sizeof(gac)/sizeof(WCHAR) - 1; + } switch (architecture) { + case peNone: + break; + case peMSIL: - strcatW(dir, msil); + strcpyW(dir + len, msil); break; case peI386: - strcatW(dir, x86); + strcpyW(dir + len, x86); break; case peAMD64: - strcatW(dir, amd64); + strcpyW(dir + len, amd64); break; - } + default: + WARN("unhandled architecture %u\n", architecture); + return FALSE; + } return TRUE; } @@ -153,7 +169,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryInterface(IAssemblyCache *iface, if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IAssemblyCache)) { - IUnknown_AddRef(iface); + IAssemblyCache_AddRef(iface); *ppobj = This; return S_OK; } @@ -312,11 +328,16 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface if (FAILED(hr)) goto done; - hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0); - if (hr == S_FALSE) + for (;;) { - hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); - goto done; + hr = IAssemblyEnum_GetNextAssembly(asmenum, NULL, &next, 0); + if (hr != S_OK) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + goto done; + } + hr = IAssemblyName_IsEqual(asmname, next, ASM_CMPF_IL_ALL); + if (hr == S_OK) break; } if (!pAsmInfo) @@ -353,24 +374,51 @@ static HRESULT WINAPI IAssemblyCacheImpl_CreateAssemblyScavenger(IAssemblyCache return E_NOTIMPL; } +static HRESULT copy_file( const WCHAR *src_dir, DWORD src_len, const WCHAR *dst_dir, DWORD dst_len, + const WCHAR *filename ) +{ + WCHAR *src_file, *dst_file; + DWORD len = strlenW( filename ); + HRESULT hr = S_OK; + + if (!(src_file = HeapAlloc( GetProcessHeap(), 0, (src_len + len + 1) * sizeof(WCHAR) ))) + return E_OUTOFMEMORY; + memcpy( src_file, src_dir, src_len * sizeof(WCHAR) ); + strcpyW( src_file + src_len, filename ); + + if (!(dst_file = HeapAlloc( GetProcessHeap(), 0, (dst_len + len + 1) * sizeof(WCHAR) ))) + { + HeapFree( GetProcessHeap(), 0, src_file ); + return E_OUTOFMEMORY; + } + memcpy( dst_file, dst_dir, dst_len * sizeof(WCHAR) ); + strcpyW( dst_file + dst_len, filename ); + + if (!CopyFileW( src_file, dst_file, FALSE )) hr = HRESULT_FROM_WIN32( GetLastError() ); + HeapFree( GetProcessHeap(), 0, src_file ); + HeapFree( GetProcessHeap(), 0, dst_file ); + return hr; +} + static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, DWORD dwFlags, LPCWSTR pszManifestFilePath, LPCFUSION_INSTALL_REFERENCE pRefData) { - static const WCHAR format[] = {'%','s','\\','%','s','\\','%','s','_','_','%','s','\\',0}; + static const WCHAR format[] = + {'%','s','\\','%','s','\\','%','s','_','_','%','s','\\',0}; + static const WCHAR format_v40[] = + {'%','s','\\','%','s','\\','v','4','.','0','_','%','s','_','_','%','s','\\',0}; static const WCHAR ext_exe[] = {'.','e','x','e',0}; static const WCHAR ext_dll[] = {'.','d','l','l',0}; IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface); ASSEMBLY *assembly; - LPWSTR filename; - LPWSTR name = NULL; - LPWSTR token = NULL; - LPWSTR version = NULL; - LPWSTR asmpath = NULL; - WCHAR path[MAX_PATH]; - WCHAR asmdir[MAX_PATH]; - LPWSTR ext; + const WCHAR *extension, *filename, *src_dir; + WCHAR *name = NULL, *token = NULL, *version = NULL, *asmpath = NULL; + WCHAR asmdir[MAX_PATH], *p, **external_files = NULL, *dst_dir = NULL; + PEKIND architecture; + char *clr_version; + DWORD i, count = 0, src_len, dst_len = sizeof(format_v40)/sizeof(format_v40[0]); HRESULT hr; TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, @@ -379,10 +427,10 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, if (!pszManifestFilePath || !*pszManifestFilePath) return E_INVALIDARG; - if (!(ext = strrchrW(pszManifestFilePath, '.'))) + if (!(extension = strrchrW(pszManifestFilePath, '.'))) return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); - if (lstrcmpiW(ext, ext_exe) && lstrcmpiW(ext, ext_dll)) + if (lstrcmpiW(extension, ext_exe) && lstrcmpiW(extension, ext_dll)) return HRESULT_FROM_WIN32(ERROR_INVALID_NAME); if (GetFileAttributesW(pszManifestFilePath) == INVALID_FILE_ATTRIBUTES) @@ -407,29 +455,67 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, if (FAILED(hr)) goto done; + hr = assembly_get_runtime_version(assembly, &clr_version); + if (FAILED(hr)) + goto done; + + hr = assembly_get_external_files(assembly, &external_files, &count); + if (FAILED(hr)) + goto done; + cache_lock( cache ); - get_assembly_directory(asmdir, MAX_PATH, assembly_get_architecture(assembly)); + architecture = assembly_get_architecture(assembly); + get_assembly_directory(asmdir, MAX_PATH, clr_version, architecture); - sprintfW(path, format, asmdir, name, version, token); + dst_len += strlenW(asmdir) + strlenW(name) + strlenW(version) + strlenW(token); + if (!(dst_dir = HeapAlloc(GetProcessHeap(), 0, dst_len * sizeof(WCHAR)))) + { + hr = E_OUTOFMEMORY; + goto done; + } + if (!strcmp(clr_version, "v4.0.30319")) + dst_len = sprintfW(dst_dir, format_v40, asmdir, name, version, token); + else + dst_len = sprintfW(dst_dir, format, asmdir, name, version, token); - create_full_path(path); + create_full_path(dst_dir); hr = assembly_get_path(assembly, &asmpath); if (FAILED(hr)) goto done; - filename = PathFindFileNameW(asmpath); + if ((p = strrchrW(asmpath, '\\'))) + { + filename = p + 1; + src_dir = asmpath; + src_len = filename - asmpath; + } + else + { + filename = asmpath; + src_dir = NULL; + src_len = 0; + } + hr = copy_file(src_dir, src_len, dst_dir, dst_len, filename); + if (FAILED(hr)) + goto done; - strcatW(path, filename); - if (!CopyFileW(asmpath, path, FALSE)) - hr = HRESULT_FROM_WIN32(GetLastError()); + for (i = 0; i < count; i++) + { + hr = copy_file(src_dir, src_len, dst_dir, dst_len, external_files[i]); + if (FAILED(hr)) + break; + } done: HeapFree(GetProcessHeap(), 0, name); HeapFree(GetProcessHeap(), 0, token); HeapFree(GetProcessHeap(), 0, version); HeapFree(GetProcessHeap(), 0, asmpath); + HeapFree(GetProcessHeap(), 0, dst_dir); + for (i = 0; i < count; i++) HeapFree(GetProcessHeap(), 0, external_files[i]); + HeapFree(GetProcessHeap(), 0, external_files); assembly_release(assembly); cache_unlock( cache ); return hr; @@ -501,7 +587,7 @@ static HRESULT WINAPI IAssemblyCacheItemImpl_QueryInterface(IAssemblyCacheItem * if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IAssemblyCacheItem)) { - IUnknown_AddRef(iface); + IAssemblyCacheItem_AddRef(iface); *ppobj = This; return S_OK; } diff --git a/reactos/dll/win32/fusion/asmenum.c b/reactos/dll/win32/fusion/asmenum.c index 89e11057ffd..23ed47b1949 100644 --- a/reactos/dll/win32/fusion/asmenum.c +++ b/reactos/dll/win32/fusion/asmenum.c @@ -25,6 +25,8 @@ #include #define COBJMACROS +#define NONAMELESSUNION +#define NONAMELESSSTRUCT #include #include @@ -73,7 +75,7 @@ static HRESULT WINAPI IAssemblyEnumImpl_QueryInterface(IAssemblyEnum *iface, if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IAssemblyEnum)) { - IUnknown_AddRef(iface); + IAssemblyEnum_AddRef(iface); *ppobj = This; return S_OK; } @@ -168,23 +170,32 @@ static const IAssemblyEnumVtbl AssemblyEnumVtbl = { IAssemblyEnumImpl_Clone }; -static void parse_name(IAssemblyName *name, int depth, LPWSTR path, LPWSTR buf) +static void build_file_mask(IAssemblyName *name, int depth, const WCHAR *path, + const WCHAR *prefix, WCHAR *buf) { - WCHAR disp[MAX_PATH]; + static const WCHAR star[] = {'*',0}; + static const WCHAR ss_fmt[] = {'%','s','\\','%','s',0}; + static const WCHAR sss_fmt[] = {'%','s','\\','%','s','_','_','%','s',0}; + static const WCHAR ssss_fmt[] = {'%','s','\\','%','s','%','s','_','_','%','s',0}; + static const WCHAR ver_fmt[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; + static const WCHAR star_fmt[] = {'%','s','\\','*',0}; + static const WCHAR star_prefix_fmt[] = {'%','s','\\','%','s','*',0}; + WCHAR disp[MAX_PATH], version[24]; /* strlen("65535") * 4 + 3 + 1 */ LPCWSTR verptr, pubkeyptr; HRESULT hr; DWORD size, major_size, minor_size, build_size, revision_size; WORD major, minor, build, revision; - - static const WCHAR star[] = {'*',0}; - static const WCHAR ss_fmt[] = {'%','s','\\','%','s',0}; - static const WCHAR verpubkey[] = {'%','s','\\','%','s','_','_','%','s',0}; - static const WCHAR ver_fmt[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; - - WCHAR version[24]; /* strlen("65535") * 4 + 3 + 1 */ WCHAR token_str[TOKEN_LENGTH + 1]; BYTE token[BYTES_PER_TOKEN]; + if (!name) + { + if (prefix && depth == 1) + sprintfW(buf, star_prefix_fmt, path, prefix); + else + sprintfW(buf, star_fmt, path); + return; + } if (depth == 0) { size = MAX_PATH; @@ -226,7 +237,10 @@ static void parse_name(IAssemblyName *name, int depth, LPWSTR path, LPWSTR buf) pubkeyptr = token_str; } - sprintfW(buf, verpubkey, path, verptr, pubkeyptr); + if (prefix) + sprintfW(buf, ssss_fmt, path, prefix, verptr, pubkeyptr); + else + sprintfW(buf, sss_fmt, path, verptr, pubkeyptr); } } @@ -291,34 +305,24 @@ static void insert_assembly(struct list *assemblies, ASMNAME *to_insert) } static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, - int depth, LPWSTR path) + int depth, const WCHAR *prefix, LPWSTR path) { - WIN32_FIND_DATAW ffd; - WCHAR buf[MAX_PATH]; - WCHAR disp[MAX_PATH]; - WCHAR asmpath[MAX_PATH]; - ASMNAME *asmname; - HANDLE hfind; - LPWSTR ptr; - HRESULT hr = S_OK; - - static WCHAR parent[MAX_PATH]; - static const WCHAR dot[] = {'.',0}; static const WCHAR dotdot[] = {'.','.',0}; - static const WCHAR search_fmt[] = {'%','s','\\','*',0}; static const WCHAR dblunder[] = {'_','_',0}; static const WCHAR path_fmt[] = {'%','s','\\','%','s','\\','%','s','.','d','l','l',0}; - static const WCHAR fmt[] = {'%','s',',',' ','V','e','r','s','i','o','n','=','%','s',',',' ', + static const WCHAR name_fmt[] = {'%','s',',',' ','V','e','r','s','i','o','n','=','%','s',',',' ', 'C','u','l','t','u','r','e','=','n','e','u','t','r','a','l',',',' ', 'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=','%','s',0}; static const WCHAR ss_fmt[] = {'%','s','\\','%','s',0}; + WIN32_FIND_DATAW ffd; + WCHAR buf[MAX_PATH], disp[MAX_PATH], asmpath[MAX_PATH], *ptr; + static WCHAR parent[MAX_PATH]; + ASMNAME *asmname; + HANDLE hfind; + HRESULT hr = S_OK; - if (name) - parse_name(name, depth, path, buf); - else - sprintfW(buf, search_fmt, path); - + build_file_mask(name, depth, path, prefix, buf); hfind = FindFirstFileW(buf, &ffd); if (hfind == INVALID_HANDLE_VALUE) return S_OK; @@ -339,13 +343,21 @@ static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, } else if (depth == 1) { - sprintfW(asmpath, path_fmt, path, ffd.cFileName, parent); + const WCHAR *token, *version = ffd.cFileName; + sprintfW(asmpath, path_fmt, path, ffd.cFileName, parent); ptr = strstrW(ffd.cFileName, dblunder); *ptr = '\0'; - ptr += 2; + token = ptr + 2; - sprintfW(disp, fmt, parent, ffd.cFileName, ptr); + if (prefix) + { + unsigned int prefix_len = strlenW(prefix); + if (strlenW(ffd.cFileName) >= prefix_len && + !memicmpW(ffd.cFileName, prefix, prefix_len)) + version += prefix_len; + } + sprintfW(disp, name_fmt, parent, version, token); asmname = HeapAlloc(GetProcessHeap(), 0, sizeof(ASMNAME)); if (!asmname) @@ -375,7 +387,7 @@ static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, } sprintfW(buf, ss_fmt, path, ffd.cFileName); - hr = enum_gac_assemblies(assemblies, name, depth + 1, buf); + hr = enum_gac_assemblies(assemblies, name, depth + 1, prefix, buf); if (FAILED(hr)) break; } while (FindNextFileW(hfind, &ffd) != 0); @@ -386,32 +398,65 @@ static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name, static HRESULT enumerate_gac(IAssemblyEnumImpl *asmenum, IAssemblyName *pName) { - WCHAR path[MAX_PATH]; - WCHAR buf[MAX_PATH]; + static const WCHAR gac[] = {'\\','G','A','C',0}; + static const WCHAR gac_32[] = {'\\','G','A','C','_','3','2',0}; + static const WCHAR gac_64[] = {'\\','G','A','C','_','6','4',0}; + static const WCHAR gac_msil[] = {'\\','G','A','C','_','M','S','I','L',0}; + static const WCHAR v40[] = {'v','4','.','0','_',0}; + WCHAR path[MAX_PATH], buf[MAX_PATH]; + SYSTEM_INFO info; HRESULT hr; DWORD size; - static WCHAR under32[] = {'_','3','2',0}; - static WCHAR msil[] = {'_','M','S','I','L',0}; + size = MAX_PATH; + hr = GetCachePath(ASM_CACHE_ROOT_EX, buf, &size); + if (FAILED(hr)) + return hr; + + strcpyW(path, buf); + GetNativeSystemInfo(&info); + if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + strcpyW(path + size - 1, gac_64); + hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, v40, path); + if (FAILED(hr)) + return hr; + } + strcpyW(path + size - 1, gac_32); + hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, v40, path); + if (FAILED(hr)) + return hr; + + strcpyW(path + size - 1, gac_msil); + hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, v40, path); + if (FAILED(hr)) + return hr; size = MAX_PATH; - hr = GetCachePath(ASM_CACHE_GAC, buf, &size); + hr = GetCachePath(ASM_CACHE_ROOT, buf, &size); if (FAILED(hr)) return hr; - lstrcpyW(path, buf); - lstrcatW(path, under32); - hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, path); + strcpyW(path, buf); + if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + strcpyW(path + size - 1, gac_64); + hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, NULL, path); + if (FAILED(hr)) + return hr; + } + strcpyW(path + size - 1, gac_32); + hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, NULL, path); if (FAILED(hr)) return hr; - lstrcpyW(path, buf); - lstrcatW(path, msil); - hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, path); + strcpyW(path + size - 1, gac_msil); + hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, NULL, path); if (FAILED(hr)) return hr; - hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, buf); + strcpyW(path + size - 1, gac); + hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, NULL, path); if (FAILED(hr)) return hr; diff --git a/reactos/dll/win32/fusion/asmname.c b/reactos/dll/win32/fusion/asmname.c index f41933ea35a..019d0e5dad3 100644 --- a/reactos/dll/win32/fusion/asmname.c +++ b/reactos/dll/win32/fusion/asmname.c @@ -88,7 +88,7 @@ static HRESULT WINAPI IAssemblyNameImpl_QueryInterface(IAssemblyName *iface, if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IAssemblyName)) { - IUnknown_AddRef(iface); + IAssemblyName_AddRef(iface); *ppobj = This; return S_OK; } @@ -265,7 +265,7 @@ static HRESULT WINAPI IAssemblyNameImpl_GetDisplayName(IAssemblyName *iface, { static const WCHAR spec[] = {'%','d',0}; static const WCHAR period[] = {'.',0}; - int i; + DWORD i; wsprintfW(verstr, spec, name->version[0]); @@ -411,10 +411,37 @@ static HRESULT WINAPI IAssemblyNameImpl_GetVersion(IAssemblyName *iface, static HRESULT WINAPI IAssemblyNameImpl_IsEqual(IAssemblyName *iface, IAssemblyName *pName, - DWORD dwCmpFlags) + DWORD flags) { - FIXME("(%p, %p, %d) stub!\n", iface, pName, dwCmpFlags); - return E_NOTIMPL; + IAssemblyNameImpl *name1 = impl_from_IAssemblyName(iface); + IAssemblyNameImpl *name2 = impl_from_IAssemblyName(pName); + + TRACE("(%p, %p, 0x%08x)\n", iface, pName, flags); + + if (!pName) return S_FALSE; + if (flags & ~ASM_CMPF_IL_ALL) FIXME("unsupported flags\n"); + + if ((flags & ASM_CMPF_NAME) && strcmpW(name1->name, name2->name)) return S_FALSE; + if (name1->versize && name2->versize) + { + if ((flags & ASM_CMPF_MAJOR_VERSION) && + name1->version[0] != name2->version[0]) return S_FALSE; + if ((flags & ASM_CMPF_MINOR_VERSION) && + name1->version[1] != name2->version[1]) return S_FALSE; + if ((flags & ASM_CMPF_BUILD_NUMBER) && + name1->version[2] != name2->version[2]) return S_FALSE; + if ((flags & ASM_CMPF_REVISION_NUMBER) && + name1->version[3] != name2->version[3]) return S_FALSE; + } + if ((flags & ASM_CMPF_PUBLIC_KEY_TOKEN) && + name1->haspubkey && name2->haspubkey && + memcmp(name1->pubkey, name2->pubkey, sizeof(name1->pubkey))) return S_FALSE; + + if ((flags & ASM_CMPF_CULTURE) && + name1->culture && name2->culture && + strcmpW(name1->culture, name2->culture)) return S_FALSE; + + return S_OK; } static HRESULT WINAPI IAssemblyNameImpl_Clone(IAssemblyName *iface, @@ -538,6 +565,10 @@ static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPCWSTR pubkey) { int i; BYTE val; + static const WCHAR nullstr[] = {'n','u','l','l',0}; + + if(lstrcmpiW(pubkey, nullstr) == 0) + return FUSION_E_PRIVATE_ASM_DISALLOWED; if (lstrlenW(pubkey) < CHARS_PER_PUBKEY) return FUSION_E_INVALID_NAME; @@ -557,10 +588,32 @@ static HRESULT parse_pubkey(IAssemblyNameImpl *name, LPCWSTR pubkey) return S_OK; } +static WCHAR *parse_value( const WCHAR *str, unsigned int len ) +{ + WCHAR *ret; + const WCHAR *p = str; + BOOL quoted = FALSE; + unsigned int i = 0; + + if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return NULL; + if (*p == '\"') + { + quoted = TRUE; + p++; + } + while (*p && *p != '\"') ret[i++] = *p++; + if ((quoted && *p != '\"') || (!quoted && *p == '\"')) + { + HeapFree( GetProcessHeap(), 0, ret ); + return NULL; + } + ret[i] = 0; + return ret; +} + static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyName) { - LPWSTR str, save; - LPWSTR ptr, ptr2; + LPWSTR str, save, ptr, ptr2, value; HRESULT hr = S_OK; BOOL done = FALSE; @@ -599,7 +652,7 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam if (!ptr) goto done; - str = ptr + 2; + str = ptr + 1; while (!done) { ptr = strchrW(str, '='); @@ -616,7 +669,7 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam goto done; } - if (!(ptr2 = strstrW(ptr, separator))) + if (!(ptr2 = strchrW(ptr, ','))) { if (!(ptr2 = strchrW(ptr, '\0'))) { @@ -628,21 +681,25 @@ static HRESULT parse_display_name(IAssemblyNameImpl *name, LPCWSTR szAssemblyNam } *ptr2 = '\0'; - + if (!(value = parse_value( ptr, ptr2 - ptr ))) + { + hr = FUSION_E_INVALID_NAME; + goto done; + } while (*str == ' ') str++; - if (!lstrcmpW(str, version)) - hr = parse_version(name, ptr); - else if (!lstrcmpW(str, culture)) - hr = parse_culture(name, ptr); - else if (!lstrcmpW(str, pubkey)) - hr = parse_pubkey(name, ptr); - else if (!lstrcmpW(str, procarch)) + if (!lstrcmpiW(str, version)) + hr = parse_version( name, value ); + else if (!lstrcmpiW(str, culture)) + hr = parse_culture( name, value ); + else if (!lstrcmpiW(str, pubkey)) + hr = parse_pubkey( name, value ); + else if (!lstrcmpiW(str, procarch)) { - name->procarch = strdupW(ptr); - if (!name->procarch) - hr = E_OUTOFMEMORY; + name->procarch = value; + value = NULL; } + HeapFree( GetProcessHeap(), 0, value ); if (FAILED(hr)) goto done; diff --git a/reactos/dll/win32/fusion/assembly.c b/reactos/dll/win32/fusion/assembly.c index c9ec1764815..f429ecc5085 100644 --- a/reactos/dll/win32/fusion/assembly.c +++ b/reactos/dll/win32/fusion/assembly.c @@ -486,8 +486,9 @@ static inline ULONG get_table_size(const ASSEMBLY *assembly, DWORD index) static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset) { - DWORD i, previ, offidx; + DWORD i, count; ULONG currofs; + ULONGLONG mask; currofs = offset; assembly->tableshdr = assembly_data_offset(assembly, currofs); @@ -506,44 +507,22 @@ static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset) if (!assembly->numrows) return E_FAIL; - assembly->numtables = 0; - for (i = 0; i < MAX_CLR_TABLES; i++) - { - if ((i < 32 && (assembly->tableshdr->MaskValid.u.LowPart >> i) & 1) || - (i >= 32 && (assembly->tableshdr->MaskValid.u.HighPart >> i) & 1)) - { - assembly->numtables++; - } - } - - currofs += assembly->numtables * sizeof(DWORD); memset(assembly->tables, -1, MAX_CLR_TABLES * sizeof(CLRTABLE)); - if (assembly->tableshdr->MaskValid.u.LowPart & 1) - assembly->tables[0].offset = currofs; - - offidx = 0; - for (i = 0; i < MAX_CLR_TABLES; i++) + for (i = count = 0, mask = 1; i < MAX_CLR_TABLES; i++, mask <<= 1) { - if ((i < 32 && (assembly->tableshdr->MaskValid.u.LowPart >> i) & 1) || - (i >= 32 && (assembly->tableshdr->MaskValid.u.HighPart >> i) & 1)) - { - assembly->tables[i].rows = assembly->numrows[offidx]; - offidx++; - } + if (assembly->tableshdr->MaskValid.QuadPart & mask) + assembly->tables[i].rows = assembly->numrows[count++]; } + assembly->numtables = count; + currofs += assembly->numtables * sizeof(DWORD); - previ = 0; - offidx = 1; - for (i = 1; i < MAX_CLR_TABLES; i++) + for (i = 0, mask = 1; i < MAX_CLR_TABLES; i++, mask <<= 1) { - if ((i < 32 && (assembly->tableshdr->MaskValid.u.LowPart >> i) & 1) || - (i >= 32 && (assembly->tableshdr->MaskValid.u.HighPart >> i) & 1)) + if (assembly->tableshdr->MaskValid.QuadPart & mask) { - currofs += get_table_size(assembly, previ) * assembly->numrows[offidx - 1]; assembly->tables[i].offset = currofs; - offidx++; - previ = i; + currofs += get_table_size(assembly, i) * assembly->tables[i].rows; } } @@ -571,7 +550,7 @@ static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz) size = FIELD_OFFSET(METADATAHDR, Version); memcpy(assembly->metadatahdr, metadatahdr, size); - /* we don't care about the version string */ + assembly->metadatahdr->Version = (LPSTR)&metadatahdr->Version; ofs = FIELD_OFFSET(METADATAHDR, Flags); ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1; @@ -765,9 +744,9 @@ HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name) ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey) + assembly->blobsz; if (assembly->stringsz == sizeof(DWORD)) - stridx = *((DWORD *)ptr); + stridx = *(DWORD *)ptr; else - stridx = *((WORD *)ptr); + stridx = *(WORD *)ptr; *name = assembly_dup_str(assembly, stridx); if (!*name) @@ -815,10 +794,10 @@ HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version) return S_OK; } -BYTE assembly_get_architecture(ASSEMBLY *assembly) +PEKIND assembly_get_architecture(ASSEMBLY *assembly) { if ((assembly->corhdr->MajorRuntimeVersion == 2) && (assembly->corhdr->MinorRuntimeVersion == 0)) - return 0; /* .NET 1.x assembly */ + return peNone; /* .NET 1.x assembly */ if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) return peAMD64; /* AMD64/IA64 assembly */ @@ -829,23 +808,22 @@ BYTE assembly_get_architecture(ASSEMBLY *assembly) return peI386; /* x86 assembly */ } -static BYTE *assembly_get_blob(ASSEMBLY *assembly, WORD index, ULONG *size) +static BYTE *assembly_get_blob(ASSEMBLY *assembly, DWORD index, ULONG *size) { return GetData(&assembly->blobs[index], size); } HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token) { - ASSEMBLYTABLE *asmtbl; ULONG i, size; LONG offset; - BYTE *hashdata; + BYTE *hashdata, *pubkey, *ptr; HCRYPTPROV crypt; HCRYPTHASH hash; - BYTE *pubkey; BYTE tokbytes[BYTES_PER_TOKEN]; HRESULT hr = E_FAIL; LPWSTR tok; + DWORD idx; *token = NULL; @@ -853,11 +831,17 @@ HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token) if (offset == -1) return E_FAIL; - asmtbl = assembly_data_offset(assembly, offset); - if (!asmtbl) + ptr = assembly_data_offset(assembly, offset); + if (!ptr) return E_FAIL; - pubkey = assembly_get_blob(assembly, asmtbl->PublicKey, &size); + ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey); + if (assembly->blobsz == sizeof(DWORD)) + idx = *(DWORD *)ptr; + else + idx = *(WORD *)ptr; + + pubkey = assembly_get_blob(assembly, idx, &size); if (!CryptAcquireContextA(&crypt, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) @@ -905,3 +889,58 @@ done: return hr; } + +HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version) +{ + *version = assembly->metadatahdr->Version; + return S_OK; +} + +HRESULT assembly_get_external_files(ASSEMBLY *assembly, LPWSTR **files, DWORD *count) +{ + LONG offset; + INT i, num_rows; + WCHAR **ret; + BYTE *ptr; + DWORD idx; + + *count = 0; + + offset = assembly->tables[TableFromToken(mdtFile)].offset; + if (offset == -1) + return S_OK; + + ptr = assembly_data_offset(assembly, offset); + if (!ptr) + return S_OK; + + num_rows = assembly->tables[TableFromToken(mdtFile)].rows; + if (num_rows <= 0) + return S_OK; + + ret = HeapAlloc(GetProcessHeap(), 0, num_rows * sizeof(WCHAR *)); + if (!ret) + return E_OUTOFMEMORY; + + for (i = 0; i < num_rows; i++) + { + ptr += sizeof(DWORD); /* skip Flags field */ + if (assembly->stringsz == sizeof(DWORD)) + idx = *(DWORD *)ptr; + else + idx = *(WORD *)ptr; + + ret[i] = assembly_dup_str(assembly, idx); + if (!ret[i]) + { + for (; i >= 0; i--) HeapFree(GetProcessHeap(), 0, ret[i]); + HeapFree(GetProcessHeap(), 0, ret); + return E_OUTOFMEMORY; + } + ptr += assembly->stringsz; /* skip Name field */ + ptr += assembly->blobsz; /* skip Hash field */ + } + *count = num_rows; + *files = ret; + return S_OK; +} diff --git a/reactos/dll/win32/fusion/fusion.c b/reactos/dll/win32/fusion/fusion.c index 1543ed73fad..c8d3fad95da 100644 --- a/reactos/dll/win32/fusion/fusion.c +++ b/reactos/dll/win32/fusion/fusion.c @@ -36,6 +36,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(fusion); + +/****************************************************************** + * InitializeFusion (FUSION.@) + */ +HRESULT WINAPI InitializeFusion(void) +{ + FIXME("\n"); + return E_NOTIMPL; +} + /****************************************************************** * ClearDownloadCache (FUSION.@) */ @@ -80,9 +90,9 @@ static HRESULT get_corversion(LPWSTR version, DWORD size) pGetCORVersion = (void *)GetProcAddress(hmscoree, "GetCORVersion"); if (!pGetCORVersion) - return E_FAIL; - - hr = pGetCORVersion(version, size, &len); + hr = E_FAIL; + else + hr = pGetCORVersion(version, size, &len); FreeLibrary(hmscoree); return hr; @@ -94,32 +104,26 @@ static HRESULT get_corversion(LPWSTR version, DWORD size) HRESULT WINAPI GetCachePath(ASM_CACHE_FLAGS dwCacheFlags, LPWSTR pwzCachePath, PDWORD pcchPath) { - WCHAR path[MAX_PATH]; - WCHAR windir[MAX_PATH]; - WCHAR version[MAX_PATH]; - DWORD len; - HRESULT hr = S_OK; - - static const WCHAR backslash[] = {'\\',0}; - static const WCHAR assembly[] = {'a','s','s','e','m','b','l','y',0}; - static const WCHAR gac[] = {'G','A','C',0}; - static const WCHAR nativeimg[] = { - 'N','a','t','i','v','e','I','m','a','g','e','s','_',0}; + static const WCHAR assembly[] = {'\\','a','s','s','e','m','b','l','y',0}; + static const WCHAR gac[] = {'\\','G','A','C',0}; + static const WCHAR nativeimg[] = {'N','a','t','i','v','e','I','m','a','g','e','s','_',0}; + static const WCHAR dotnet[] = {'\\','M','i','c','r','o','s','o','f','t','.','N','E','T',0}; #ifdef _WIN64 static const WCHAR zapfmt[] = {'%','s','\\','%','s','\\','%','s','%','s','_','6','4',0}; #else static const WCHAR zapfmt[] = {'%','s','\\','%','s','\\','%','s','%','s','_','3','2',0}; #endif + WCHAR path[MAX_PATH], windir[MAX_PATH], version[MAX_PATH]; + DWORD len; + HRESULT hr = S_OK; TRACE("(%08x, %p, %p)\n", dwCacheFlags, pwzCachePath, pcchPath); if (!pcchPath) return E_INVALIDARG; - GetWindowsDirectoryW(windir, MAX_PATH); - lstrcpyW(path, windir); - lstrcatW(path, backslash); - lstrcatW(path, assembly); + len = GetWindowsDirectoryW(windir, MAX_PATH); + strcpyW(path, windir); switch (dwCacheFlags) { @@ -129,37 +133,42 @@ HRESULT WINAPI GetCachePath(ASM_CACHE_FLAGS dwCacheFlags, LPWSTR pwzCachePath, if (FAILED(hr)) return hr; - sprintfW(path, zapfmt, windir, assembly, nativeimg, version); + len = sprintfW(path, zapfmt, windir, assembly + 1, nativeimg, version); break; } - case ASM_CACHE_GAC: { - lstrcatW(path, backslash); - lstrcatW(path, gac); + strcpyW(path + len, assembly); + len += sizeof(assembly)/sizeof(WCHAR) - 1; + strcpyW(path + len, gac); + len += sizeof(gac)/sizeof(WCHAR) - 1; break; } - case ASM_CACHE_DOWNLOAD: { FIXME("Download cache not implemented\n"); return E_FAIL; } - case ASM_CACHE_ROOT: - break; /* already set */ - + strcpyW(path + len, assembly); + len += sizeof(assembly)/sizeof(WCHAR) - 1; + break; + case ASM_CACHE_ROOT_EX: + strcpyW(path + len, dotnet); + len += sizeof(dotnet)/sizeof(WCHAR) - 1; + strcpyW(path + len, assembly); + len += sizeof(assembly)/sizeof(WCHAR) - 1; + break; default: return E_INVALIDARG; } - len = lstrlenW(path) + 1; + len++; if (*pcchPath <= len || !pwzCachePath) hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); else if (pwzCachePath) - lstrcpyW(pwzCachePath, path); + strcpyW(pwzCachePath, path); *pcchPath = len; - return hr; } diff --git a/reactos/dll/win32/fusion/fusion.spec b/reactos/dll/win32/fusion/fusion.spec index 54e4eadd715..264aff70959 100644 --- a/reactos/dll/win32/fusion/fusion.spec +++ b/reactos/dll/win32/fusion/fusion.spec @@ -8,7 +8,7 @@ @ stdcall CreateInstallReferenceEnum(ptr ptr long ptr) @ stdcall GetCachePath(long wstr ptr) @ stub GetHistoryFileDirectory -@ stub InitializeFusion +@ stdcall InitializeFusion() @ stub InstallCustomAssembly @ stub InstallCustomModule @ stub LookupHistoryAssembly diff --git a/reactos/dll/win32/fusion/fusion_main.c b/reactos/dll/win32/fusion/fusion_main.c deleted file mode 100644 index 8af1fc86d21..00000000000 --- a/reactos/dll/win32/fusion/fusion_main.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * fusion main - * - * Copyright 2008 James Hawkins - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#define WIN32_NO_STATUS - -#include - -#include - -#include -#include -#include - -WINE_DEFAULT_DEBUG_CHANNEL(fusion); - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); - - switch (fdwReason) - { - case DLL_WINE_PREATTACH: - return FALSE; /* prefer native version */ - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - break; - case DLL_PROCESS_DETACH: - break; - default: - break; - } - - return TRUE; -} diff --git a/reactos/dll/win32/fusion/fusionpriv.h b/reactos/dll/win32/fusion/fusionpriv.h index 374b14abb8b..db89154803e 100644 --- a/reactos/dll/win32/fusion/fusionpriv.h +++ b/reactos/dll/win32/fusion/fusionpriv.h @@ -433,8 +433,10 @@ HRESULT assembly_release(ASSEMBLY *assembly) DECLSPEC_HIDDEN; HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name) DECLSPEC_HIDDEN; HRESULT assembly_get_path(const ASSEMBLY *assembly, LPWSTR *path) DECLSPEC_HIDDEN; HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version) DECLSPEC_HIDDEN; -BYTE assembly_get_architecture(ASSEMBLY *assembly) DECLSPEC_HIDDEN; +PEKIND assembly_get_architecture(ASSEMBLY *assembly) DECLSPEC_HIDDEN; HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token) DECLSPEC_HIDDEN; +HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version) DECLSPEC_HIDDEN; +HRESULT assembly_get_external_files(ASSEMBLY *assembly, LPWSTR **files, DWORD *count) DECLSPEC_HIDDEN; extern HRESULT IAssemblyName_SetPath(IAssemblyName *iface, LPCWSTR path) DECLSPEC_HIDDEN; extern HRESULT IAssemblyName_GetPath(IAssemblyName *iface, LPWSTR buf, ULONG *len) DECLSPEC_HIDDEN; diff --git a/reactos/include/psdk/corerror.h b/reactos/include/psdk/corerror.h index 1537f93e2cd..3ddfe474ac9 100644 --- a/reactos/include/psdk/corerror.h +++ b/reactos/include/psdk/corerror.h @@ -119,6 +119,7 @@ #define COR_E_HOSTPROTECTION EMAKEHR(0x1640) #define COR_E_ILLEGAL_REENTRANCY EMAKEHR(0x1641) +#define FUSION_E_PRIVATE_ASM_DISALLOWED EMAKEHR(0x1044) #define FUSION_E_INVALID_NAME EMAKEHR(0x1047) #define CLDB_E_FILE_OLDVER EMAKEHR(0x1107) diff --git a/reactos/include/psdk/fusion.idl b/reactos/include/psdk/fusion.idl index 99638383535..cff1e6cb8d3 100644 --- a/reactos/include/psdk/fusion.idl +++ b/reactos/include/psdk/fusion.idl @@ -28,7 +28,8 @@ typedef enum ASM_CACHE_ZAP = 0x1, ASM_CACHE_GAC = 0x2, ASM_CACHE_DOWNLOAD = 0x4, - ASM_CACHE_ROOT = 0x8 + ASM_CACHE_ROOT = 0x8, + ASM_CACHE_ROOT_EX = 0x80 } ASM_CACHE_FLAGS; typedef enum @@ -38,6 +39,7 @@ typedef enum peI386 = 0x00000002, peIA64 = 0x00000003, peAMD64 = 0x00000004, + peARM = 0x00000005, peInvalid = 0xffffffff } PEKIND; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 42c68c2979a..78a954f7274 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -62,7 +62,7 @@ reactos/dll/win32/dbghelp # Synced to Wine-1.3.37 reactos/dll/win32/dciman32 # Synced to Wine-1.5.19 reactos/dll/win32/dwmapi # Synced to Wine-1.5.19 reactos/dll/win32/faultrep # Synced to Wine-1.5.4 -reactos/dll/win32/fusion # Synced to Wine-1.5.4 +reactos/dll/win32/fusion # Synced to Wine-1.5.26 reactos/dll/win32/gdiplus # Synced to Wine-1.5.4 reactos/dll/win32/hhctrl.ocx # Synced to Wine-1.5.26 reactos/dll/win32/hlink # Synced to Wine-1.5.4 From 074fd3121828ae0d16949e4f9f7aeb66f90c3c70 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 4 May 2013 20:21:53 +0000 Subject: [PATCH 37/67] [FUSION_WINETEST] * Sync with Wine 1.5.26. svn path=/trunk/; revision=58928 --- rostests/winetests/fusion/CMakeLists.txt | 4 +- rostests/winetests/fusion/asmcache.c | 74 +++++++++++--- rostests/winetests/fusion/asmenum.c | 18 +++- rostests/winetests/fusion/asmname.c | 119 ++++++++++++++++++++++- rostests/winetests/fusion/fusion.c | 34 ++++--- rostests/winetests/fusion/testlist.c | 5 +- 6 files changed, 207 insertions(+), 47 deletions(-) diff --git a/rostests/winetests/fusion/CMakeLists.txt b/rostests/winetests/fusion/CMakeLists.txt index e265d5b2dbe..841c52c7dca 100644 --- a/rostests/winetests/fusion/CMakeLists.txt +++ b/rostests/winetests/fusion/CMakeLists.txt @@ -1,7 +1,5 @@ -add_definitions( - -D__ROS_LONG64__ - -D_DLL -D__USE_CRTIMP) +add_definitions(-D__ROS_LONG64__) list(APPEND SOURCE asmcache.c diff --git a/rostests/winetests/fusion/asmcache.c b/rostests/winetests/fusion/asmcache.c index 1b7cb282213..07f704759e8 100644 --- a/rostests/winetests/fusion/asmcache.c +++ b/rostests/winetests/fusion/asmcache.c @@ -16,17 +16,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + #define COBJMACROS #define INITGUID #include -#include -#include +//#include +#include +#include +#include +#include +//#include #include #include -#include "wine/test.h" +#include typedef struct _tagASSEMBLY ASSEMBLY; @@ -1011,6 +1019,18 @@ static void test_QueryAssemblyInfo(void) '_','M','S','I','L','\\','w','i','n','e','\\', '1','.','0','.','0','.','0','_','_','2','d','0','3','6','1','7','b', '1','c','3','1','e','2','f','5','\\',0}; + static const WCHAR wine2[] = { + 'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','1',',', + 'p','u','b','l','i','c','K','e','y','T','o','k','e','n','=', + '2','d','0','3','6','1','7','b','1','c','3','1','e','2','f','5',',', + 'c','u','l','t','u','r','e','=','n','e','u','t','r','a','l',0}; + static const WCHAR nullpublickey[] = { + 'm','s','c','o','r','l','i','b','.','d','l','l',',','v','e','r','s','i','o','n','=','0','.','0','.', + '0','.','0',',','c','u','l','t','u','r','e','=','n','e','u','t','r','a','l',',', + 'p','u','b','l','i','c','K','e','y','T','o','k','e','n','=','n','u','l','l',0}; + static const WCHAR nullpublickey1[] = { + 'm','s','c','o','r','l','i','b','.','d','l','l',',', + 'p','u','b','l','i','c','K','e','y','T','o','k','e','n','=','n','u','L','l',0}; size = MAX_PATH; hr = pGetCachePath(ASM_CACHE_GAC, asmpath, &size); @@ -1363,6 +1383,36 @@ static void test_QueryAssemblyInfo(void) "Assembly path was changed\n"); ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf); + /* display name is "wine,version=1.0.0.1,publicKeyToken=2d03617b1c31e2f5,culture=neutral" */ + INIT_ASM_INFO(); + lstrcpyW(name, wine2); + hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE, + name, &info); + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), + "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr); + ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), + "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); + ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags); + ok(info.uliAssemblySizeInKB.u.HighPart == 0, + "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart); + ok(info.uliAssemblySizeInKB.u.LowPart == 0, + "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart); + ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty), + "Assembly path was changed\n"); + ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf); + + /* display name is "mscorlib.dll,version=0.0.0.0,culture=neutral,publicKeyToken=null" */ + INIT_ASM_INFO(); + lstrcpyW(name, nullpublickey); + hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, name, &info); + ok(hr == FUSION_E_PRIVATE_ASM_DISALLOWED, "got %08x\n", hr); + + /* display name is "mscorlib.dll,publicKeyToken=nuLl" */ + INIT_ASM_INFO(); + lstrcpyW(name, nullpublickey1); + hr = IAssemblyCache_QueryAssemblyInfo(cache, 0, name, &info); + ok(hr == FUSION_E_PRIVATE_ASM_DISALLOWED, "got %08x\n", hr); + /* display name is "wine, Culture=neutral" */ INIT_ASM_INFO(); lstrcpyW(name, wine); @@ -1394,24 +1444,18 @@ static void test_QueryAssemblyInfo(void) lstrcatW(name, badculture); hr = IAssemblyCache_QueryAssemblyInfo(cache, QUERYASMINFO_FLAG_GETSIZE, name, &info); - todo_wine - { - ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), - "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr); - ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags); - } + ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), + "Expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got %08x\n", hr); + ok(info.dwAssemblyFlags == 0, "Expected 0, got %08x\n", info.dwAssemblyFlags); ok(info.cbAssemblyInfo == sizeof(ASSEMBLY_INFO), "Expected sizeof(ASSEMBLY_INFO), got %d\n", info.cbAssemblyInfo); ok(info.uliAssemblySizeInKB.u.HighPart == 0, "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.HighPart); ok(info.uliAssemblySizeInKB.u.LowPart == 0, "Expected 0, got %d\n", info.uliAssemblySizeInKB.u.LowPart); - todo_wine - { - ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty), - "Assembly path was changed\n"); - ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf); - } + ok(!lstrcmpW(info.pszCurrentAssemblyPathBuf, empty), + "Assembly path was changed\n"); + ok(info.cchBuf == MAX_PATH, "Expected MAX_PATH, got %d\n", info.cchBuf); /* display name is "wine, PublicKeyTokens=2d03617b1c31e2f5" */ INIT_ASM_INFO(); diff --git a/rostests/winetests/fusion/asmenum.c b/rostests/winetests/fusion/asmenum.c index a060529f27e..e9ea071e9e1 100644 --- a/rostests/winetests/fusion/asmenum.c +++ b/rostests/winetests/fusion/asmenum.c @@ -16,18 +16,26 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + #define COBJMACROS #include -#include +//#include +#include +#include +#include +#include #include -#include +//#include #include -#include +//#include -#include "wine/test.h" -#include "wine/list.h" +#include +#include static HRESULT (WINAPI *pCreateAssemblyEnum)(IAssemblyEnum **pEnum, IUnknown *pUnkReserved, diff --git a/rostests/winetests/fusion/asmname.c b/rostests/winetests/fusion/asmname.c index a99b288dca5..9cad29cbbb1 100644 --- a/rostests/winetests/fusion/asmname.c +++ b/rostests/winetests/fusion/asmname.c @@ -16,16 +16,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + #define COBJMACROS -#include +//#include +#include -#include -#include +//#include +#include +#include +#include +#include +//#include #include #include -#include "wine/test.h" +#include /* ok-like statement which takes two unicode strings or one unicode and one ANSI string as arguments */ static CHAR string1[MAX_PATH]; @@ -891,6 +900,107 @@ static void test_CreateAssemblyNameObject(void) ok(hr == FUSION_E_INVALID_NAME, "Expected FUSION_E_INVALID_NAME, got %08x\n", hr); ok(name == (IAssemblyName *)0xdeadbeef, "Expected 0xdeadbeef, got %p\n", name); + + /* no spaces */ + to_widechar(namestr, "wine,version=1.0.0.0"); + name = (IAssemblyName *)0xdeadbeef; + hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(name != NULL, "Expected non-NULL name\n"); + hi = lo = 0xdeadbeef; + hr = IAssemblyName_GetVersion(name, &hi, &lo); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(hi == 65536, "Expected 536, got %u\n", hi); + ok(lo == 0, "Expected 0, got %u\n", lo); + IAssemblyName_Release(name); + + /* quoted values */ + to_widechar(namestr, "wine, version=\"1.0.0.0\",culture=\"en\""); + name = (IAssemblyName *)0xdeadbeef; + hr = pCreateAssemblyNameObject(&name, namestr, CANOF_PARSE_DISPLAY_NAME, NULL); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(name != NULL, "Expected non-NULL name\n"); + hi = lo = 0xdeadbeef; + hr = IAssemblyName_GetVersion(name, &hi, &lo); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + ok(hi == 65536, "Expected 65536, got %u\n", hi); + ok(lo == 0, "Expected 0, got %u\n", lo); + IAssemblyName_Release(name); +} + +static void test_IAssemblyName_IsEqual(void) +{ + static const WCHAR wine1[] = + {'w','i','n','e',0}; + static const WCHAR wine2[] = + {'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','0',0}; + static const WCHAR wine3[] = + {'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','0',',', + 'c','u','l','t','u','r','e','=','n','e','u','t','r','a','l',0}; + static const WCHAR wine4[] = + {'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','0',',', + 'c','u','l','t','u','r','e','=','e','n',0}; + static const WCHAR wine5[] = + {'w','i','n','e',',','v','e','r','s','i','o','n','=','1','.','0','.','0','.','0',',', + 'p','u','b','l','i','c','K','e','y','T','o','k','e','n','=','1','2','3','4','5','6', + '7','8','9','0','a','b','c','d','e','f',0}; + HRESULT hr; + IAssemblyName *name1, *name2; + + hr = pCreateAssemblyNameObject( &name1, wine1, CANOF_PARSE_DISPLAY_NAME, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = pCreateAssemblyNameObject( &name2, wine1, CANOF_PARSE_DISPLAY_NAME, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + if (0) { /* crashes on some old version */ + hr = IAssemblyName_IsEqual( name1, NULL, 0 ); + ok( hr == S_FALSE, "got %08x\n", hr ); + + hr = IAssemblyName_IsEqual( name1, NULL, ASM_CMPF_IL_ALL ); + ok( hr == S_FALSE, "got %08x\n", hr ); + } + + hr = IAssemblyName_IsEqual( name1, name1, ASM_CMPF_IL_ALL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL ); + ok( hr == S_OK, "got %08x\n", hr ); + + IAssemblyName_Release( name2 ); + hr = pCreateAssemblyNameObject( &name2, wine2, CANOF_PARSE_DISPLAY_NAME, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL ); + ok( hr == S_OK, "got %08x\n", hr ); + + IAssemblyName_Release( name2 ); + hr = pCreateAssemblyNameObject( &name2, wine3, CANOF_PARSE_DISPLAY_NAME, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL ); + ok( hr == S_OK, "got %08x\n", hr ); + + IAssemblyName_Release( name1 ); + hr = pCreateAssemblyNameObject( &name1, wine4, CANOF_PARSE_DISPLAY_NAME, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL ); + ok( hr == S_FALSE, "got %08x\n", hr ); + + IAssemblyName_Release( name1 ); + hr = pCreateAssemblyNameObject( &name1, wine1, CANOF_PARSE_DISPLAY_NAME, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + IAssemblyName_Release( name2 ); + hr = pCreateAssemblyNameObject( &name2, wine5, CANOF_PARSE_DISPLAY_NAME, NULL ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = IAssemblyName_IsEqual( name1, name2, ASM_CMPF_IL_ALL ); + ok( hr == S_OK, "got %08x\n", hr ); + + IAssemblyName_Release( name1 ); + IAssemblyName_Release( name2 ); } START_TEST(asmname) @@ -902,4 +1012,5 @@ START_TEST(asmname) } test_CreateAssemblyNameObject(); + test_IAssemblyName_IsEqual(); } diff --git a/rostests/winetests/fusion/fusion.c b/rostests/winetests/fusion/fusion.c index 6ebd4550eb0..d0d757587b8 100644 --- a/rostests/winetests/fusion/fusion.c +++ b/rostests/winetests/fusion/fusion.c @@ -16,10 +16,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +//#include +#include +#include +#include +#include #include -#include "wine/test.h" +#include static HMODULE hmscoree; @@ -30,14 +40,6 @@ static HRESULT (WINAPI *pLoadLibraryShim)(LPCWSTR szDllName, LPCWSTR szVersion, static HRESULT (WINAPI *pGetCORVersion)(LPWSTR pbuffer, DWORD cchBuffer, DWORD *dwLength); -static CHAR string1[MAX_PATH], string2[MAX_PATH]; - -#define ok_w2(format, szString1, szString2) \ -\ - WideCharToMultiByte(CP_ACP, 0, szString1, -1, string1, MAX_PATH, NULL, NULL); \ - WideCharToMultiByte(CP_ACP, 0, szString2, -1, string2, MAX_PATH, NULL, NULL); \ - ok(!lstrcmpA(string1, string2), format, string1, string2) - static BOOL init_functionpointers(void) { HRESULT hr; @@ -127,14 +129,14 @@ static void test_GetCachePath(void) lstrcpyW(path, nochange); hr = pGetCachePath(ASM_CACHE_GAC, path, NULL); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); - ok_w2("Expected \"%s\", got \"%s\"\n", nochange, path); + ok( !lstrcmpW( nochange, path ), "Expected %s, got %s\n", wine_dbgstr_w(nochange), wine_dbgstr_w(path)); /* get the cache path */ lstrcpyW(path, nochange); size = MAX_PATH; hr = pGetCachePath(ASM_CACHE_GAC, path, &size); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); - ok_w2("Expected \"%s\", got \"%s\"\n", cachepath, path); + ok( !lstrcmpW( cachepath, path ), "Expected %s, got %s\n", wine_dbgstr_w(cachepath), wine_dbgstr_w(path)); /* pcchPath has no room for NULL terminator */ lstrcpyW(path, nochange); @@ -142,7 +144,7 @@ static void test_GetCachePath(void) hr = pGetCachePath(ASM_CACHE_GAC, path, &size); ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "Expected HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), got %08x\n", hr); - ok_w2("Expected \"%s\", got \"%s\"\n", nochange, path); + ok( !lstrcmpW( nochange, path ), "Expected %s, got %s\n", wine_dbgstr_w(nochange), wine_dbgstr_w(path)); lstrcpyW(cachepath, windir); lstrcatW(cachepath, backslash); @@ -156,7 +158,7 @@ static void test_GetCachePath(void) broken(hr == E_INVALIDARG), /* .NET 1.1 */ "Expected S_OK, got %08x\n", hr); if (hr == S_OK) - ok_w2("Expected \"%s\", got \"%s\"\n", cachepath, path); + ok( !lstrcmpW( cachepath, path ), "Expected %s, got %s\n", wine_dbgstr_w(cachepath), wine_dbgstr_w(path)); if (pGetCORVersion) { @@ -191,7 +193,7 @@ static void test_GetCachePath(void) size = MAX_PATH; hr = pGetCachePath(ASM_CACHE_ZAP, path, &size); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); - ok_w2("Expected \"%s\", got \"%s\"\n", cachepath, path); + ok( !lstrcmpW( cachepath, path ), "Expected %s, got %s\n", wine_dbgstr_w(cachepath), wine_dbgstr_w(path)); } /* two flags at once */ @@ -199,7 +201,7 @@ static void test_GetCachePath(void) size = MAX_PATH; hr = pGetCachePath(ASM_CACHE_GAC | ASM_CACHE_ROOT, path, &size); ok(hr == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", hr); - ok_w2("Expected \"%s\", got \"%s\"\n", nochange, path); + ok( !lstrcmpW( nochange, path ), "Expected %s, got %s\n", wine_dbgstr_w(nochange), wine_dbgstr_w(path)); } START_TEST(fusion) diff --git a/rostests/winetests/fusion/testlist.c b/rostests/winetests/fusion/testlist.c index a42cfc24642..20ade861be9 100644 --- a/rostests/winetests/fusion/testlist.c +++ b/rostests/winetests/fusion/testlist.c @@ -1,10 +1,7 @@ /* Automatically generated file; DO NOT EDIT!! */ -#define WIN32_LEAN_AND_MEAN -#include - #define STANDALONE -#include "wine/test.h" +#include extern void func_fusion(void); extern void func_asmname(void); From 148e43e691da1894e8b48e04fe4596bb8d02e0c4 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 4 May 2013 20:42:43 +0000 Subject: [PATCH 38/67] [CRT] * Annotate sys/utime.h. svn path=/trunk/; revision=58929 --- reactos/include/crt/sys/utime.h | 80 ++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/reactos/include/crt/sys/utime.h b/reactos/include/crt/sys/utime.h index 13925ec87fb..964890d83bd 100644 --- a/reactos/include/crt/sys/utime.h +++ b/reactos/include/crt/sys/utime.h @@ -38,7 +38,7 @@ extern "C" { }; #endif -#ifndef NO_OLDNAMES +#ifndef NO_OLDNAMES struct utimbuf { time_t actime; time_t modtime; @@ -49,19 +49,75 @@ extern "C" { __time32_t modtime; }; #endif + #endif /* !_UTIMBUF_DEFINED */ - _CRTIMP int __cdecl _utime(const char *_Filename,struct _utimbuf *_Time); - _CRTIMP int __cdecl _utime32(const char *_Filename,struct __utimbuf32 *_Time); - _CRTIMP int __cdecl _futime(int _FileDes,struct _utimbuf *_Time); - _CRTIMP int __cdecl _futime32(int _FileDes,struct __utimbuf32 *_Time); - _CRTIMP int __cdecl _wutime(const wchar_t *_Filename,struct _utimbuf *_Time); - _CRTIMP int __cdecl _wutime32(const wchar_t *_Filename,struct __utimbuf32 *_Time); + _CRTIMP + int + __cdecl + _utime( + _In_z_ const char *_Filename, + _In_opt_ struct _utimbuf *_Time); + + _CRTIMP + int + __cdecl + _utime32( + _In_z_ const char *_Filename, + _In_opt_ struct __utimbuf32 *_Time); + + _CRTIMP + int + __cdecl + _futime( + _In_ int _FileDes, + _In_opt_ struct _utimbuf *_Time); + + _CRTIMP + int + __cdecl + _futime32( + _In_ int _FileDes, + _In_opt_ struct __utimbuf32 *_Time); + + _CRTIMP + int + __cdecl + _wutime( + _In_z_ const wchar_t *_Filename, + _In_opt_ struct _utimbuf *_Time); + + _CRTIMP + int + __cdecl + _wutime32( + _In_z_ const wchar_t *_Filename, + _In_opt_ struct __utimbuf32 *_Time); + #if _INTEGRAL_MAX_BITS >= 64 - _CRTIMP int __cdecl _utime64(const char *_Filename,struct __utimbuf64 *_Time); - _CRTIMP int __cdecl _futime64(int _FileDes,struct __utimbuf64 *_Time); - _CRTIMP int __cdecl _wutime64(const wchar_t *_Filename,struct __utimbuf64 *_Time); -#endif + + _CRTIMP + int + __cdecl + _utime64( + _In_z_ const char *_Filename, + _In_opt_ struct __utimbuf64 *_Time); + + _CRTIMP + int + __cdecl + _futime64( + _In_ int _FileDes, + _In_opt_ struct __utimbuf64 *_Time); + + _CRTIMP + int + __cdecl + _wutime64( + _In_z_ const wchar_t *_Filename, + _In_opt_ struct __utimbuf64 *_Time); + +#endif /* _INTEGRAL_MAX_BITS >= 64 */ #ifndef RC_INVOKED #ifdef _USE_32BIT_TIME_T @@ -76,7 +132,7 @@ __CRT_INLINE int __cdecl _wutime32(const wchar_t *_Filename,struct __utimbuf32 * } #endif -#ifndef NO_OLDNAMES +#ifndef NO_OLDNAMES __CRT_INLINE int __cdecl utime(const char *_Filename,struct utimbuf *_Utimbuf) { return _utime(_Filename,(struct _utimbuf *)_Utimbuf); } From 800947d692df1f99dbd0c2d8ada3d3d48a0e2da8 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 4 May 2013 20:43:16 +0000 Subject: [PATCH 39/67] [PSDK] * Add NT_CONSOLE_PROPS and NT_FE_CONSOLE_PROPS and fix EXP_SZ_LINK. * Add SHELL_LINK_INFO_* and some Shell Link Extra Data structures (for IShellLinkDataList). [USERINIT][CPLS][DLLS] * Add the now necessary wincon.h inclusion. * Brought to you by Dominik Hornung. CORE-7162 #resolve #comment Committed in r58930. Danke ! svn path=/trunk/; revision=58930 --- .../applications/mscutils/servman/precomp.h | 1 + reactos/base/applications/mstsc/precomp.h | 1 + reactos/base/applications/rapps/rapps.h | 1 + reactos/base/shell/explorer-new/precomp.h | 1 + reactos/base/shell/explorer/precomp.h | 1 + reactos/base/system/userinit/userinit.c | 1 + reactos/dll/cpl/desk/desk.h | 1 + reactos/dll/cpl/main/main.h | 1 + reactos/dll/cpl/sysdm/precomp.h | 1 + reactos/dll/shellext/deskadp/precomp.h | 1 + reactos/dll/shellext/deskmon/precomp.h | 1 + reactos/dll/shellext/slayer/precomp.h | 1 + reactos/dll/win32/browseui/precomp.h | 1 + reactos/dll/win32/comdlg32/cdlg.h | 1 + reactos/dll/win32/comdlg32/filedlgbrowser.h | 1 + reactos/dll/win32/ieframe/ieframe.h | 1 + reactos/dll/win32/msi/package.c | 1 + reactos/dll/win32/newdev/newdev_private.h | 1 + reactos/dll/win32/setupapi/setupapi_private.h | 1 + reactos/dll/win32/shell32/precomp.h | 1 + reactos/dll/win32/shlwapi/ordinal.c | 1 + reactos/dll/win32/syssetup/precomp.h | 1 + reactos/include/psdk/shlobj.h | 47 ++++- reactos/include/psdk/shlobj_undoc.h | 183 ++++++++++++++++++ 24 files changed, 244 insertions(+), 8 deletions(-) diff --git a/reactos/base/applications/mscutils/servman/precomp.h b/reactos/base/applications/mscutils/servman/precomp.h index fa94a159387..9bde57022b5 100644 --- a/reactos/base/applications/mscutils/servman/precomp.h +++ b/reactos/base/applications/mscutils/servman/precomp.h @@ -11,6 +11,7 @@ #include #include #include /* GET_X/Y_LPARAM */ +#include #include #include #include diff --git a/reactos/base/applications/mstsc/precomp.h b/reactos/base/applications/mstsc/precomp.h index 8f1601ce3c8..75061933ba3 100644 --- a/reactos/base/applications/mstsc/precomp.h +++ b/reactos/base/applications/mstsc/precomp.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/base/applications/rapps/rapps.h b/reactos/base/applications/rapps/rapps.h index dd216ce3f0b..4c97d2ee3e4 100644 --- a/reactos/base/applications/rapps/rapps.h +++ b/reactos/base/applications/rapps/rapps.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/base/shell/explorer-new/precomp.h b/reactos/base/shell/explorer-new/precomp.h index 3ccceb181d0..343f06b7b31 100644 --- a/reactos/base/shell/explorer-new/precomp.h +++ b/reactos/base/shell/explorer-new/precomp.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/base/shell/explorer/precomp.h b/reactos/base/shell/explorer/precomp.h index 1caf6f50d5e..ccc73ff8381 100644 --- a/reactos/base/shell/explorer/precomp.h +++ b/reactos/base/shell/explorer/precomp.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/reactos/base/system/userinit/userinit.c b/reactos/base/system/userinit/userinit.c index e1a6fd23f55..7362a10733c 100644 --- a/reactos/base/system/userinit/userinit.c +++ b/reactos/base/system/userinit/userinit.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/cpl/desk/desk.h b/reactos/dll/cpl/desk/desk.h index 1ebe2b480b6..c714b4182e1 100644 --- a/reactos/dll/cpl/desk/desk.h +++ b/reactos/dll/cpl/desk/desk.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/cpl/main/main.h b/reactos/dll/cpl/main/main.h index b2dbf13419c..596e62b68da 100644 --- a/reactos/dll/cpl/main/main.h +++ b/reactos/dll/cpl/main/main.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/cpl/sysdm/precomp.h b/reactos/dll/cpl/sysdm/precomp.h index bf52f3aeb03..279167cedb9 100644 --- a/reactos/dll/cpl/sysdm/precomp.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/shellext/deskadp/precomp.h b/reactos/dll/shellext/deskadp/precomp.h index f8bad53e5c5..9c9cfad512d 100644 --- a/reactos/dll/shellext/deskadp/precomp.h +++ b/reactos/dll/shellext/deskadp/precomp.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/shellext/deskmon/precomp.h b/reactos/dll/shellext/deskmon/precomp.h index 564922a2a11..08b565559cd 100644 --- a/reactos/dll/shellext/deskmon/precomp.h +++ b/reactos/dll/shellext/deskmon/precomp.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/shellext/slayer/precomp.h b/reactos/dll/shellext/slayer/precomp.h index b5ea7d54401..c01102214c0 100644 --- a/reactos/dll/shellext/slayer/precomp.h +++ b/reactos/dll/shellext/slayer/precomp.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/win32/browseui/precomp.h b/reactos/dll/win32/browseui/precomp.h index 76bfac8db0a..3bcfc389ca2 100644 --- a/reactos/dll/win32/browseui/precomp.h +++ b/reactos/dll/win32/browseui/precomp.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/win32/comdlg32/cdlg.h b/reactos/dll/win32/comdlg32/cdlg.h index 5f3ac59786e..fd3bf71ecb0 100644 --- a/reactos/dll/win32/comdlg32/cdlg.h +++ b/reactos/dll/win32/comdlg32/cdlg.h @@ -165,6 +165,7 @@ typedef struct { #include "wingdi.h" #include "winuser.h" #include "winnls.h" +#include "wincon.h" #include "commctrl.h" #include "shlobj.h" #include "shellapi.h" diff --git a/reactos/dll/win32/comdlg32/filedlgbrowser.h b/reactos/dll/win32/comdlg32/filedlgbrowser.h index 90402b9d8a3..db82840c7df 100644 --- a/reactos/dll/win32/comdlg32/filedlgbrowser.h +++ b/reactos/dll/win32/comdlg32/filedlgbrowser.h @@ -33,6 +33,7 @@ //#include "windef.h" //#include "winbase.h" //#include "winuser.h" +#include "wincon.h" #include //#include "objbase.h" //#include "commdlg.h" diff --git a/reactos/dll/win32/ieframe/ieframe.h b/reactos/dll/win32/ieframe/ieframe.h index b526130a810..653b73093fe 100644 --- a/reactos/dll/win32/ieframe/ieframe.h +++ b/reactos/dll/win32/ieframe/ieframe.h @@ -31,6 +31,7 @@ #include #include //#include "winuser.h" +#include //#include "ole2.h" //#include "olectl.h" diff --git a/reactos/dll/win32/msi/package.c b/reactos/dll/win32/msi/package.c index d2b67e52bb0..e6d5b6a5f23 100644 --- a/reactos/dll/win32/msi/package.c +++ b/reactos/dll/win32/msi/package.c @@ -33,6 +33,7 @@ //#include "winnls.h" #include #include +#include #include //#include "msi.h" //#include "msiquery.h" diff --git a/reactos/dll/win32/newdev/newdev_private.h b/reactos/dll/win32/newdev/newdev_private.h index e3a7afe362f..533d77139c4 100644 --- a/reactos/dll/win32/newdev/newdev_private.h +++ b/reactos/dll/win32/newdev/newdev_private.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/win32/setupapi/setupapi_private.h b/reactos/dll/win32/setupapi/setupapi_private.h index 88dd35afd08..c85064f0b58 100644 --- a/reactos/dll/win32/setupapi/setupapi_private.h +++ b/reactos/dll/win32/setupapi/setupapi_private.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/win32/shell32/precomp.h b/reactos/dll/win32/shell32/precomp.h index 5a5b5745514..59224ca6be3 100644 --- a/reactos/dll/win32/shell32/precomp.h +++ b/reactos/dll/win32/shell32/precomp.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/reactos/dll/win32/shlwapi/ordinal.c b/reactos/dll/win32/shlwapi/ordinal.c index d832d1bbc40..644a400d1a1 100644 --- a/reactos/dll/win32/shlwapi/ordinal.c +++ b/reactos/dll/win32/shlwapi/ordinal.c @@ -43,6 +43,7 @@ //#include "winuser.h" #include #include +#include #include //#include "objbase.h" //#include "exdisp.h" diff --git a/reactos/dll/win32/syssetup/precomp.h b/reactos/dll/win32/syssetup/precomp.h index cbcdc84d937..6dbfee864c0 100644 --- a/reactos/dll/win32/syssetup/precomp.h +++ b/reactos/dll/win32/syssetup/precomp.h @@ -12,6 +12,7 @@ #include #include #include +#include #define NTOS_MODE_USER #include #include diff --git a/reactos/include/psdk/shlobj.h b/reactos/include/psdk/shlobj.h index 973994ae4a1..dc56d23f0de 100644 --- a/reactos/include/psdk/shlobj.h +++ b/reactos/include/psdk/shlobj.h @@ -1449,7 +1449,7 @@ typedef struct { typedef struct { DWORD cbSize; - DWORD cbSignature; + DWORD dwSignature; CHAR szTarget[MAX_PATH]; WCHAR szwTarget[MAX_PATH]; } EXP_SZ_LINK, *LPEXP_SZ_LINK; @@ -1467,14 +1467,45 @@ typedef struct { BYTE abPropertyStorage[1]; } EXP_PROPERTYSTORAGE; -#define EXP_SZ_LINK_SIG 0xa0000001 -#define NT_CONSOLE_PROPS_SIG 0xa0000002 -#define NT_FE_CONSOLE_PROPS_SIG 0xa0000004 -#define EXP_SPECIAL_FOLDER_SIG 0xa0000005 -#define EXP_DARWIN_ID_SIG 0xa0000006 -#define EXP_SZ_ICON_SIG 0xa0000007 +#ifdef LF_FACESIZE +typedef struct { + DATABLOCK_HEADER dbh; + WORD wFillAttribute; + WORD wPopupFillAttribute; + COORD dwScreenBufferSize; + COORD dwWindowSize; + COORD dwWindowOrigin; + DWORD nFont; + DWORD nInputBufferSize; + COORD dwFontSize; + UINT uFontFamily; + UINT uFontWeight; + WCHAR FaceName[LF_FACESIZE]; + UINT uCursorSize; + BOOL bFullScreen; + BOOL bQuickEdit; + BOOL bInsertMode; + BOOL bAutoPosition; + UINT uHistoryBufferSize; + UINT uNumberOfHistoryBuffers; + BOOL bHistoryNoDup; + COLORREF ColorTable[16]; +} NT_CONSOLE_PROPS, *LPNT_CONSOLE_PROPS; +#endif + +typedef struct { + DATABLOCK_HEADER dbh; + UINT uCodePage; +} NT_FE_CONSOLE_PROPS, *LPNT_FE_CONSOLE_PROPS; + +#define EXP_SZ_LINK_SIG 0xa0000001 /* EXP_SZ_LINK */ +#define NT_CONSOLE_PROPS_SIG 0xa0000002 /* NT_CONSOLE_PROPS */ +#define NT_FE_CONSOLE_PROPS_SIG 0xa0000004 /* NT_FE_CONSOLE_PROPS */ +#define EXP_SPECIAL_FOLDER_SIG 0xa0000005 /* EXP_SPECIAL_FOLDER */ +#define EXP_DARWIN_ID_SIG 0xa0000006 /* EXP_DARWIN_LINK */ +#define EXP_SZ_ICON_SIG 0xa0000007 /* EXP_SZ_LINK */ #define EXP_LOGO3_ID_SIG EXP_SZ_ICON_SIG /* Old SDKs only */ -#define EXP_PROPERTYSTORAGE_SIG 0xa0000009 +#define EXP_PROPERTYSTORAGE_SIG 0xa0000009 /* EXP_PROPERTYSTORAGE */ typedef struct _SHChangeDWORDAsIDList { USHORT cb; diff --git a/reactos/include/psdk/shlobj_undoc.h b/reactos/include/psdk/shlobj_undoc.h index 5be8e58d074..8a799cfb563 100644 --- a/reactos/include/psdk/shlobj_undoc.h +++ b/reactos/include/psdk/shlobj_undoc.h @@ -2,6 +2,7 @@ * ReactOS undocumented shell interface * * Copyright 2009 Andrew Hill + * Copyright 2013 Dominik Hornung * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -867,6 +868,188 @@ typedef struct tagSHELL_LINK_HEADER DWORD dwReserved3; } SHELL_LINK_HEADER, *LPSHELL_LINK_HEADER; +/***************************************************************************** + * SHELL_LINK_INFOA/W + * If cbHeaderSize == 0x0000001C then use SHELL_LINK_INFOA + * If cbHeaderSize >= 0x00000024 then use SHELL_LINK_INFOW + */ +typedef struct tagSHELL_LINK_INFOA +{ + /* Size of the link info data */ + DWORD cbSize; + /* Size of this structure (ANSI: = 0x0000001C) */ + DWORD cbHeaderSize; + /* Specifies which fields are present/populated (SLI_*) */ + DWORD dwFlags; + /* Offset of the VolumeID field (SHELL_LINK_INFO_VOLUME_ID) */ + DWORD cbVolumeIDOffset; + /* Offset of the LocalBasePath field (ANSI, NULL-terminated string) */ + DWORD cbLocalBasePathOffset; + /* Offset of the CommonNetworkRelativeLink field (SHELL_LINK_INFO_CNR_LINK) */ + DWORD cbCommonNetworkRelativeLinkOffset; + /* Offset of the CommonPathSuffix field (ANSI, NULL-terminated string) */ + DWORD cbCommonPathSuffixOffset; +} SHELL_LINK_INFOA, *LPSHELL_LINK_INFOA; + +typedef struct tagSHELL_LINK_INFOW +{ + /* Size of the link info data */ + DWORD cbSize; + /* Size of this structure (Unicode: >= 0x00000024) */ + DWORD cbHeaderSize; + /* Specifies which fields are present/populated (SLI_*) */ + DWORD dwFlags; + /* Offset of the VolumeID field (SHELL_LINK_INFO_VOLUME_ID) */ + DWORD cbVolumeIDOffset; + /* Offset of the LocalBasePath field (ANSI, NULL-terminated string) */ + DWORD cbLocalBasePathOffset; + /* Offset of the CommonNetworkRelativeLink field (SHELL_LINK_INFO_CNR_LINK) */ + DWORD cbCommonNetworkRelativeLinkOffset; + /* Offset of the CommonPathSuffix field (ANSI, NULL-terminated string) */ + DWORD cbCommonPathSuffixOffset; + /* Offset of the LocalBasePathUnicode field (Unicode, NULL-terminated string) */ + DWORD cbLocalBasePathUnicodeOffset; + /* Offset of the CommonPathSuffixUnicode field (Unicode, NULL-terminated string) */ + DWORD cbCommonPathSuffixUnicodeOffset; +} SHELL_LINK_INFOW, *LPSHELL_LINK_INFOW; + +/* VolumeID, LocalBasePath, LocalBasePathUnicode(cbHeaderSize >= 0x24) are present */ +#define SLI_VALID_LOCAL 0x00000001 +/* CommonNetworkRelativeLink is present */ +#define SLI_VALID_NETWORK 0x00000002 + +/***************************************************************************** + * SHELL_LINK_INFO_VOLUME_IDA/W + * If cbVolumeLabelOffset != 0x00000014 (should be 0x00000010) then use + * SHELL_LINK_INFO_VOLUME_IDA + * If cbVolumeLabelOffset == 0x00000014 then use SHELL_LINK_INFO_VOLUME_IDW + */ +typedef struct tagSHELL_LINK_INFO_VOLUME_IDA +{ + /* Size of the VolumeID field (> 0x00000010) */ + DWORD cbSize; + /* Drive type of the drive the link target is stored on (DRIVE_*) */ + DWORD dwDriveType; + /* Serial number of the volume the link target is stored on */ + DWORD nDriveSerialNumber; + /* Offset of the volume label (ANSI, NULL-terminated string). + Must be != 0x00000014 (see tagSHELL_LINK_INFO_VOLUME_IDW) */ + DWORD cbVolumeLabelOffset; +} SHELL_LINK_INFO_VOLUME_IDA, *LPSHELL_LINK_INFO_VOLUME_IDA; + +typedef struct tagSHELL_LINK_INFO_VOLUME_IDW +{ + /* Size of the VolumeID field (> 0x00000010) */ + DWORD cbSize; + /* Drive type of the drive the link target is stored on (DRIVE_*) */ + DWORD dwDriveType; + /* Serial number of the volume the link target is stored on */ + DWORD nDriveSerialNumber; + /* Offset of the volume label (ANSI, NULL-terminated string). + If the value of this field is 0x00000014, ignore it and use + cbVolumeLabelUnicodeOffset! */ + DWORD cbVolumeLabelOffset; + /* Offset of the volume label (Unicode, NULL-terminated string). + If the value of the VolumeLabelOffset field is not 0x00000014, + this field must be ignored (==> it doesn't exists ==> ANSI). */ + DWORD cbVolumeLabelUnicodeOffset; +} SHELL_LINK_INFO_VOLUME_IDW, *LPSHELL_LINK_INFO_VOLUME_IDW; + +/***************************************************************************** + * SHELL_LINK_INFO_CNR_LINKA/W (CNR = Common Network Relative) + * If cbNetNameOffset == 0x00000014 then use SHELL_LINK_INFO_CNR_LINKA + * If cbNetNameOffset > 0x00000014 then use SHELL_LINK_INFO_CNR_LINKW + */ +typedef struct tagSHELL_LINK_INFO_CNR_LINKA +{ + /* Size of the CommonNetworkRelativeLink field (>= 0x00000014) */ + DWORD cbSize; + /* Specifies which fields are present/populated (SLI_CNR_*) */ + DWORD dwFlags; + /* Offset of the NetName field (ANSI, NULL–terminated string) */ + DWORD cbNetNameOffset; + /* Offset of the DeviceName field (ANSI, NULL–terminated string) */ + DWORD cbDeviceNameOffset; + /* Type of the network provider (WNNC_NET_* defined in winnetwk.h) */ + DWORD dwNetworkProviderType; +} SHELL_LINK_INFO_CNR_LINKA, *LPSHELL_LINK_INFO_CNR_LINKA; + +typedef struct tagSHELL_LINK_INFO_CNR_LINKW +{ + /* Size of the CommonNetworkRelativeLink field (>= 0x00000014) */ + DWORD cbSize; + /* Specifies which fields are present/populated (SLI_CNR_*) */ + DWORD dwFlags; + /* Offset of the NetName field (ANSI, NULL–terminated string) */ + DWORD cbNetNameOffset; + /* Offset of the DeviceName field (ANSI, NULL–terminated string) */ + DWORD cbDeviceNameOffset; + /* Type of the network provider (WNNC_NET_* defined in winnetwk.h) */ + DWORD dwNetworkProviderType; + /* Offset of the NetNameUnicode field (Unicode, NULL–terminated string) */ + DWORD cbNetNameUnicodeOffset; + /* Offset of the DeviceNameUnicode field (Unicode, NULL–terminated string) */ + DWORD cbDeviceNameUnicodeOffset; +} SHELL_LINK_INFO_CNR_LINKW, *LPSHELL_LINK_INFO_CNR_LINKW; + +/* DeviceName is present */ +#define SLI_CNR_VALID_DEVICE 0x00000001 +/* NetworkProviderType is present */ +#define SLI_CNR_VALID_NET_TYPE 0x00000002 + +/***************************************************************************** + * Shell Link Extra Data (IShellLinkDataList) + */ +typedef struct tagEXP_TRACKER +{ + /* .cbSize = 0x00000060, .dwSignature = 0xa0000003 */ + DATABLOCK_HEADER dbh; + /* Length >= 0x00000058 */ + DWORD nLength; + /* Must be 0x00000000 */ + DWORD nVersion; + /* NetBIOS name (ANSI, unused bytes are set to zero) */ + CHAR szMachineID[16]; /* "variable" >= 16 (?) */ + /* Some GUIDs for the Link Tracking service (from the FS?) */ + GUID guidDroidVolume; + GUID guidDroidObject; + GUID guidDroidBirthVolume; + GUID guidDroidBirthObject; +} EXP_TRACKER, *LPEXP_TRACKER; + +typedef struct tagEXP_SHIM +{ + /* .cbSize >= 0x00000088, .dwSignature = 0xa0000008 */ + DATABLOCK_HEADER dbh; + /* Name of a shim layer to apply (Unicode, unused bytes are set to zero) */ + WCHAR szwLayerName[64]; /* "variable" >= 64 */ +} EXP_SHIM, *LPEXP_SHIM; + +typedef struct tagEXP_KNOWN_FOLDER +{ + /* .cbSize = 0x0000001c, .dwSignature = 0xa000000b */ + DATABLOCK_HEADER dbh; + /* A GUID value that identifies a known folder */ + GUID guidKnownFolder; + /* Specifies the location of the ItemID of the first child + segment of the IDList specified by guidKnownFolder */ + DWORD cbOffset; +} EXP_KNOWN_FOLDER, *LPEXP_KNOWN_FOLDER; + +typedef struct tagEXP_VISTA_ID_LIST +{ + /* .cbSize >= 0x0000000a, .dwSignature = 0xa000000c */ + DATABLOCK_HEADER dbh; + /* Specifies an alternate IDList that can be used instead + of the "normal" IDList (SLDF_HAS_ID_LIST) */ + /* LPITEMIDLIST pIDList; (variable) */ +} EXP_VISTA_ID_LIST, *LPEXP_VISTA_ID_LIST; + +#define EXP_TRACKER_SIG 0xa0000003 +#define EXP_SHIM_SIG 0xa0000008 +#define EXP_KNOWN_FOLDER_SIG 0xa000000b +#define EXP_VISTA_ID_LIST_SIG 0xa000000c + #include #ifdef __cplusplus From 819b46d5a82186d01aeb2d472c211469bd3b4411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 May 2013 21:03:27 +0000 Subject: [PATCH 40/67] [CONSRV] Add heap diagnostic flags for the ConSrvHeap. svn path=/trunk/; revision=58931 --- reactos/win32ss/user/consrv/init.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/reactos/win32ss/user/consrv/init.c b/reactos/win32ss/user/consrv/init.c index 640f76f67a0..dd67d80469e 100644 --- a/reactos/win32ss/user/consrv/init.c +++ b/reactos/win32ss/user/consrv/init.c @@ -484,7 +484,12 @@ CSR_SERVER_DLL_INIT(ConServerDllInitialization) // HACK: To try to uncover a heap corruption in CONSRV, use our own heap // instead of the CSR heap, so that we won't corrupt it. // ConSrvHeap = RtlGetProcessHeap(); - ConSrvHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL); + ConSrvHeap = RtlCreateHeap(HEAP_GROWABLE | + HEAP_PROTECTION_ENABLED | + HEAP_FREE_CHECKING_ENABLED | + HEAP_TAIL_CHECKING_ENABLED | + HEAP_VALIDATE_ALL_ENABLED, + NULL, 0, 0, NULL, NULL); if (!ConSrvHeap) return STATUS_NO_MEMORY; ConSrvInitConsoleSupport(); From b914d7bd8edfda70dacbb63d04bcf9f02392f93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 4 May 2013 22:15:26 +0000 Subject: [PATCH 41/67] [CDMAKE] ISO images generated by cdmake have invalid time and date. Patch by Aleksandar Andrejevic, aka. [TheFlash] CORE-7163 #resolve #comment Committed in revision r58932, thanks for the patch ;) svn path=/trunk/; revision=58932 --- reactos/tools/cdmake/cdmake.c | 50 ++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/reactos/tools/cdmake/cdmake.c b/reactos/tools/cdmake/cdmake.c index 622226b78cc..751c588da68 100644 --- a/reactos/tools/cdmake/cdmake.c +++ b/reactos/tools/cdmake/cdmake.c @@ -1097,6 +1097,20 @@ static void get_file_specifications(PDIR_RECORD d) } } +static void get_time_string(char *str) +{ + struct tm *current; + time_t timestamp = time(NULL); + current = gmtime(×tamp); + sprintf(str, "%04d%02d%02d%02d%02d%02d00", + current->tm_year + 1900, + current->tm_mon, + current->tm_mday, + current->tm_hour, + current->tm_min, + current->tm_sec); +} + static void pass(void) { PDIR_RECORD d; @@ -1110,6 +1124,9 @@ static void pass(void) char *old_end_source; int n; FILE *file; + char timestring[17]; + + get_time_string(timestring); // first 16 sectors are zeros @@ -1144,13 +1161,13 @@ static void pass(void) write_block(37, ' '); // copyright file identifier write_block(37, ' '); // abstract file identifier write_block(37, ' '); // bibliographic file identifier - write_string("0000000000000000"); // volume creation + write_string(timestring); // volume creation write_byte(0); - write_string("0000000000000000"); // most recent modification + write_string(timestring); // most recent modification write_byte(0); - write_string("0000000000000000"); // volume expires + write_string(timestring); // volume expires write_byte(0); - write_string("0000000000000000"); // volume is effective + write_string(timestring); // volume is effective write_byte(0); write_byte(1); write_byte(0); @@ -1203,14 +1220,14 @@ static void pass(void) write_block(37, ' '); // copyright file identifier write_block(37, ' '); // abstract file identifier write_block(37, ' '); // bibliographic file identifier - write_string("0000000000000000"); // volume creation - write_byte(0); - write_string("0000000000000000"); // most recent modification - write_byte(0); - write_string("0000000000000000"); // volume expires - write_byte(0); - write_string("0000000000000000"); // volume is effective - write_byte(0); + write_string(timestring); // volume creation + write_byte(48); + write_string(timestring); // most recent modification + write_byte(48); + write_string(timestring); // volume expires + write_byte(48); + write_string(timestring); // volume is effective + write_byte(48); write_byte(1); write_byte(0); fill_sector(); @@ -1499,6 +1516,8 @@ Program execution starts here. int main(int argc, char **argv) { + struct tm *current_time; + time_t timestamp = time(NULL); BOOL q_option = FALSE; BOOL v_option = FALSE; int i; @@ -1520,8 +1539,15 @@ int main(int argc, char **argv) error_exit("Insufficient memory"); memset(&root, 0, sizeof(root)); + current_time = gmtime(×tamp); root.level = 1; root.flags = DIRECTORY_FLAG; + root.date_and_time.year = current_time->tm_year + 1900; + root.date_and_time.month = current_time->tm_mon; + root.date_and_time.day = current_time->tm_mday; + root.date_and_time.hour = current_time->tm_hour; + root.date_and_time.minute = current_time->tm_min; + root.date_and_time.second = current_time->tm_sec; // initialize CD-ROM write buffer From 7934e35cdf55b07334f04d86d9c7717b0cb41c0b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 5 May 2013 00:39:58 +0000 Subject: [PATCH 42/67] [LSASRV] Free additional data returned by calls to LsaApLogonUser/Ex/2. svn path=/trunk/; revision=58933 --- reactos/dll/win32/lsasrv/authpackage.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/reactos/dll/win32/lsasrv/authpackage.c b/reactos/dll/win32/lsasrv/authpackage.c index a5af21fedee..04d23726bd0 100644 --- a/reactos/dll/win32/lsasrv/authpackage.c +++ b/reactos/dll/win32/lsasrv/authpackage.c @@ -743,6 +743,7 @@ done: if (LocalAuthInfo != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, LocalAuthInfo); + /* Free the token information */ if (TokenInformation != NULL) { if (TokenInformationType == LsaTokenInformationV1) @@ -786,19 +787,31 @@ done: } } + /* Free the account name */ if (AccountName != NULL) { + if (AccountName->Buffer != NULL) + LsapFreeHeap(AccountName->Buffer); + LsapFreeHeap(AccountName); } + /* Free the authentication authority */ if (AuthenticatingAuthority != NULL) { + if (AuthenticatingAuthority != NULL) + LsapFreeHeap(AuthenticatingAuthority->Buffer); + LsapFreeHeap(AuthenticatingAuthority); } + /* Free the machine name */ if (MachineName != NULL) { + if (MachineName->Buffer != NULL) + LsapFreeHeap(MachineName->Buffer); + LsapFreeHeap(MachineName); } return Status; From e979b5ce8a35e218b48b701525910ab27596eb6b Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 5 May 2013 00:53:25 +0000 Subject: [PATCH 43/67] [MSV1_0] Add token data from the old logon code. svn path=/trunk/; revision=58934 --- reactos/dll/win32/msv1_0/msv1_0.c | 558 +++++++++++++++++++++++++++++- reactos/dll/win32/msv1_0/msv1_0.h | 7 +- 2 files changed, 557 insertions(+), 8 deletions(-) diff --git a/reactos/dll/win32/msv1_0/msv1_0.c b/reactos/dll/win32/msv1_0/msv1_0.c index e4267c35a67..e1fe77cd3c8 100644 --- a/reactos/dll/win32/msv1_0/msv1_0.c +++ b/reactos/dll/win32/msv1_0/msv1_0.c @@ -81,7 +81,7 @@ BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, PVOID ClientBaseAddress = NULL; LPWSTR Ptr; ULONG BufferLength; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; *ProfileBuffer = NULL; *ProfileBufferLength = 0; @@ -118,12 +118,24 @@ BuildInteractiveProfileBuffer(IN PLSA_CLIENT_REQUEST ClientRequest, LocalBuffer->MessageType = MsV1_0InteractiveProfile; LocalBuffer->LogonCount = UserInfo->All.LogonCount; LocalBuffer->BadPasswordCount = UserInfo->All.BadPasswordCount; -// LARGE_INTEGER LogonTime; -// LARGE_INTEGER LogoffTime; -// LARGE_INTEGER KickOffTime; -// LARGE_INTEGER PasswordLastSet; -// LARGE_INTEGER PasswordCanChange; -// LARGE_INTEGER PasswordMustChange; + + LocalBuffer->LogonTime.LowPart = UserInfo->All.LastLogon.LowPart; + LocalBuffer->LogonTime.HighPart = UserInfo->All.LastLogon.HighPart; + +// LocalBuffer->LogoffTime.LowPart = +// LocalBuffer->LogoffTime.HighPart = + +// LocalBuffer->KickOffTime.LowPart = +// LocalBuffer->KickOffTime.HighPart = + + LocalBuffer->PasswordLastSet.LowPart = UserInfo->All.PasswordLastSet.LowPart; + LocalBuffer->PasswordLastSet.HighPart = UserInfo->All.PasswordLastSet.HighPart; + + LocalBuffer->PasswordCanChange.LowPart = UserInfo->All.PasswordCanChange.LowPart; + LocalBuffer->PasswordCanChange.HighPart = UserInfo->All.PasswordCanChange.HighPart; + + LocalBuffer->PasswordMustChange.LowPart = UserInfo->All.PasswordMustChange.LowPart; + LocalBuffer->PasswordMustChange.HighPart = UserInfo->All.PasswordMustChange.HighPart; LocalBuffer->LogonScript.Length = UserInfo->All.ScriptPath.Length; LocalBuffer->LogonScript.MaximumLength = UserInfo->All.ScriptPath.Length + sizeof(WCHAR); @@ -208,6 +220,511 @@ done: } +static +PSID +AppendRidToSid(PSID SrcSid, + ULONG Rid) +{ + PSID DstSid = NULL; + UCHAR RidCount; + ULONG Size; + ULONG i; + + RidCount = *RtlSubAuthorityCountSid(SrcSid); + if (RidCount >= 8) + return NULL; + + Size = RtlLengthRequiredSid(RidCount + 1); + + DstSid = DispatchTable.AllocateLsaHeap(Size); + if (DstSid == NULL) + return NULL; + + for (i = 0; i < RidCount; i++) + *RtlSubAuthoritySid(DstSid, i) = *RtlSubAuthoritySid(SrcSid, i); + + *RtlSubAuthoritySid(DstSid, RidCount) = Rid; + + return DstSid; +} + +static +NTSTATUS +BuildTokenUser(OUT PTOKEN_USER User, + IN PSID AccountDomainSid, + IN ULONG RelativeId) +{ + User->User.Sid = AppendRidToSid(AccountDomainSid, + RelativeId); + User->User.Attributes = 0; + + return STATUS_SUCCESS; +} + + +static +NTSTATUS +BuildTokenGroups(IN PSID AccountDomainSid, + IN PLUID LogonId, + OUT PTOKEN_GROUPS *Groups, + OUT PSID *PrimaryGroupSid, + OUT PSID *OwnerSid) +{ + SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY}; + SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; + PTOKEN_GROUPS TokenGroups; +#define MAX_GROUPS 8 + DWORD GroupCount = 0; + PSID Sid; + NTSTATUS Status = STATUS_SUCCESS; + + TokenGroups = DispatchTable.AllocateLsaHeap(sizeof(TOKEN_GROUPS) + + MAX_GROUPS * sizeof(SID_AND_ATTRIBUTES)); + if (TokenGroups == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + Sid = AppendRidToSid(AccountDomainSid, DOMAIN_GROUP_RID_USERS); + if (Sid == NULL) + { + + } + + /* Member of the domain */ + TokenGroups->Groups[GroupCount].Sid = Sid; + TokenGroups->Groups[GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + *PrimaryGroupSid = Sid; + GroupCount++; + + /* Member of 'Everyone' */ + RtlAllocateAndInitializeSid(&WorldAuthority, + 1, + SECURITY_WORLD_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + TokenGroups->Groups[GroupCount].Sid = Sid; + TokenGroups->Groups[GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + GroupCount++; + +#if 1 + /* Member of 'Administrators' */ + RtlAllocateAndInitializeSid(&SystemAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + TokenGroups->Groups[GroupCount].Sid = Sid; + TokenGroups->Groups[GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + GroupCount++; +#else + TRACE("Not adding user to Administrators group\n"); +#endif + + /* Member of 'Users' */ + RtlAllocateAndInitializeSid(&SystemAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_USERS, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + TokenGroups->Groups[GroupCount].Sid = Sid; + TokenGroups->Groups[GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + GroupCount++; + + /* Logon SID */ + RtlAllocateAndInitializeSid(&SystemAuthority, + SECURITY_LOGON_IDS_RID_COUNT, + SECURITY_LOGON_IDS_RID, + LogonId->HighPart, + LogonId->LowPart, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + TokenGroups->Groups[GroupCount].Sid = Sid; + TokenGroups->Groups[GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY | SE_GROUP_LOGON_ID; + GroupCount++; + *OwnerSid = Sid; + + /* Member of 'Local users */ + RtlAllocateAndInitializeSid(&LocalAuthority, + 1, + SECURITY_LOCAL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + TokenGroups->Groups[GroupCount].Sid = Sid; + TokenGroups->Groups[GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + GroupCount++; + + /* Member of 'Interactive users' */ + RtlAllocateAndInitializeSid(&SystemAuthority, + 1, + SECURITY_INTERACTIVE_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + TokenGroups->Groups[GroupCount].Sid = Sid; + TokenGroups->Groups[GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + GroupCount++; + + /* Member of 'Authenticated users' */ + RtlAllocateAndInitializeSid(&SystemAuthority, + 1, + SECURITY_AUTHENTICATED_USER_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &Sid); + TokenGroups->Groups[GroupCount].Sid = Sid; + TokenGroups->Groups[GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + GroupCount++; + + TokenGroups->GroupCount = GroupCount; + ASSERT(TokenGroups->GroupCount <= MAX_GROUPS); + + *Groups = TokenGroups; + + return Status; +} + + +static +NTSTATUS +BuildTokenPrimaryGroup(PTOKEN_PRIMARY_GROUP PrimaryGroup, + PSID PrimaryGroupSid) +{ + ULONG RidCount; + ULONG Size; + + RidCount = *RtlSubAuthorityCountSid(PrimaryGroupSid); + Size = RtlLengthRequiredSid(RidCount); + + PrimaryGroup->PrimaryGroup = DispatchTable.AllocateLsaHeap(Size); + if (PrimaryGroup->PrimaryGroup == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyMemory(PrimaryGroup->PrimaryGroup, + PrimaryGroupSid, + Size); + + return STATUS_SUCCESS; +} + +static +NTSTATUS +BuildTokenPrivileges(PTOKEN_PRIVILEGES *TokenPrivileges) +{ + /* FIXME shouldn't use hard-coded list of privileges */ + static struct + { + LPCWSTR PrivName; + DWORD Attributes; + } + DefaultPrivs[] = + { + { L"SeMachineAccountPrivilege", 0 }, + { L"SeSecurityPrivilege", 0 }, + { L"SeTakeOwnershipPrivilege", 0 }, + { L"SeLoadDriverPrivilege", 0 }, + { L"SeSystemProfilePrivilege", 0 }, + { L"SeSystemtimePrivilege", 0 }, + { L"SeProfileSingleProcessPrivilege", 0 }, + { L"SeIncreaseBasePriorityPrivilege", 0 }, + { L"SeCreatePagefilePrivilege", 0 }, + { L"SeBackupPrivilege", 0 }, + { L"SeRestorePrivilege", 0 }, + { L"SeShutdownPrivilege", 0 }, + { L"SeDebugPrivilege", 0 }, + { L"SeSystemEnvironmentPrivilege", 0 }, + { L"SeChangeNotifyPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }, + { L"SeRemoteShutdownPrivilege", 0 }, + { L"SeUndockPrivilege", 0 }, + { L"SeEnableDelegationPrivilege", 0 }, + { L"SeImpersonatePrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT }, + { L"SeCreateGlobalPrivilege", SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT } + }; + PTOKEN_PRIVILEGES Privileges = NULL; + ULONG i; + RPC_UNICODE_STRING PrivilegeName; + LSAPR_HANDLE PolicyHandle = NULL; + NTSTATUS Status = STATUS_SUCCESS; + + Status = LsaIOpenPolicyTrusted(&PolicyHandle); + if (!NT_SUCCESS(Status)) + { + goto done; + } + + /* Allocate and initialize token privileges */ + Privileges = DispatchTable.AllocateLsaHeap(sizeof(TOKEN_PRIVILEGES) + + sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]) * + sizeof(LUID_AND_ATTRIBUTES)); + if (Privileges == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Privileges->PrivilegeCount = 0; + for (i = 0; i < sizeof(DefaultPrivs) / sizeof(DefaultPrivs[0]); i++) + { + PrivilegeName.Length = wcslen(DefaultPrivs[i].PrivName) * sizeof(WCHAR); + PrivilegeName.MaximumLength = PrivilegeName.Length + sizeof(WCHAR); + PrivilegeName.Buffer = (LPWSTR)DefaultPrivs[i].PrivName; + + Status = LsarLookupPrivilegeValue(PolicyHandle, + &PrivilegeName, + &Privileges->Privileges[Privileges->PrivilegeCount].Luid); + if (!NT_SUCCESS(Status)) + { + WARN("Can't set privilege %S\n", DefaultPrivs[i].PrivName); + } + else + { + Privileges->Privileges[Privileges->PrivilegeCount].Attributes = DefaultPrivs[i].Attributes; + Privileges->PrivilegeCount++; + } + } + + *TokenPrivileges = Privileges; + +done: + if (PolicyHandle != NULL) + LsarClose(PolicyHandle); + + return Status; +} + + +static +NTSTATUS +BuildTokenOwner(PTOKEN_OWNER Owner, + PSID OwnerSid) +{ + ULONG RidCount; + ULONG Size; + + RidCount = *RtlSubAuthorityCountSid(OwnerSid); + Size = RtlLengthRequiredSid(RidCount); + + Owner->Owner = DispatchTable.AllocateLsaHeap(Size); + if (Owner->Owner == NULL) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyMemory(Owner->Owner, + OwnerSid, + Size); + + return STATUS_SUCCESS; +} + + +static +NTSTATUS +BuildTokenDefaultDacl(PTOKEN_DEFAULT_DACL DefaultDacl, + PSID OwnerSid) +{ + SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; + PSID LocalSystemSid = NULL; + PACL Dacl = NULL; + NTSTATUS Status = STATUS_SUCCESS; + + RtlAllocateAndInitializeSid(&SystemAuthority, + 1, + SECURITY_LOCAL_SYSTEM_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + SECURITY_NULL_RID, + &LocalSystemSid); + + Dacl = DispatchTable.AllocateLsaHeap(1024); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = RtlCreateAcl(Dacl, 1024, ACL_REVISION); + if (!NT_SUCCESS(Status)) + goto done; + + RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + GENERIC_ALL, + OwnerSid); + + /* SID: S-1-5-18 */ + RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + GENERIC_ALL, + LocalSystemSid); + + DefaultDacl->DefaultDacl = Dacl; + +done: + if (!NT_SUCCESS(Status)) + { + if (Dacl != NULL) + DispatchTable.FreeLsaHeap(Dacl); + } + + if (LocalSystemSid != NULL) + RtlFreeSid(LocalSystemSid); + + return Status; +} + + +static +NTSTATUS +BuildTokenInformationBuffer(PLSA_TOKEN_INFORMATION_V1 *TokenInformation, + PRPC_SID AccountDomainSid, + ULONG RelativeId, + PLUID LogonId) +{ + PLSA_TOKEN_INFORMATION_V1 Buffer = NULL; + PSID OwnerSid = NULL; + PSID PrimaryGroupSid = NULL; + ULONG i; + NTSTATUS Status = STATUS_SUCCESS; + + Buffer = DispatchTable.AllocateLsaHeap(sizeof(LSA_TOKEN_INFORMATION_V1)); + if (Buffer == NULL) + { + TRACE("Failed to allocate the local buffer!\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + /* FIXME: */ + Buffer->ExpirationTime.QuadPart = -1; + + Status = BuildTokenUser(&Buffer->User, + (PSID)AccountDomainSid, + RelativeId); + if (!NT_SUCCESS(Status)) + goto done; + + Status = BuildTokenGroups((PSID)AccountDomainSid, + LogonId, + &Buffer->Groups, + &PrimaryGroupSid, + &OwnerSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = BuildTokenPrimaryGroup(&Buffer->PrimaryGroup, + PrimaryGroupSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = BuildTokenPrivileges(&Buffer->Privileges); + if (!NT_SUCCESS(Status)) + goto done; + + Status = BuildTokenOwner(&Buffer->Owner, + OwnerSid); + if (!NT_SUCCESS(Status)) + goto done; + + Status = BuildTokenDefaultDacl(&Buffer->DefaultDacl, + OwnerSid); + if (!NT_SUCCESS(Status)) + goto done; + + *TokenInformation = Buffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (Buffer != NULL) + { + if (Buffer->User.User.Sid != NULL) + DispatchTable.FreeLsaHeap(Buffer->User.User.Sid); + + if (Buffer->Groups != NULL) + { + for (i = 0; i < Buffer->Groups->GroupCount; i++) + { + if (Buffer->Groups->Groups[i].Sid != NULL) + DispatchTable.FreeLsaHeap(Buffer->Groups->Groups[i].Sid); + } + + DispatchTable.FreeLsaHeap(Buffer->Groups); + } + + if (Buffer->PrimaryGroup.PrimaryGroup != NULL) + DispatchTable.FreeLsaHeap(Buffer->PrimaryGroup.PrimaryGroup); + + if (Buffer->Privileges != NULL) + DispatchTable.FreeLsaHeap(Buffer->Privileges); + + if (Buffer->Owner.Owner != NULL) + DispatchTable.FreeLsaHeap(Buffer->Owner.Owner); + + if (Buffer->DefaultDacl.DefaultDacl != NULL) + DispatchTable.FreeLsaHeap(Buffer->DefaultDacl.DefaultDacl); + + DispatchTable.FreeLsaHeap(Buffer); + } + } + + return Status; +} + + /* * @unimplemented */ @@ -504,7 +1021,34 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest, /* Return the token information type */ *TokenInformationType = LsaTokenInformationV1; + /* Build and fill the token information buffer */ + Status = BuildTokenInformationBuffer((PLSA_TOKEN_INFORMATION_V1*)TokenInformation, + AccountDomainSid, + RelativeIds.Element[0], + LogonId); + if (!NT_SUCCESS(Status)) + { + TRACE("BuildTokenInformationBuffer failed (Status %08lx)\n", Status); + goto done; + } + + *SubStatus = STATUS_SUCCESS; + done: + /* Return the account name */ + *AccountName = DispatchTable.AllocateLsaHeap(sizeof(UNICODE_STRING)); + if (*AccountName != NULL) + { + (*AccountName)->Buffer = DispatchTable.AllocateLsaHeap(LogonInfo->UserName.Length + + sizeof(UNICODE_NULL)); + if ((*AccountName)->Buffer != NULL) + { + (*AccountName)->MaximumLength = LogonInfo->UserName.Length + + sizeof(UNICODE_NULL); + RtlCopyUnicodeString(*AccountName, &LogonInfo->UserName); + } + } + if (!NT_SUCCESS(Status)) { if (*ProfileBuffer != NULL) diff --git a/reactos/dll/win32/msv1_0/msv1_0.h b/reactos/dll/win32/msv1_0/msv1_0.h index 5fabddfc282..46021d36b12 100644 --- a/reactos/dll/win32/msv1_0/msv1_0.h +++ b/reactos/dll/win32/msv1_0/msv1_0.h @@ -281,11 +281,16 @@ NTSTATUS WINAPI LsarClose(IN OUT LSAPR_HANDLE *ObjectHandle); +NTSTATUS +WINAPI +LsarLookupPrivilegeValue(IN LSAPR_HANDLE PolicyHandle, + IN PRPC_UNICODE_STRING Name, + OUT PLUID Value); + NTSTATUS WINAPI LsarQueryInformationPolicy(IN LSAPR_HANDLE PolicyHandle, IN POLICY_INFORMATION_CLASS InformationClass, OUT PLSAPR_POLICY_INFORMATION *PolicyInformation); - /* EOF */ From 6743a1174e0bba04f2c304f3dc077394c0f4697e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 5 May 2013 09:02:36 +0000 Subject: [PATCH 44/67] {RTL] - Implement RtlFillMemoryUlonglong - Add missing bitmap64.c - Fix 64bit bitmap code svn path=/trunk/; revision=58936 --- reactos/lib/rtl/bitmap.c | 40 ++++++++++++++++++++------------------ reactos/lib/rtl/bitmap64.c | 4 ++++ reactos/lib/rtl/mem.c | 19 ++++++++++++++++++ 3 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 reactos/lib/rtl/bitmap64.c diff --git a/reactos/lib/rtl/bitmap.c b/reactos/lib/rtl/bitmap.c index 02c6ef0f4f5..72790b4d99c 100644 --- a/reactos/lib/rtl/bitmap.c +++ b/reactos/lib/rtl/bitmap.c @@ -20,6 +20,7 @@ #ifdef USE_RTL_BITMAP64 #define _BITCOUNT 64 +#define MAXINDEX 0xFFFFFFFFFFFFFFFF typedef ULONG64 BITMAP_INDEX, *PBITMAP_INDEX; typedef ULONG64 BITMAP_BUFFER, *PBITMAP_BUFFER; #define RTL_BITMAP RTL_BITMAP64 @@ -55,6 +56,7 @@ typedef ULONG64 BITMAP_BUFFER, *PBITMAP_BUFFER; #define RtlFindLongestRunSet RtlFindLongestRunSet64 #else #define _BITCOUNT 32 +#define MAXINDEX 0xFFFFFFFF typedef ULONG BITMAP_INDEX, *PBITMAP_INDEX; typedef ULONG BITMAP_BUFFER, *PBITMAP_BUFFER; #endif @@ -312,8 +314,8 @@ RtlClearBits( /* Are we unaligned? */ if (Bits) { - /* Create an inverse mask by shifting MAXULONG */ - Mask = MAXULONG << Bits; + /* Create an inverse mask by shifting MAXINDEX */ + Mask = MAXINDEX << Bits; /* This is what's left in the first ULONG */ Bits = _BITCOUNT - Bits; @@ -346,7 +348,7 @@ RtlClearBits( /* Clear what's left */ NumberToClear &= (_BITCOUNT - 1); - Mask = MAXULONG << NumberToClear; + Mask = MAXINDEX << NumberToClear; *Buffer &= Mask; } @@ -369,8 +371,8 @@ RtlSetBits( /* Are we unaligned? */ if (Bits) { - /* Create a mask by shifting MAXULONG */ - Mask = MAXULONG << Bits; + /* Create a mask by shifting MAXINDEX */ + Mask = MAXINDEX << Bits; /* This is what's left in the first ULONG */ Bits = _BITCOUNT - Bits; @@ -398,12 +400,12 @@ RtlSetBits( } /* Set all full ULONGs */ - RtlFillMemoryUlong(Buffer, NumberToSet >> 3, MAXULONG); + RtlFillMemoryUlong(Buffer, NumberToSet >> 3, MAXINDEX); Buffer += NumberToSet / _BITCOUNT; /* Set what's left */ NumberToSet &= (_BITCOUNT - 1); - Mask = MAXULONG << NumberToSet; + Mask = MAXINDEX << NumberToSet; *Buffer |= ~Mask; } @@ -491,7 +493,7 @@ RtlFindClearBits( /* Check for valid parameters */ if (!BitMapHeader || NumberToFind > BitMapHeader->SizeOfBitMap) { - return MAXULONG; + return MAXINDEX; } /* Check if the hint is outside the bitmap */ @@ -517,7 +519,7 @@ retry: /* Search for the next clear run, by skipping a set run */ CurrentBit += RtlpGetLengthOfRunSet(BitMapHeader, CurrentBit, - MAXULONG); + MAXINDEX); /* Get length of the clear bit run */ CurrentLength = RtlpGetLengthOfRunClear(BitMapHeader, @@ -544,7 +546,7 @@ retry: } /* Nothing found */ - return MAXULONG; + return MAXINDEX; } BITMAP_INDEX @@ -559,7 +561,7 @@ RtlFindSetBits( /* Check for valid parameters */ if (!BitMapHeader || NumberToFind > BitMapHeader->SizeOfBitMap) { - return MAXULONG; + return MAXINDEX; } /* Check if the hint is outside the bitmap */ @@ -585,7 +587,7 @@ retry: /* Search for the next set run, by skipping a clear run */ CurrentBit += RtlpGetLengthOfRunClear(BitMapHeader, CurrentBit, - MAXULONG); + MAXINDEX); /* Get length of the set bit run */ CurrentLength = RtlpGetLengthOfRunSet(BitMapHeader, @@ -612,7 +614,7 @@ retry: } /* Nothing found */ - return MAXULONG; + return MAXINDEX; } BITMAP_INDEX @@ -628,7 +630,7 @@ RtlFindClearBitsAndSet( Position = RtlFindClearBits(BitMapHeader, NumberToFind, HintIndex); /* Did we get something? */ - if (Position != MAXULONG) + if (Position != MAXINDEX) { /* Yes, set the bits */ RtlSetBits(BitMapHeader, Position, NumberToFind); @@ -651,7 +653,7 @@ RtlFindSetBitsAndClear( Position = RtlFindSetBits(BitMapHeader, NumberToFind, HintIndex); /* Did we get something? */ - if (Position != MAXULONG) + if (Position != MAXINDEX) { /* Yes, clear the bits */ RtlClearBits(BitMapHeader, Position, NumberToFind); @@ -678,11 +680,11 @@ RtlFindNextForwardRunClear( } /* Assume a set run first, count it's length */ - Length = RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXULONG); + Length = RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXINDEX); *StartingRunIndex = FromIndex + Length; /* Now return the length of the run */ - return RtlpGetLengthOfRunClear(BitMapHeader, FromIndex + Length, MAXULONG); + return RtlpGetLengthOfRunClear(BitMapHeader, FromIndex + Length, MAXINDEX); } BITMAP_INDEX @@ -702,11 +704,11 @@ RtlFindNextForwardRunSet( } /* Assume a clear run first, count it's length */ - Length = RtlpGetLengthOfRunClear(BitMapHeader, FromIndex, MAXULONG); + Length = RtlpGetLengthOfRunClear(BitMapHeader, FromIndex, MAXINDEX); *StartingRunIndex = FromIndex + Length; /* Now return the length of the run */ - return RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXULONG); + return RtlpGetLengthOfRunSet(BitMapHeader, FromIndex, MAXINDEX); } BITMAP_INDEX diff --git a/reactos/lib/rtl/bitmap64.c b/reactos/lib/rtl/bitmap64.c new file mode 100644 index 00000000000..3e572f765ed --- /dev/null +++ b/reactos/lib/rtl/bitmap64.c @@ -0,0 +1,4 @@ + +#define USE_RTL_BITMAP64 + +#include "bitmap.c" diff --git a/reactos/lib/rtl/mem.c b/reactos/lib/rtl/mem.c index 3bbcf0d33b7..9869a898bc7 100644 --- a/reactos/lib/rtl/mem.c +++ b/reactos/lib/rtl/mem.c @@ -112,6 +112,25 @@ RtlFillMemoryUlong(PVOID Destination, } } +#ifdef _WIN64 +VOID +NTAPI +RtlFillMemoryUlonglong( + PVOID Destination, + SIZE_T Length, + ULONGLONG Fill) +{ + PULONGLONG Dest = Destination; + SIZE_T Count = Length / sizeof(ULONGLONG); + + while (Count > 0) + { + *Dest = Fill; + Dest++; + Count--; + } +} +#endif #undef RtlMoveMemory /* From d4c38c2fe4a85125b5627d026bd3cfe2f3dc37a5 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 09:30:12 +0000 Subject: [PATCH 45/67] [RTL] Implement RtlAcquirePrivilege and RtlReleasePrivilege. Reviewed by Aleksey svn path=/trunk/; revision=58937 --- reactos/lib/rtl/priv.c | 296 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 291 insertions(+), 5 deletions(-) diff --git a/reactos/lib/rtl/priv.c b/reactos/lib/rtl/priv.c index ebcf55f13cf..171e3ef5538 100644 --- a/reactos/lib/rtl/priv.c +++ b/reactos/lib/rtl/priv.c @@ -4,6 +4,7 @@ * FILE: lib/rtl/priv.c * PURPOSE: Security related functions and Security Objects * PROGRAMMER: Eric Kohl + * Pierre Schweitzer (pierre@reactos.org) */ /* INCLUDES *****************************************************************/ @@ -15,6 +16,27 @@ /* FUNCTIONS ***************************************************************/ +/* + * @implemented + */ +NTSTATUS +NTAPI +RtlpOpenThreadToken(IN ACCESS_MASK DesiredAccess, + OUT PHANDLE TokenHandle) +{ + NTSTATUS Status; + + Status = ZwOpenThreadToken(NtCurrentThread(), DesiredAccess, + TRUE, TokenHandle); + if (!NT_SUCCESS(Status)) + { + Status = ZwOpenThreadToken(NtCurrentThread(), DesiredAccess, + FALSE, TokenHandle); + } + + return Status; +} + /* * @implemented */ @@ -81,7 +103,7 @@ RtlImpersonateSelf(IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel) } /* - * @unimplemented + * @implemented */ NTSTATUS NTAPI @@ -90,18 +112,282 @@ RtlAcquirePrivilege(IN PULONG Privilege, IN ULONG Flags, OUT PVOID *ReturnedState) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + PRTL_ACQUIRE_STATE State; + ULONG ReturnLength, i, OldSize; + SECURITY_QUALITY_OF_SERVICE Sqos; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE ImpersonationToken = 0, ProcessToken; + + /* Validate flags */ + if (Flags & ~(RTL_ACQUIRE_PRIVILEGE_PROCESS | RTL_ACQUIRE_PRIVILEGE_IMPERSONATE)) + { + return STATUS_INVALID_PARAMETER; + } + + /* If user wants to acquire privileges for the process, we have to impersonate him */ + if (Flags & RTL_ACQUIRE_PRIVILEGE_PROCESS) + { + Flags |= RTL_ACQUIRE_PRIVILEGE_IMPERSONATE; + } + + /* Allocate enough memory to hold: old privileges (fixed buffer size, might not be enough) + * new privileges (big enough, after old privileges memory area) + */ + State = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(RTL_ACQUIRE_STATE) + sizeof(TOKEN_PRIVILEGES) + + NumPriv * sizeof(LUID_AND_ATTRIBUTES)); + if (!State) + { + return STATUS_NO_MEMORY; + } + + /* Only zero a bit of the memory (will be faster that way) */ + State->Token = 0; + State->OldImpersonationToken = 0; + State->Flags = 0; + State->OldPrivileges = NULL; + + /* Check whether we have already an active impersonation */ + if (NtCurrentTeb()->IsImpersonating) + { + /* Check whether we want to impersonate */ + if (Flags & RTL_ACQUIRE_PRIVILEGE_IMPERSONATE) + { + /* That's all fine, just get the token. + * We need access for: adjust (obvious...) but also + * query, to be able to query old privileges + */ + Status = RtlpOpenThreadToken(TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &State->Token); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, State); + return Status; + } + } + else + { + /* Otherwise, we have to temporary disable active impersonation. + * Get previous impersonation token to save it + */ + Status = RtlpOpenThreadToken(TOKEN_IMPERSONATE, &State->OldImpersonationToken); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, State); + return Status; + } + + /* Remember the fact we had an active impersonation */ + State->Flags |= RTL_ACQUIRE_PRIVILEGE_IMPERSONATE; + + /* Revert impersonation (ie, give 0 as handle) */ + Status = ZwSetInformationThread(NtCurrentThread(), + ThreadImpersonationToken, + &ImpersonationToken, + sizeof(HANDLE)); + } + } + + /* If we have no token yet (which is likely) */ + if (!State->Token) + { + /* If we are asked to use process, then do */ + if (Flags & RTL_ACQUIRE_PRIVILEGE_PROCESS) + { + Status = ZwOpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, + &State->Token); + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + } + else + { + /* Otherwise, we have to impersonate. + * Open token for duplication + */ + Status = ZwOpenProcessToken(NtCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken); + + InitializeObjectAttributes(&ObjectAttributes, + NULL, + 0, + NULL, + NULL); + + ObjectAttributes.SecurityQualityOfService = &Sqos; + Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); + Sqos.ImpersonationLevel = SecurityDelegation; + Sqos.ContextTrackingMode = 1; + Sqos.EffectiveOnly = FALSE; + + /* Duplicate */ + Status = ZwDuplicateToken(ProcessToken, + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_IMPERSONATE, + &ObjectAttributes, + FALSE, + TokenImpersonation, + &ImpersonationToken); + if (!NT_SUCCESS(Status)) + { + ZwClose(ProcessToken); + goto Cleanup; + } + + /* Assign our duplicated token to current thread */ + Status = ZwSetInformationThread(NtCurrentThread(), + ThreadImpersonationToken, + &ImpersonationToken, + sizeof(HANDLE)); + if (!NT_SUCCESS(Status)) + { + ZwClose(ImpersonationToken); + ZwClose(ProcessToken); + goto Cleanup; + } + + /* Save said token */ + State->Token = ImpersonationToken; + + ZwClose(ProcessToken); + } + } + + /* Properly set the privileges pointers: + * OldPrivileges points to the static memory in struct (= OldPrivBuffer) + * NewPrivileges points to the dynamic memory after OldPrivBuffer + * There's NO overflow risks (OldPrivileges is always used with its size) + */ + State->OldPrivileges = (PTOKEN_PRIVILEGES)State->OldPrivBuffer; + State->NewPrivileges = (PTOKEN_PRIVILEGES)(State->OldPrivBuffer + 1024); + + /* Assign all the privileges to be acquired */ + State->NewPrivileges->PrivilegeCount = NumPriv; + for (i = 0; i < NumPriv; ++i) + { + State->NewPrivileges->Privileges[i].Luid.LowPart = Privilege[i]; + State->NewPrivileges->Privileges[i].Luid.HighPart = 0; + State->NewPrivileges->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED; + } + + /* Start privileges adjustements */ + OldSize = sizeof(State->OldPrivBuffer); + do + { + ReturnLength = sizeof(State->OldPrivBuffer); + Status = ZwAdjustPrivilegesToken(State->Token, FALSE, State->NewPrivileges, + OldSize, State->OldPrivileges, &ReturnLength); + /* This is returned when OldPrivileges buffer is too small */ + if (Status == STATUS_BUFFER_TOO_SMALL) + { + /* Try to allocate a new one, big enough to hold data */ + State->OldPrivileges = RtlAllocateHeap(RtlGetProcessHeap(), 0, ReturnLength); + if (State->OldPrivileges) + { + OldSize = ReturnLength; + continue; + } + else + { + /* If we failed, properly set status: we failed because of the lack of memory */ + Status = STATUS_NO_MEMORY; + } + } + + /* If we failed to assign at least one privilege */ + if (Status == STATUS_NOT_ALL_ASSIGNED) + { + /* If there was actually only one privilege to acquire, use more accurate status */ + if (NumPriv == 1) + { + Status = STATUS_PRIVILEGE_NOT_HELD; + } + } + + /* Fail if needed, otherwise return our state to caller */ + if (!NT_SUCCESS(Status)) + { + goto Cleanup; + } + else + { + *ReturnedState = State; + } + } while (FALSE); + + return Status; + +Cleanup: + /* If we allocated our own buffer for old privileges, release it */ + if (State->OldPrivileges && (PVOID)State->OldPrivBuffer != (PVOID)State->OldPrivileges) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, State->OldPrivileges); + } + + /* Do we have to restore previously active impersonation? */ + if (State->Flags & RTL_ACQUIRE_PRIVILEGE_IMPERSONATE) + { + Status = ZwSetInformationThread(NtCurrentThread(), ThreadImpersonationToken, + &State->OldImpersonationToken, sizeof(HANDLE)); + /* If this ever happens, we're in a really bad situation... */ + if (!NT_SUCCESS(Status)) + { + RtlRaiseStatus(Status); + } + } + + /* Release token */ + if (State->Token) + { + ZwClose(State->Token); + } + + /* And free our state buffer */ + RtlFreeHeap(RtlGetProcessHeap(), 0, State); + + return Status; } /* - * @unimplemented + * @implemented */ VOID NTAPI RtlReleasePrivilege(IN PVOID ReturnedState) { - UNIMPLEMENTED; + NTSTATUS Status; + PRTL_ACQUIRE_STATE State = (PRTL_ACQUIRE_STATE)ReturnedState; + + /* If we had an active impersonation before we acquired privileges */ + if (State->Flags & RTL_ACQUIRE_PRIVILEGE_IMPERSONATE) + { + /* Restore it for the current thread */ + Status = ZwSetInformationThread(NtCurrentThread(), ThreadImpersonationToken, + &State->OldImpersonationToken, sizeof(HANDLE)); + if (!NT_SUCCESS(Status)) + { + RtlRaiseStatus(Status); + } + + /* And close the token if needed */ + if (State->OldImpersonationToken) + ZwClose(State->OldImpersonationToken); + } + else + { + /* Otherwise, restore old state */ + ZwAdjustPrivilegesToken(State->Token, FALSE, + State->OldPrivileges, 0, NULL, NULL); + + } + + /* If we used a different buffer for old privileges, just free it */ + if ((PVOID)State->OldPrivBuffer != (PVOID)State->OldPrivileges) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, State->OldPrivileges); + } + + /* Release token and free state */ + ZwClose(State->Token); + RtlFreeHeap(RtlGetProcessHeap(), 0, State); } /* From d41a8557a345128398f825c58b82b941779f81d5 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 09:55:32 +0000 Subject: [PATCH 46/67] [RTL] Comment out RtlAcquirePrivilege & RtlReleasePrivilege for the moment. It appears we are overflowing memory and thus corrupting registry, that breaks ReactOS install. To be investigated... svn path=/trunk/; revision=58938 --- reactos/lib/rtl/priv.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/reactos/lib/rtl/priv.c b/reactos/lib/rtl/priv.c index 171e3ef5538..8ca5a1d28f7 100644 --- a/reactos/lib/rtl/priv.c +++ b/reactos/lib/rtl/priv.c @@ -112,6 +112,7 @@ RtlAcquirePrivilege(IN PULONG Privilege, IN ULONG Flags, OUT PVOID *ReturnedState) { +#if 0 NTSTATUS Status; PRTL_ACQUIRE_STATE State; ULONG ReturnLength, i, OldSize; @@ -344,6 +345,10 @@ Cleanup: RtlFreeHeap(RtlGetProcessHeap(), 0, State); return Status; +#else + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +#endif } /* @@ -353,6 +358,7 @@ VOID NTAPI RtlReleasePrivilege(IN PVOID ReturnedState) { +#if 0 NTSTATUS Status; PRTL_ACQUIRE_STATE State = (PRTL_ACQUIRE_STATE)ReturnedState; @@ -388,6 +394,9 @@ RtlReleasePrivilege(IN PVOID ReturnedState) /* Release token and free state */ ZwClose(State->Token); RtlFreeHeap(RtlGetProcessHeap(), 0, State); +#else + UNIMPLEMENTED; +#endif } /* From 2cc6ced701a17e24ae87a07c2950eba2bc1190a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 5 May 2013 10:18:52 +0000 Subject: [PATCH 47/67] [CDMAKE] Reset the "volume expiration date" and the "volume effective date". They are not used. See http://wiki.osdev.org/ISO_9660#The_Primary_Volume_Descriptor for more information. svn path=/trunk/; revision=58939 --- reactos/tools/cdmake/cdmake.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reactos/tools/cdmake/cdmake.c b/reactos/tools/cdmake/cdmake.c index 751c588da68..fbe1a5bfac0 100644 --- a/reactos/tools/cdmake/cdmake.c +++ b/reactos/tools/cdmake/cdmake.c @@ -1165,9 +1165,9 @@ static void pass(void) write_byte(0); write_string(timestring); // most recent modification write_byte(0); - write_string(timestring); // volume expires + write_string("0000000000000000"); // volume expires write_byte(0); - write_string(timestring); // volume is effective + write_string("0000000000000000"); // volume is effective write_byte(0); write_byte(1); write_byte(0); @@ -1221,13 +1221,13 @@ static void pass(void) write_block(37, ' '); // abstract file identifier write_block(37, ' '); // bibliographic file identifier write_string(timestring); // volume creation - write_byte(48); + write_byte(0); write_string(timestring); // most recent modification - write_byte(48); - write_string(timestring); // volume expires - write_byte(48); - write_string(timestring); // volume is effective - write_byte(48); + write_byte(0); + write_string("0000000000000000"); // volume expires + write_byte(0); + write_string("0000000000000000"); // volume is effective + write_byte(0); write_byte(1); write_byte(0); fill_sector(); From 5cd67c3c362fe87f8629678b291d38b9d556d2b7 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sun, 5 May 2013 12:18:49 +0000 Subject: [PATCH 48/67] [KMTESTS:MM] - Fix 64-bit warnings. Patch by Nikolay Borisov. ROSTESTS-112 #resolve svn path=/trunk/; revision=58940 --- rostests/kmtests/ntos_mm/ZwAllocateVirtualMemory.c | 4 ++-- rostests/kmtests/ntos_mm/ZwCreateSection.c | 2 +- rostests/kmtests/ntos_mm/ZwMapViewOfSection.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rostests/kmtests/ntos_mm/ZwAllocateVirtualMemory.c b/rostests/kmtests/ntos_mm/ZwAllocateVirtualMemory.c index 01ae694b7db..d551ee200ba 100644 --- a/rostests/kmtests/ntos_mm/ZwAllocateVirtualMemory.c +++ b/rostests/kmtests/ntos_mm/ZwAllocateVirtualMemory.c @@ -14,14 +14,14 @@ /* These are being used in ZwMapViewOfSection as well */ const char TestString[] = "TheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedTheWhiteRabbitTheLongBrownFoxJumpedThe"; -const SIZE_T TestStringSize = sizeof(TestString); +const ULONG TestStringSize = sizeof(TestString); VOID Test_ZwAllocateVirtualMemory(VOID); typedef struct _TEST_CONTEXT { HANDLE ProcessHandle; - ULONG RegionSize; + SIZE_T RegionSize; ULONG AllocationType; ULONG Protect; PVOID Bases[1024]; diff --git a/rostests/kmtests/ntos_mm/ZwCreateSection.c b/rostests/kmtests/ntos_mm/ZwCreateSection.c index 4dbc75e2586..54f2dc796b2 100644 --- a/rostests/kmtests/ntos_mm/ZwCreateSection.c +++ b/rostests/kmtests/ntos_mm/ZwCreateSection.c @@ -11,7 +11,7 @@ #define NO_HANDLE_CLOSE -998 #define _4mb 4194304 extern const char TestString[]; -extern const SIZE_T TestStringSize; +extern const ULONG TestStringSize; static UNICODE_STRING FileReadOnlyPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll"); static UNICODE_STRING WritableFilePath = RTL_CONSTANT_STRING(L"\\SystemRoot\\kmtest-MmSection.txt"); static UNICODE_STRING CalcImgPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\calc.exe"); diff --git a/rostests/kmtests/ntos_mm/ZwMapViewOfSection.c b/rostests/kmtests/ntos_mm/ZwMapViewOfSection.c index 1350984a235..44f446f96ea 100644 --- a/rostests/kmtests/ntos_mm/ZwMapViewOfSection.c +++ b/rostests/kmtests/ntos_mm/ZwMapViewOfSection.c @@ -16,7 +16,7 @@ static UNICODE_STRING NtosImgPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32 static UNICODE_STRING WritableFilePath = RTL_CONSTANT_STRING(L"\\SystemRoot\\kmtest-MmSection.txt"); static UNICODE_STRING SharedSectionName = RTL_CONSTANT_STRING(L"\\BaseNamedObjects\\kmtest-SharedSection"); extern const char TestString[]; -extern const SIZE_T TestStringSize; +extern const ULONG TestStringSize; static OBJECT_ATTRIBUTES NtdllObject; static OBJECT_ATTRIBUTES KmtestFileObject; static OBJECT_ATTRIBUTES NtoskrnlFileObject; @@ -266,7 +266,7 @@ AdvancedErrorChecks(HANDLE FileHandleReadOnly, HANDLE FileHandleWriteOnly) static SIZE_T -CompareFileContents(HANDLE FileHandle, SIZE_T BufferLength, PVOID Buffer) +CompareFileContents(HANDLE FileHandle, ULONG BufferLength, PVOID Buffer) { NTSTATUS Status; LARGE_INTEGER ByteOffset; From c6f4a6973ada0024915245d85adf7615694c460d Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Sun, 5 May 2013 13:09:46 +0000 Subject: [PATCH 49/67] [FUSION] Remove baseaddress to fix address conflicts. Reenable creation of InstallRoot .NET key in its REG_SZ form. svn path=/trunk/; revision=58941 --- reactos/boot/bootdata/hivesft.inf | 5 +---- reactos/cmake/baseaddress.cmake | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/reactos/boot/bootdata/hivesft.inf b/reactos/boot/bootdata/hivesft.inf index 8c47bee7859..7f98ba10b14 100644 --- a/reactos/boot/bootdata/hivesft.inf +++ b/reactos/boot/bootdata/hivesft.inf @@ -69,9 +69,6 @@ HKLM,"SOFTWARE\Microsoft\Rpc\SecurityService","18",2,"secur32.dll" HKLM,"SOFTWARE\Microsoft\Rpc\SecurityService","68",2,"netlogon.dll" HKLM,"SOFTWARE\Microsoft\Rpc\SecurityService","9",2,"secur32.dll" -; .NET -HKLM,"SOFTWARE\Microsoft\.NETFramework\","InstallRoot",0x00020000,"%SystemRoot%\Microsoft .NET\Framework\" - HKLM,"SOFTWARE\Microsoft\Secure",,0x00000012 ; WBem @@ -115,7 +112,7 @@ HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions",,0x00000012 ; FIXME - usetup doesn't handle extra paths HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce","",0x00000000,"cmd /c md ""%programfiles%\Internet Explorer\"" && move %windir%\iexplore.exe ""%programfiles%\Internet Explorer\"" && ""%programfiles%\Internet Explorer\iexplore.exe"" /RegServer" ; Create .NET Framework InstallRoot key, reg_sz & full path -;HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce","InstallRoot.NET",0x00000000,"cmd /c reg add HKLM\SOFTWARE\Microsoft\.NETFramework /v InstallRoot /t REG_SZ /d %SystemRoot%\Microsoft.NET\Framework\" +HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce","InstallRoot.NET",0x00000000,"cmd /c reg add HKLM\SOFTWARE\Microsoft\.NETFramework /v InstallRoot /t REG_SZ /d %SystemRoot%\Microsoft.NET\Framework\" HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons",,0x00000012 HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu",,0x00000012 diff --git a/reactos/cmake/baseaddress.cmake b/reactos/cmake/baseaddress.cmake index e8061ea845b..df61a282b98 100644 --- a/reactos/cmake/baseaddress.cmake +++ b/reactos/cmake/baseaddress.cmake @@ -123,7 +123,8 @@ set(baseaddress_dxdiagn 0x74520000) set(baseaddress_faultrep 0x744f0000) set(baseaddress_fmifs 0x744d0000) set(baseaddress_fontext 0x744a0000) -set(baseaddress_fusion 0x74470000) +#fusion has to have dynamic address +#set(baseaddress_fusion 0x74470000) set(baseaddress_getuname 0x74440000) set(baseaddress_hhctrl 0x74400000) set(baseaddress_hlink 0x743c0000) From ed2e1fdfc91315004df88c9fd5bc51982647414d Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 5 May 2013 14:43:39 +0000 Subject: [PATCH 50/67] [LIBUSB] - Remove useless debug prints, which violate the spec - Fix identation CORE-7009 svn path=/trunk/; revision=58942 --- reactos/lib/drivers/libusb/hcd_controller.cpp | 9 --------- reactos/lib/drivers/libusb/hub_controller.cpp | 9 ++------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/reactos/lib/drivers/libusb/hcd_controller.cpp b/reactos/lib/drivers/libusb/hcd_controller.cpp index 0a70e2a448d..5662270cd7c 100644 --- a/reactos/lib/drivers/libusb/hcd_controller.cpp +++ b/reactos/lib/drivers/libusb/hcd_controller.cpp @@ -279,14 +279,6 @@ CHCDController::HandleDeviceControl( // it does // Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength); - - if (NT_SUCCESS(Status)) - { - // - // informal debug print - // - DPRINT1("[%s] Result %S\n", m_USBType, DriverKey->DriverKeyName); - } } // @@ -337,7 +329,6 @@ CHCDController::HandleDeviceControl( PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG) - sizeof(WCHAR) >= ResultLength); DriverKey->DriverKeyName[ResultLength / sizeof(WCHAR)] = L'\0'; - DPRINT1("[%s] Result %S\n", m_USBType, DriverKey->DriverKeyName); } // diff --git a/reactos/lib/drivers/libusb/hub_controller.cpp b/reactos/lib/drivers/libusb/hub_controller.cpp index d1e7df74593..fa90685ff75 100644 --- a/reactos/lib/drivers/libusb/hub_controller.cpp +++ b/reactos/lib/drivers/libusb/hub_controller.cpp @@ -476,8 +476,6 @@ CHubController::HandlePnp( swprintf(Buffer, L"USB\\ROOT_HUB"); } - DPRINT("Name %S\n", Buffer); - // // calculate length // @@ -549,11 +547,8 @@ CHubController::HandlePnp( Index += swprintf(&Buffer[Index], L"USB\\ROOT_HUB") + 1; } - Buffer[Index] = UNICODE_NULL; - Index++; - - - DPRINT1("[%s] Name %S\n", m_USBType, Buffer); + Buffer[Index] = UNICODE_NULL; + Index++; // // allocate buffer From bf9fa8056be77c1ce2a5ecb1a06bd77c6a8ce540 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 5 May 2013 14:51:27 +0000 Subject: [PATCH 51/67] [HID] - Fix bug in irp completion handler CORE-7069 svn path=/trunk/; revision=58943 --- reactos/drivers/hid/hidclass/hidclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/drivers/hid/hidclass/hidclass.c b/reactos/drivers/hid/hidclass/hidclass.c index c687e840599..af30050276d 100644 --- a/reactos/drivers/hid/hidclass/hidclass.c +++ b/reactos/drivers/hid/hidclass/hidclass.c @@ -458,7 +458,7 @@ HidClass_ReadCompleteIrp( // copy result status // IrpContext->OriginalIrp->IoStatus.Status = Irp->IoStatus.Status; - Irp->IoStatus.Information = Irp->IoStatus.Information; + IrpContext->OriginalIrp->IoStatus.Information = Irp->IoStatus.Information; // // free input report buffer From 5d4c6981e0d34e25b74f30fcf0991611bc086b4c Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sun, 5 May 2013 15:04:49 +0000 Subject: [PATCH 52/67] [HIDCLASS] - Don't return inconsistent status values from HidClass_DeviceControl svn path=/trunk/; revision=58944 --- reactos/drivers/hid/hidclass/hidclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/drivers/hid/hidclass/hidclass.c b/reactos/drivers/hid/hidclass/hidclass.c index af30050276d..7f241520a13 100644 --- a/reactos/drivers/hid/hidclass/hidclass.c +++ b/reactos/drivers/hid/hidclass/hidclass.c @@ -864,7 +864,7 @@ HidClass_DeviceControl( // invalid request // DPRINT1("[HIDCLASS] DeviceControl Irp for FDO arrived\n"); - Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Status = STATUS_INVALID_PARAMETER_1; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INVALID_PARAMETER_1; } From 3c4b46ea6248dbeeb6b3b5e82f80bb3572e50bff Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 16:38:41 +0000 Subject: [PATCH 53/67] [KERNEL32] If you workaround RtlAcquirePrivilege, do it properly! Will prevent bad address freeing... svn path=/trunk/; revision=58945 --- reactos/dll/win32/kernel32/client/time.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/kernel32/client/time.c b/reactos/dll/win32/kernel32/client/time.c index 44516d4b6ee..1302d3ca068 100644 --- a/reactos/dll/win32/kernel32/client/time.c +++ b/reactos/dll/win32/kernel32/client/time.c @@ -379,12 +379,16 @@ SetLocalTime(IN CONST SYSTEMTIME *lpSystemTime) NewSystemTime.QuadPart += TimeZoneBias.QuadPart; Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State); - Status = STATUS_SUCCESS; if (NT_SUCCESS(Status)) { Status = NtSetSystemTime(&NewSystemTime, NULL); RtlReleasePrivilege(State); } + else + { + DPRINT1("Workaround RtlAcquirePrivilege failure!\n"); + Status = NtSetSystemTime(&NewSystemTime, NULL); + } if (!NT_SUCCESS(Status)) { From f96e0193f45cc6c0c8292e517c530321f791b7df Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 17:32:00 +0000 Subject: [PATCH 54/67] [RTL] Add a few DPRINTs. Fix a bug where last status was overrided in case of failure. Still commented out... svn path=/trunk/; revision=58946 --- reactos/lib/rtl/priv.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/reactos/lib/rtl/priv.c b/reactos/lib/rtl/priv.c index 8ca5a1d28f7..286b2b2ceda 100644 --- a/reactos/lib/rtl/priv.c +++ b/reactos/lib/rtl/priv.c @@ -113,13 +113,15 @@ RtlAcquirePrivilege(IN PULONG Privilege, OUT PVOID *ReturnedState) { #if 0 - NTSTATUS Status; PRTL_ACQUIRE_STATE State; + NTSTATUS Status, IntStatus; ULONG ReturnLength, i, OldSize; SECURITY_QUALITY_OF_SERVICE Sqos; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE ImpersonationToken = 0, ProcessToken; + DPRINT("RtlAcquirePrivilege(%p, %u, %u, %p)\n", Privilege, NumPriv, Flags, ReturnedState); + /* Validate flags */ if (Flags & ~(RTL_ACQUIRE_PRIVILEGE_PROCESS | RTL_ACQUIRE_PRIVILEGE_IMPERSONATE)) { @@ -283,6 +285,7 @@ RtlAcquirePrivilege(IN PULONG Privilege, State->OldPrivileges = RtlAllocateHeap(RtlGetProcessHeap(), 0, ReturnLength); if (State->OldPrivileges) { + DPRINT("Allocated old privileges: %p\n", State->OldPrivileges); OldSize = ReturnLength; continue; } @@ -314,6 +317,8 @@ RtlAcquirePrivilege(IN PULONG Privilege, } } while (FALSE); + DPRINT("RtlAcquirePrivilege succeed!\n"); + return Status; Cleanup: @@ -326,12 +331,12 @@ Cleanup: /* Do we have to restore previously active impersonation? */ if (State->Flags & RTL_ACQUIRE_PRIVILEGE_IMPERSONATE) { - Status = ZwSetInformationThread(NtCurrentThread(), ThreadImpersonationToken, - &State->OldImpersonationToken, sizeof(HANDLE)); + IntStatus = ZwSetInformationThread(NtCurrentThread(), ThreadImpersonationToken, + &State->OldImpersonationToken, sizeof(HANDLE)); /* If this ever happens, we're in a really bad situation... */ - if (!NT_SUCCESS(Status)) + if (!NT_SUCCESS(IntStatus)) { - RtlRaiseStatus(Status); + RtlRaiseStatus(IntStatus); } } @@ -344,6 +349,8 @@ Cleanup: /* And free our state buffer */ RtlFreeHeap(RtlGetProcessHeap(), 0, State); + DPRINT("RtlAcquirePrivilege() failed with status: %lx\n", Status); + return Status; #else UNIMPLEMENTED; @@ -362,6 +369,8 @@ RtlReleasePrivilege(IN PVOID ReturnedState) NTSTATUS Status; PRTL_ACQUIRE_STATE State = (PRTL_ACQUIRE_STATE)ReturnedState; + DPRINT("RtlReleasePrivilege(%p)\n", ReturnedState); + /* If we had an active impersonation before we acquired privileges */ if (State->Flags & RTL_ACQUIRE_PRIVILEGE_IMPERSONATE) { @@ -388,6 +397,7 @@ RtlReleasePrivilege(IN PVOID ReturnedState) /* If we used a different buffer for old privileges, just free it */ if ((PVOID)State->OldPrivBuffer != (PVOID)State->OldPrivileges) { + DPRINT("Releasing old privileges: %p\n", State->OldPrivileges); RtlFreeHeap(RtlGetProcessHeap(), 0, State->OldPrivileges); } From 9818ea06e5fefb4154e9c557ffa12b715695206e Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 19:24:25 +0000 Subject: [PATCH 55/67] [RTL] Don't allocate an extra privilege entry when not required. Still doesn't fix issue. svn path=/trunk/; revision=58949 --- reactos/lib/rtl/priv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/lib/rtl/priv.c b/reactos/lib/rtl/priv.c index 286b2b2ceda..5a047cc4a3f 100644 --- a/reactos/lib/rtl/priv.c +++ b/reactos/lib/rtl/priv.c @@ -11,7 +11,7 @@ #include -#define NDEBUG +//#define NDEBUG #include /* FUNCTIONS ***************************************************************/ @@ -138,7 +138,7 @@ RtlAcquirePrivilege(IN PULONG Privilege, * new privileges (big enough, after old privileges memory area) */ State = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(RTL_ACQUIRE_STATE) + sizeof(TOKEN_PRIVILEGES) + - NumPriv * sizeof(LUID_AND_ATTRIBUTES)); + (NumPriv - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES)); if (!State) { return STATUS_NO_MEMORY; From 648e8504fc7fd8eb1184fceaf73d71a4f73e6c59 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 20:01:14 +0000 Subject: [PATCH 56/67] [KERNEL32] Also "fix" hack of RtlAcquirePrivilege in SetSystemTime(). Spotted by Thomas. Note for syssetup/rtl/kernel32 devs: Make it crystal clear that this is a hack and has to be deleted once RAP is fine. Also note that for SetLocalTime() and 2nd stage, syssetup acquires the privilege itself in SetSystemLocalTime() before calling SetLocalTime(). This will also have to be deleted once RAP is working fine. Otherwise it will keep failing: it is not possible to acquire a privilege already held. svn path=/trunk/; revision=58953 --- reactos/dll/win32/kernel32/client/time.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/time.c b/reactos/dll/win32/kernel32/client/time.c index 1302d3ca068..c9669fa5d30 100644 --- a/reactos/dll/win32/kernel32/client/time.c +++ b/reactos/dll/win32/kernel32/client/time.c @@ -386,7 +386,7 @@ SetLocalTime(IN CONST SYSTEMTIME *lpSystemTime) } else { - DPRINT1("Workaround RtlAcquirePrivilege failure!\n"); + DPRINT1("HACK: Workaround RtlAcquirePrivilege failure! Remove me once RAP is fine\n"); Status = NtSetSystemTime(&NewSystemTime, NULL); } @@ -427,12 +427,16 @@ SetSystemTime(IN CONST SYSTEMTIME *lpSystemTime) } Status = RtlAcquirePrivilege(&Privilege, 1, 0, &State); - Status = STATUS_SUCCESS; if (NT_SUCCESS(Status)) { Status = NtSetSystemTime(&NewSystemTime, NULL); RtlReleasePrivilege(State); } + else + { + DPRINT1("HACK: Workaround RtlAcquirePrivilege failure! Remove me once RAP is fine\n"); + Status = NtSetSystemTime(&NewSystemTime, NULL); + } if (!NT_SUCCESS(Status)) { From a330845fa1965ff4d5d0853be3b929e896ab51a6 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 20:19:23 +0000 Subject: [PATCH 57/67] [RTL] Properly define the loop for privileges adjustement. Spotted & fixed by Thomas. svn path=/trunk/; revision=58955 --- reactos/lib/rtl/priv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/lib/rtl/priv.c b/reactos/lib/rtl/priv.c index 5a047cc4a3f..9b9bfb80ce9 100644 --- a/reactos/lib/rtl/priv.c +++ b/reactos/lib/rtl/priv.c @@ -314,8 +314,9 @@ RtlAcquirePrivilege(IN PULONG Privilege, else { *ReturnedState = State; + break; } - } while (FALSE); + } while (TRUE); DPRINT("RtlAcquirePrivilege succeed!\n"); From be5914df2fa2d7235c14ab45dfda341dfe621aae Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 22:19:54 +0000 Subject: [PATCH 58/67] [RTL] When we are impersonating, also set the flag, so that on release, we can kill it. This hopefully fixes 2nd stage and the whole mess it was causing in privileges. svn path=/trunk/; revision=58959 --- reactos/lib/rtl/priv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reactos/lib/rtl/priv.c b/reactos/lib/rtl/priv.c index 9b9bfb80ce9..5021966d45c 100644 --- a/reactos/lib/rtl/priv.c +++ b/reactos/lib/rtl/priv.c @@ -247,8 +247,9 @@ RtlAcquirePrivilege(IN PULONG Privilege, goto Cleanup; } - /* Save said token */ + /* Save said token and the fact we have impersonated */ State->Token = ImpersonationToken; + State->Flags |= RTL_ACQUIRE_PRIVILEGE_IMPERSONATE; ZwClose(ProcessToken); } @@ -372,7 +373,9 @@ RtlReleasePrivilege(IN PVOID ReturnedState) DPRINT("RtlReleasePrivilege(%p)\n", ReturnedState); - /* If we had an active impersonation before we acquired privileges */ + /* If we had an active impersonation before we acquired privileges + * Or if we have impersonated, quit it + */ if (State->Flags & RTL_ACQUIRE_PRIVILEGE_IMPERSONATE) { /* Restore it for the current thread */ From 567881b5938047663f74b09bc1b521755ca665e3 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sun, 5 May 2013 22:31:17 +0000 Subject: [PATCH 59/67] [RTL] Finally reenable RtlAcquirePrivilege and RtlReleasePrivilege now that they are fixed. [KERNEL32] Remove the hacks in SetSystemTime() and SetLocalTime() now that RtlAcquirePrivilege is working properly. [SYSSETUP] Remove the hack for privileges in SetSystemLocalTime() now that SetLocalTime() can properly acquire needed privilege. CORE-7168 #comment Fixed with r58960 #resolve svn path=/trunk/; revision=58960 --- reactos/dll/win32/kernel32/client/time.c | 10 ----- reactos/dll/win32/syssetup/wizard.c | 50 ++---------------------- reactos/lib/rtl/priv.c | 11 +----- 3 files changed, 4 insertions(+), 67 deletions(-) diff --git a/reactos/dll/win32/kernel32/client/time.c b/reactos/dll/win32/kernel32/client/time.c index c9669fa5d30..8a6835cb8d5 100644 --- a/reactos/dll/win32/kernel32/client/time.c +++ b/reactos/dll/win32/kernel32/client/time.c @@ -384,11 +384,6 @@ SetLocalTime(IN CONST SYSTEMTIME *lpSystemTime) Status = NtSetSystemTime(&NewSystemTime, NULL); RtlReleasePrivilege(State); } - else - { - DPRINT1("HACK: Workaround RtlAcquirePrivilege failure! Remove me once RAP is fine\n"); - Status = NtSetSystemTime(&NewSystemTime, NULL); - } if (!NT_SUCCESS(Status)) { @@ -432,11 +427,6 @@ SetSystemTime(IN CONST SYSTEMTIME *lpSystemTime) Status = NtSetSystemTime(&NewSystemTime, NULL); RtlReleasePrivilege(State); } - else - { - DPRINT1("HACK: Workaround RtlAcquirePrivilege failure! Remove me once RAP is fine\n"); - Status = NtSetSystemTime(&NewSystemTime, NULL); - } if (!NT_SUCCESS(Status)) { diff --git a/reactos/dll/win32/syssetup/wizard.c b/reactos/dll/win32/syssetup/wizard.c index f1caf2ac4a7..ff181e34bce 100644 --- a/reactos/dll/win32/syssetup/wizard.c +++ b/reactos/dll/win32/syssetup/wizard.c @@ -1374,57 +1374,13 @@ SetAutoDaylightInfo(HWND hwnd) static BOOL SetSystemLocalTime(HWND hwnd, PSETUPDATA SetupData) { - HANDLE hToken; - DWORD PrevSize; - TOKEN_PRIVILEGES priv, previouspriv; BOOL Ret = FALSE; /* - * enable the SeSystemtimePrivilege privilege + * Call SetLocalTime twice to ensure correct results */ - - if(OpenProcessToken(GetCurrentProcess(), - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, - &hToken)) - { - priv.PrivilegeCount = 1; - priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - if(LookupPrivilegeValue(NULL, - SE_SYSTEMTIME_NAME, - &priv.Privileges[0].Luid)) - { - if(AdjustTokenPrivileges(hToken, - FALSE, - &priv, - sizeof(previouspriv), - &previouspriv, - &PrevSize) && - GetLastError() == ERROR_SUCCESS) - { - /* - * We successfully enabled it, we're permitted to change the system time - * Call SetLocalTime twice to ensure correct results - */ - Ret = SetLocalTime(&SetupData->SystemTime) && - SetLocalTime(&SetupData->SystemTime); - - /* - * for the sake of security, restore the previous status again - */ - if(previouspriv.PrivilegeCount > 0) - { - AdjustTokenPrivileges(hToken, - FALSE, - &previouspriv, - 0, - NULL, - 0); - } - } - } - CloseHandle(hToken); - } + Ret = SetLocalTime(&SetupData->SystemTime) && + SetLocalTime(&SetupData->SystemTime); return Ret; } diff --git a/reactos/lib/rtl/priv.c b/reactos/lib/rtl/priv.c index 5021966d45c..5d925af85bb 100644 --- a/reactos/lib/rtl/priv.c +++ b/reactos/lib/rtl/priv.c @@ -11,7 +11,7 @@ #include -//#define NDEBUG +#define NDEBUG #include /* FUNCTIONS ***************************************************************/ @@ -112,7 +112,6 @@ RtlAcquirePrivilege(IN PULONG Privilege, IN ULONG Flags, OUT PVOID *ReturnedState) { -#if 0 PRTL_ACQUIRE_STATE State; NTSTATUS Status, IntStatus; ULONG ReturnLength, i, OldSize; @@ -354,10 +353,6 @@ Cleanup: DPRINT("RtlAcquirePrivilege() failed with status: %lx\n", Status); return Status; -#else - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -#endif } /* @@ -367,7 +362,6 @@ VOID NTAPI RtlReleasePrivilege(IN PVOID ReturnedState) { -#if 0 NTSTATUS Status; PRTL_ACQUIRE_STATE State = (PRTL_ACQUIRE_STATE)ReturnedState; @@ -408,9 +402,6 @@ RtlReleasePrivilege(IN PVOID ReturnedState) /* Release token and free state */ ZwClose(State->Token); RtlFreeHeap(RtlGetProcessHeap(), 0, State); -#else - UNIMPLEMENTED; -#endif } /* From c97cdd5dd974adfad37064a1e53610959cc7d096 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Mon, 6 May 2013 08:10:53 +0000 Subject: [PATCH 60/67] [KMTESTS:FSRTL] Add more tests for MCBs svn path=/trunk/; revision=58961 --- rostests/kmtests/ntos_fsrtl/FsRtlMcb.c | 93 ++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/rostests/kmtests/ntos_fsrtl/FsRtlMcb.c b/rostests/kmtests/ntos_fsrtl/FsRtlMcb.c index 8041fc247f2..8d0e22c3a11 100644 --- a/rostests/kmtests/ntos_fsrtl/FsRtlMcb.c +++ b/rostests/kmtests/ntos_fsrtl/FsRtlMcb.c @@ -141,6 +141,99 @@ static VOID FsRtlLargeMcbTest() ok(Index == 1, "Expected Index 1, got: %lu\n", Index); FsRtlUninitializeLargeMcb(&LargeMcb); + + FsRtlInitializeLargeMcb(&LargeMcb, PagedPool); + NbRuns = FsRtlNumberOfRunsInLargeMcb(&LargeMcb); + ok(NbRuns == 0, "Expected 0 runs, got: %lu\n", NbRuns); + + ok(FsRtlAddLargeMcbEntry(&LargeMcb, 1024, 1024, 1024) == TRUE, "expected TRUE, got FALSE\n"); + ok(FsRtlAddLargeMcbEntry(&LargeMcb, 3072, 3072, 1024) == TRUE, "expected TRUE, got FALSE\n"); + ok(FsRtlAddLargeMcbEntry(&LargeMcb, 5120, 5120, 1024) == TRUE, "expected TRUE, got FALSE\n"); + + NbRuns = FsRtlNumberOfRunsInLargeMcb(&LargeMcb); + ok(NbRuns == 6, "Expected 6 runs, got: %lu\n", NbRuns); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 0, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 0, "Expected Vbn 0, got: %I64d\n", Vbn); + ok(Lbn == -1, "Expected Lbn -1, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 1, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 1024, "Expected Vbn 1024, got: %I64d\n", Vbn); + ok(Lbn == 1024, "Expected Lbn 1024, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 2, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 2048, "Expected Vbn 2048, got: %I64d\n", Vbn); + ok(Lbn == -1, "Expected Lbn -1, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 3, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 3072, "Expected Vbn 3072, got: %I64d\n", Vbn); + ok(Lbn == 3072, "Expected Lbn 3072, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 4, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 4096, "Expected Vbn 4096, got: %I64d\n", Vbn); + ok(Lbn == -1, "Expected Lbn -1, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 5, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 5120, "Expected Vbn 5120, got: %I64d\n", Vbn); + ok(Lbn == 5120, "Expected Lbn 5120, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlAddLargeMcbEntry(&LargeMcb, 0, 0, 1024) == TRUE, "expected TRUE, got FALSE\n"); + + NbRuns = FsRtlNumberOfRunsInLargeMcb(&LargeMcb); + ok(NbRuns == 4, "Expected 4 runs, got: %lu\n", NbRuns); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 0, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 0, "Expected Vbn 0, got: %I64d\n", Vbn); + ok(Lbn == -1, "Expected Lbn -1, got: %I64d\n", Lbn); + ok(SectorCount == 3072, "Expected SectorCount 3072, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 1, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 3072, "Expected Vbn 3072, got: %I64d\n", Vbn); + ok(Lbn == 3072, "Expected Lbn 3072, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 2, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 4096, "Expected Vbn 4096, got: %I64d\n", Vbn); + ok(Lbn == -1, "Expected Lbn -1, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 3, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 5120, "Expected Vbn 5120, got: %I64d\n", Vbn); + ok(Lbn == 5120, "Expected Lbn 5120, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlAddLargeMcbEntry(&LargeMcb, 4608, 4608, 1024) == TRUE, "expected TRUE, got FALSE\n"); + + NbRuns = FsRtlNumberOfRunsInLargeMcb(&LargeMcb); + ok(NbRuns == 4, "Expected 4 runs, got: %lu\n", NbRuns); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 0, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 0, "Expected Vbn 0, got: %I64d\n", Vbn); + ok(Lbn == -1, "Expected Lbn -1, got: %I64d\n", Lbn); + ok(SectorCount == 3072, "Expected SectorCount 3072, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 1, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 3072, "Expected Vbn 3072, got: %I64d\n", Vbn); + ok(Lbn == 3072, "Expected Lbn 3072, got: %I64d\n", Lbn); + ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 2, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 4096, "Expected Vbn 4096, got: %I64d\n", Vbn); + ok(Lbn == -1, "Expected Lbn -1, got: %I64d\n", Lbn); + ok(SectorCount == 512, "Expected SectorCount 512, got: %I64d\n", SectorCount); + + ok(FsRtlGetNextLargeMcbEntry(&LargeMcb, 3, &Vbn, &Lbn, &SectorCount) == TRUE, "expected TRUE, got FALSE\n"); + ok(Vbn == 4608, "Expected Vbn 4608, got: %I64d\n", Vbn); + ok(Lbn == 4608, "Expected Lbn 4608, got: %I64d\n", Lbn); + ok(SectorCount == 1536, "Expected SectorCount 1536, got: %I64d\n", SectorCount); + + FsRtlUninitializeLargeMcb(&LargeMcb); } START_TEST(FsRtlMcb) From bfe3492dc490ebda2e1feb2dde2d254d4e256dc9 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Mon, 6 May 2013 11:24:55 +0000 Subject: [PATCH 61/67] [KMTESTS:FSRTL] Add comments svn path=/trunk/; revision=58962 --- rostests/kmtests/ntos_fsrtl/FsRtlMcb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rostests/kmtests/ntos_fsrtl/FsRtlMcb.c b/rostests/kmtests/ntos_fsrtl/FsRtlMcb.c index 8d0e22c3a11..8638bdaf514 100644 --- a/rostests/kmtests/ntos_fsrtl/FsRtlMcb.c +++ b/rostests/kmtests/ntos_fsrtl/FsRtlMcb.c @@ -146,6 +146,10 @@ static VOID FsRtlLargeMcbTest() NbRuns = FsRtlNumberOfRunsInLargeMcb(&LargeMcb); ok(NbRuns == 0, "Expected 0 runs, got: %lu\n", NbRuns); + /* Create a mapping with three holes between each mapping + * It looks like that: + * ----//////-----/////-----/////// + */ ok(FsRtlAddLargeMcbEntry(&LargeMcb, 1024, 1024, 1024) == TRUE, "expected TRUE, got FALSE\n"); ok(FsRtlAddLargeMcbEntry(&LargeMcb, 3072, 3072, 1024) == TRUE, "expected TRUE, got FALSE\n"); ok(FsRtlAddLargeMcbEntry(&LargeMcb, 5120, 5120, 1024) == TRUE, "expected TRUE, got FALSE\n"); @@ -183,6 +187,7 @@ static VOID FsRtlLargeMcbTest() ok(Lbn == 5120, "Expected Lbn 5120, got: %I64d\n", Lbn); ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + /* Fill first hole */ ok(FsRtlAddLargeMcbEntry(&LargeMcb, 0, 0, 1024) == TRUE, "expected TRUE, got FALSE\n"); NbRuns = FsRtlNumberOfRunsInLargeMcb(&LargeMcb); @@ -208,6 +213,7 @@ static VOID FsRtlLargeMcbTest() ok(Lbn == 5120, "Expected Lbn 5120, got: %I64d\n", Lbn); ok(SectorCount == 1024, "Expected SectorCount 1024, got: %I64d\n", SectorCount); + /* Fill half of the last hole and overlap */ ok(FsRtlAddLargeMcbEntry(&LargeMcb, 4608, 4608, 1024) == TRUE, "expected TRUE, got FALSE\n"); NbRuns = FsRtlNumberOfRunsInLargeMcb(&LargeMcb); From c1d4f2f390de260bd35e4092a63cc13e5b964a9c Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 6 May 2013 21:43:03 +0000 Subject: [PATCH 62/67] [MSGINA] Convert tabs to spaces. No code changes! svn path=/trunk/; revision=58963 --- reactos/dll/win32/msgina/gui.c | 734 +++++++++++----------- reactos/dll/win32/msgina/msgina.c | 974 +++++++++++++++--------------- reactos/dll/win32/msgina/msgina.h | 58 +- reactos/dll/win32/msgina/stubs.c | 100 +-- reactos/dll/win32/msgina/tui.c | 356 +++++------ 5 files changed, 1111 insertions(+), 1111 deletions(-) diff --git a/reactos/dll/win32/msgina/gui.c b/reactos/dll/win32/msgina/gui.c index 99c3a61c809..a8e28974f9f 100644 --- a/reactos/dll/win32/msgina/gui.c +++ b/reactos/dll/win32/msgina/gui.c @@ -11,222 +11,222 @@ WINE_DEFAULT_DEBUG_CHANNEL(msgina); typedef struct _DISPLAYSTATUSMSG { - PGINA_CONTEXT Context; - HDESK hDesktop; - DWORD dwOptions; - PWSTR pTitle; - PWSTR pMessage; - HANDLE StartupEvent; + PGINA_CONTEXT Context; + HDESK hDesktop; + DWORD dwOptions; + PWSTR pTitle; + PWSTR pMessage; + HANDLE StartupEvent; } DISPLAYSTATUSMSG, *PDISPLAYSTATUSMSG; static BOOL GUIInitialize( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - TRACE("GUIInitialize(%p)\n", pgContext); - return TRUE; + TRACE("GUIInitialize(%p)\n", pgContext); + return TRUE; } static INT_PTR CALLBACK StatusMessageWindowProc( - IN HWND hwndDlg, - IN UINT uMsg, - IN WPARAM wParam, - IN LPARAM lParam) + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) { - UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(wParam); - switch (uMsg) - { - case WM_INITDIALOG: - { - PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam; - if (!msg) - return FALSE; + switch (uMsg) + { + case WM_INITDIALOG: + { + PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lParam; + if (!msg) + return FALSE; - msg->Context->hStatusWindow = hwndDlg; + msg->Context->hStatusWindow = hwndDlg; - if (msg->pTitle) - SetWindowTextW(hwndDlg, msg->pTitle); - SetDlgItemTextW(hwndDlg, IDC_STATUSLABEL, msg->pMessage); - SetEvent(msg->StartupEvent); - return TRUE; - } - } - return FALSE; + if (msg->pTitle) + SetWindowTextW(hwndDlg, msg->pTitle); + SetDlgItemTextW(hwndDlg, IDC_STATUSLABEL, msg->pMessage); + SetEvent(msg->StartupEvent); + return TRUE; + } + } + return FALSE; } static DWORD WINAPI StartupWindowThread(LPVOID lpParam) { - HDESK hDesk; - PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam; + HDESK hDesk; + PDISPLAYSTATUSMSG msg = (PDISPLAYSTATUSMSG)lpParam; - /* When SetThreadDesktop is called the system closes the desktop handle when needed - so we have to create a new handle because this handle may still be in use by winlogon */ - if (!DuplicateHandle ( GetCurrentProcess(), - msg->hDesktop, - GetCurrentProcess(), - (HANDLE*)&hDesk, - 0, - FALSE, - DUPLICATE_SAME_ACCESS)) - { - HeapFree(GetProcessHeap(), 0, lpParam); - return FALSE; - } + /* When SetThreadDesktop is called the system closes the desktop handle when needed + so we have to create a new handle because this handle may still be in use by winlogon */ + if (!DuplicateHandle ( GetCurrentProcess(), + msg->hDesktop, + GetCurrentProcess(), + (HANDLE*)&hDesk, + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) + { + HeapFree(GetProcessHeap(), 0, lpParam); + return FALSE; + } - if(!SetThreadDesktop(hDesk)) - { - HeapFree(GetProcessHeap(), 0, lpParam); - return FALSE; - } + if(!SetThreadDesktop(hDesk)) + { + HeapFree(GetProcessHeap(), 0, lpParam); + return FALSE; + } - DialogBoxParam( - hDllInstance, - MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG), - GetDesktopWindow(), - StatusMessageWindowProc, - (LPARAM)lpParam); + DialogBoxParam( + hDllInstance, + MAKEINTRESOURCE(IDD_STATUSWINDOW_DLG), + GetDesktopWindow(), + StatusMessageWindowProc, + (LPARAM)lpParam); - HeapFree(GetProcessHeap(), 0, lpParam); - return TRUE; + HeapFree(GetProcessHeap(), 0, lpParam); + return TRUE; } static BOOL GUIDisplayStatusMessage( - IN PGINA_CONTEXT pgContext, - IN HDESK hDesktop, - IN DWORD dwOptions, - IN PWSTR pTitle, - IN PWSTR pMessage) + IN PGINA_CONTEXT pgContext, + IN HDESK hDesktop, + IN DWORD dwOptions, + IN PWSTR pTitle, + IN PWSTR pMessage) { - PDISPLAYSTATUSMSG msg; - HANDLE Thread; - DWORD ThreadId; + PDISPLAYSTATUSMSG msg; + HANDLE Thread; + DWORD ThreadId; - TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage); + TRACE("GUIDisplayStatusMessage(%ws)\n", pMessage); - if (!pgContext->hStatusWindow) - { - msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG)); - if(!msg) - return FALSE; + if (!pgContext->hStatusWindow) + { + msg = (PDISPLAYSTATUSMSG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DISPLAYSTATUSMSG)); + if(!msg) + return FALSE; - msg->Context = pgContext; - msg->dwOptions = dwOptions; - msg->pTitle = pTitle; - msg->pMessage = pMessage; - msg->hDesktop = hDesktop; + msg->Context = pgContext; + msg->dwOptions = dwOptions; + msg->pTitle = pTitle; + msg->pMessage = pMessage; + msg->hDesktop = hDesktop; - msg->StartupEvent = CreateEventW( - NULL, - TRUE, - FALSE, - NULL); + msg->StartupEvent = CreateEventW( + NULL, + TRUE, + FALSE, + NULL); - if (!msg->StartupEvent) - return FALSE; + if (!msg->StartupEvent) + return FALSE; - Thread = CreateThread( - NULL, - 0, - StartupWindowThread, - (PVOID)msg, - 0, - &ThreadId); - if (Thread) - { - CloseHandle(Thread); - WaitForSingleObject(msg->StartupEvent, INFINITE); - CloseHandle(msg->StartupEvent); - return TRUE; - } + Thread = CreateThread( + NULL, + 0, + StartupWindowThread, + (PVOID)msg, + 0, + &ThreadId); + if (Thread) + { + CloseHandle(Thread); + WaitForSingleObject(msg->StartupEvent, INFINITE); + CloseHandle(msg->StartupEvent); + return TRUE; + } - return FALSE; - } + return FALSE; + } - if (pTitle) - SetWindowTextW(pgContext->hStatusWindow, pTitle); + if (pTitle) + SetWindowTextW(pgContext->hStatusWindow, pTitle); - SetDlgItemTextW(pgContext->hStatusWindow, IDC_STATUSLABEL, pMessage); + SetDlgItemTextW(pgContext->hStatusWindow, IDC_STATUSLABEL, pMessage); - return TRUE; + return TRUE; } static BOOL GUIRemoveStatusMessage( - IN PGINA_CONTEXT pgContext) + IN PGINA_CONTEXT pgContext) { - if (pgContext->hStatusWindow) - { - EndDialog(pgContext->hStatusWindow, 0); - pgContext->hStatusWindow = NULL; - } + if (pgContext->hStatusWindow) + { + EndDialog(pgContext->hStatusWindow, 0); + pgContext->hStatusWindow = NULL; + } - return TRUE; + return TRUE; } static INT_PTR CALLBACK EmptyWindowProc( - IN HWND hwndDlg, - IN UINT uMsg, - IN WPARAM wParam, - IN LPARAM lParam) + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) { - UNREFERENCED_PARAMETER(hwndDlg); - UNREFERENCED_PARAMETER(uMsg); - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(hwndDlg); + UNREFERENCED_PARAMETER(uMsg); + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); - return FALSE; + return FALSE; } static VOID GUIDisplaySASNotice( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - INT result; + INT result; - TRACE("GUIDisplaySASNotice()\n"); + TRACE("GUIDisplaySASNotice()\n"); - /* Display the notice window */ - result = DialogBoxParam( - pgContext->hDllInstance, - MAKEINTRESOURCE(IDD_NOTICE_DLG), - GetDesktopWindow(), - EmptyWindowProc, - (LPARAM)NULL); - if (result == -1) - { - /* Failed to display the window. Do as if the user - * already has pressed CTRL+ALT+DELETE */ - pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); - } + /* Display the notice window */ + result = DialogBoxParam( + pgContext->hDllInstance, + MAKEINTRESOURCE(IDD_NOTICE_DLG), + GetDesktopWindow(), + EmptyWindowProc, + (LPARAM)NULL); + if (result == -1) + { + /* Failed to display the window. Do as if the user + * already has pressed CTRL+ALT+DELETE */ + pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); + } } /* Get the text contained in a textbox. Allocates memory in pText * to contain the text. Returns TRUE in case of success */ static BOOL GetTextboxText( - IN HWND hwndDlg, - IN INT TextboxId, - OUT LPWSTR *pText) + IN HWND hwndDlg, + IN INT TextboxId, + OUT LPWSTR *pText) { - LPWSTR Text; - int Count; + LPWSTR Text; + int Count; - Count = GetWindowTextLength(GetDlgItem(hwndDlg, TextboxId)); - Text = HeapAlloc(GetProcessHeap(), 0, (Count + 1) * sizeof(WCHAR)); - if (!Text) - return FALSE; - if (Count != GetWindowTextW(GetDlgItem(hwndDlg, TextboxId), Text, Count + 1)) - { - HeapFree(GetProcessHeap(), 0, Text); - return FALSE; - } - *pText = Text; - return TRUE; + Count = GetWindowTextLength(GetDlgItem(hwndDlg, TextboxId)); + Text = HeapAlloc(GetProcessHeap(), 0, (Count + 1) * sizeof(WCHAR)); + if (!Text) + return FALSE; + if (Count != GetWindowTextW(GetDlgItem(hwndDlg, TextboxId), Text, Count + 1)) + { + HeapFree(GetProcessHeap(), 0, Text); + return FALSE; + } + *pText = Text; + return TRUE; } static VOID @@ -260,209 +260,209 @@ OnInitSecurityDlg(HWND hwnd, static INT_PTR CALLBACK LoggedOnWindowProc( - IN HWND hwndDlg, - IN UINT uMsg, - IN WPARAM wParam, - IN LPARAM lParam) + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) { - switch (uMsg) - { - case WM_INITDIALOG: - { - OnInitSecurityDlg(hwndDlg, (PGINA_CONTEXT)lParam); - SetFocus(GetDlgItem(hwndDlg, IDNO)); - return TRUE; - } + switch (uMsg) + { + case WM_INITDIALOG: + { + OnInitSecurityDlg(hwndDlg, (PGINA_CONTEXT)lParam); + SetFocus(GetDlgItem(hwndDlg, IDNO)); + return TRUE; + } - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDC_LOCK: - EndDialog(hwndDlg, WLX_SAS_ACTION_LOCK_WKSTA); - return TRUE; - case IDC_LOGOFF: - EndDialog(hwndDlg, WLX_SAS_ACTION_LOGOFF); - return TRUE; - case IDC_SHUTDOWN: - EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF); - return TRUE; - case IDC_TASKMGR: - EndDialog(hwndDlg, WLX_SAS_ACTION_TASKLIST); - return TRUE; - case IDCANCEL: - EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); - return TRUE; - } - break; - } - case WM_CLOSE: - { - EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); - return TRUE; - } - } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_LOCK: + EndDialog(hwndDlg, WLX_SAS_ACTION_LOCK_WKSTA); + return TRUE; + case IDC_LOGOFF: + EndDialog(hwndDlg, WLX_SAS_ACTION_LOGOFF); + return TRUE; + case IDC_SHUTDOWN: + EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN_POWER_OFF); + return TRUE; + case IDC_TASKMGR: + EndDialog(hwndDlg, WLX_SAS_ACTION_TASKLIST); + return TRUE; + case IDCANCEL: + EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); + return TRUE; + } + break; + } + case WM_CLOSE: + { + EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); + return TRUE; + } + } - return FALSE; + return FALSE; } static INT GUILoggedOnSAS( - IN OUT PGINA_CONTEXT pgContext, - IN DWORD dwSasType) + IN OUT PGINA_CONTEXT pgContext, + IN DWORD dwSasType) { - INT result; + INT result; - TRACE("GUILoggedOnSAS()\n"); + TRACE("GUILoggedOnSAS()\n"); - if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL) - { - /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will - * close itself thanks to the use of WlxDialogBoxParam */ - return WLX_SAS_ACTION_NONE; - } + if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL) + { + /* Nothing to do for WLX_SAS_TYPE_TIMEOUT ; the dialog will + * close itself thanks to the use of WlxDialogBoxParam */ + return WLX_SAS_ACTION_NONE; + } - result = pgContext->pWlxFuncs->WlxSwitchDesktopToWinlogon( - pgContext->hWlx); + result = pgContext->pWlxFuncs->WlxSwitchDesktopToWinlogon( + pgContext->hWlx); - result = pgContext->pWlxFuncs->WlxDialogBoxParam( - pgContext->hWlx, - pgContext->hDllInstance, - MAKEINTRESOURCEW(IDD_LOGGEDON_DLG), - GetDesktopWindow(), - LoggedOnWindowProc, - (LPARAM)pgContext); + result = pgContext->pWlxFuncs->WlxDialogBoxParam( + pgContext->hWlx, + pgContext->hDllInstance, + MAKEINTRESOURCEW(IDD_LOGGEDON_DLG), + GetDesktopWindow(), + LoggedOnWindowProc, + (LPARAM)pgContext); - if (result < WLX_SAS_ACTION_LOGON || - result > WLX_SAS_ACTION_SWITCH_CONSOLE) - { - result = WLX_SAS_ACTION_NONE; - } + if (result < WLX_SAS_ACTION_LOGON || + result > WLX_SAS_ACTION_SWITCH_CONSOLE) + { + result = WLX_SAS_ACTION_NONE; + } - if (result == WLX_SAS_ACTION_NONE) - { - result = pgContext->pWlxFuncs->WlxSwitchDesktopToUser( - pgContext->hWlx); - } + if (result == WLX_SAS_ACTION_NONE) + { + result = pgContext->pWlxFuncs->WlxSwitchDesktopToUser( + pgContext->hWlx); + } - return result; + return result; } static INT_PTR CALLBACK LoggedOutWindowProc( - IN HWND hwndDlg, - IN UINT uMsg, - IN WPARAM wParam, - IN LPARAM lParam) + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) { - PGINA_CONTEXT pgContext; + PGINA_CONTEXT pgContext; - pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA); + pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA); - switch (uMsg) - { - case WM_INITDIALOG: - { - /* FIXME: take care of DontDisplayLastUserName, NoDomainUI, ShutdownWithoutLogon */ - pgContext = (PGINA_CONTEXT)lParam; - SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext); - SetFocus(GetDlgItem(hwndDlg, IDC_USERNAME)); + switch (uMsg) + { + case WM_INITDIALOG: + { + /* FIXME: take care of DontDisplayLastUserName, NoDomainUI, ShutdownWithoutLogon */ + pgContext = (PGINA_CONTEXT)lParam; + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext); + SetFocus(GetDlgItem(hwndDlg, IDC_USERNAME)); - pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - return TRUE; - } - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc; - if (pgContext->hBitmap) - { - hdc = BeginPaint(hwndDlg, &ps); - DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); - EndPaint(hwndDlg, &ps); - } - return TRUE; - } - case WM_DESTROY: - { - DeleteObject(pgContext->hBitmap); - return TRUE; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDOK: - { - LPWSTR UserName = NULL, Password = NULL; - INT result = WLX_SAS_ACTION_NONE; + pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); + return TRUE; + } + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc; + if (pgContext->hBitmap) + { + hdc = BeginPaint(hwndDlg, &ps); + DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); + EndPaint(hwndDlg, &ps); + } + return TRUE; + } + case WM_DESTROY: + { + DeleteObject(pgContext->hBitmap); + return TRUE; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + { + LPWSTR UserName = NULL, Password = NULL; + INT result = WLX_SAS_ACTION_NONE; - if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0') - break; - if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) && - DoLoginTasks(pgContext, UserName, NULL, Password)) - { - result = WLX_SAS_ACTION_LOGON; - } - HeapFree(GetProcessHeap(), 0, UserName); - HeapFree(GetProcessHeap(), 0, Password); - EndDialog(hwndDlg, result); - return TRUE; - } - case IDCANCEL: - { - EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); - return TRUE; - } - case IDC_SHUTDOWN: - { - EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN); - return TRUE; - } - } - break; - } - } + if (GetTextboxText(hwndDlg, IDC_USERNAME, &UserName) && *UserName == '\0') + break; + if (GetTextboxText(hwndDlg, IDC_PASSWORD, &Password) && + DoLoginTasks(pgContext, UserName, NULL, Password)) + { + result = WLX_SAS_ACTION_LOGON; + } + HeapFree(GetProcessHeap(), 0, UserName); + HeapFree(GetProcessHeap(), 0, Password); + EndDialog(hwndDlg, result); + return TRUE; + } + case IDCANCEL: + { + EndDialog(hwndDlg, WLX_SAS_ACTION_NONE); + return TRUE; + } + case IDC_SHUTDOWN: + { + EndDialog(hwndDlg, WLX_SAS_ACTION_SHUTDOWN); + return TRUE; + } + } + break; + } + } - return FALSE; + return FALSE; } static INT GUILoggedOutSAS( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - int result; + int result; - TRACE("GUILoggedOutSAS()\n"); + TRACE("GUILoggedOutSAS()\n"); - result = pgContext->pWlxFuncs->WlxDialogBoxParam( - pgContext->hWlx, - pgContext->hDllInstance, - MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG), - GetDesktopWindow(), - LoggedOutWindowProc, - (LPARAM)pgContext); - if (result >= WLX_SAS_ACTION_LOGON && - result <= WLX_SAS_ACTION_SWITCH_CONSOLE) - { - WARN("WlxLoggedOutSAS() returns 0x%x\n", result); - return result; - } + result = pgContext->pWlxFuncs->WlxDialogBoxParam( + pgContext->hWlx, + pgContext->hDllInstance, + MAKEINTRESOURCEW(IDD_LOGGEDOUT_DLG), + GetDesktopWindow(), + LoggedOutWindowProc, + (LPARAM)pgContext); + if (result >= WLX_SAS_ACTION_LOGON && + result <= WLX_SAS_ACTION_SWITCH_CONSOLE) + { + WARN("WlxLoggedOutSAS() returns 0x%x\n", result); + return result; + } - WARN("WlxDialogBoxParam() failed (0x%x)\n", result); - return WLX_SAS_ACTION_NONE; + WARN("WlxDialogBoxParam() failed (0x%x)\n", result); + return WLX_SAS_ACTION_NONE; } static INT GUILockedSAS( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - TRACE("GUILockedSAS()\n"); + TRACE("GUILockedSAS()\n"); - UNREFERENCED_PARAMETER(pgContext); + UNREFERENCED_PARAMETER(pgContext); - UNIMPLEMENTED; - return WLX_SAS_ACTION_UNLOCK_WKSTA; + UNIMPLEMENTED; + return WLX_SAS_ACTION_UNLOCK_WKSTA; } @@ -485,71 +485,71 @@ OnInitLockedDlg(HWND hwnd, static INT_PTR CALLBACK LockedWindowProc( - IN HWND hwndDlg, - IN UINT uMsg, - IN WPARAM wParam, - IN LPARAM lParam) + IN HWND hwndDlg, + IN UINT uMsg, + IN WPARAM wParam, + IN LPARAM lParam) { - PGINA_CONTEXT pgContext; + PGINA_CONTEXT pgContext; - pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA); + pgContext = (PGINA_CONTEXT)GetWindowLongPtr(hwndDlg, GWL_USERDATA); - switch (uMsg) - { - case WM_INITDIALOG: - { - pgContext = (PGINA_CONTEXT)lParam; - SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext); + switch (uMsg) + { + case WM_INITDIALOG: + { + pgContext = (PGINA_CONTEXT)lParam; + SetWindowLongPtr(hwndDlg, GWL_USERDATA, (DWORD_PTR)pgContext); - pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - OnInitLockedDlg(hwndDlg, pgContext); - return TRUE; - } - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC hdc; - if (pgContext->hBitmap) - { - hdc = BeginPaint(hwndDlg, &ps); - DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); - EndPaint(hwndDlg, &ps); - } - return TRUE; - } - case WM_DESTROY: - { - DeleteObject(pgContext->hBitmap); - return TRUE; - } - } + pgContext->hBitmap = LoadImage(hDllInstance, MAKEINTRESOURCE(IDI_ROSLOGO), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); + OnInitLockedDlg(hwndDlg, pgContext); + return TRUE; + } + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc; + if (pgContext->hBitmap) + { + hdc = BeginPaint(hwndDlg, &ps); + DrawStateW(hdc, NULL, NULL, (LPARAM)pgContext->hBitmap, (WPARAM)0, 0, 0, 0, 0, DST_BITMAP); + EndPaint(hwndDlg, &ps); + } + return TRUE; + } + case WM_DESTROY: + { + DeleteObject(pgContext->hBitmap); + return TRUE; + } + } - return FALSE; + return FALSE; } static VOID GUIDisplayLockedNotice( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - TRACE("GUIdisplayLockedNotice()\n"); + TRACE("GUIdisplayLockedNotice()\n"); - pgContext->pWlxFuncs->WlxDialogBoxParam( - pgContext->hWlx, - pgContext->hDllInstance, - MAKEINTRESOURCEW(IDD_LOCKED_DLG), - GetDesktopWindow(), - LockedWindowProc, - (LPARAM)pgContext); + pgContext->pWlxFuncs->WlxDialogBoxParam( + pgContext->hWlx, + pgContext->hDllInstance, + MAKEINTRESOURCEW(IDD_LOCKED_DLG), + GetDesktopWindow(), + LockedWindowProc, + (LPARAM)pgContext); } GINA_UI GinaGraphicalUI = { - GUIInitialize, - GUIDisplayStatusMessage, - GUIRemoveStatusMessage, - GUIDisplaySASNotice, - GUILoggedOnSAS, - GUILoggedOutSAS, - GUILockedSAS, - GUIDisplayLockedNotice, + GUIInitialize, + GUIDisplayStatusMessage, + GUIRemoveStatusMessage, + GUIDisplaySASNotice, + GUILoggedOnSAS, + GUILoggedOutSAS, + GUILockedSAS, + GUIDisplayLockedNotice, }; diff --git a/reactos/dll/win32/msgina/msgina.c b/reactos/dll/win32/msgina/msgina.c index 18488bd5c6d..f6bc70aaec0 100644 --- a/reactos/dll/win32/msgina/msgina.c +++ b/reactos/dll/win32/msgina/msgina.c @@ -39,100 +39,100 @@ static PGINA_UI pGinaUI; */ BOOL WINAPI WlxNegotiate( - IN DWORD dwWinlogonVersion, - OUT PDWORD pdwDllVersion) + IN DWORD dwWinlogonVersion, + OUT PDWORD pdwDllVersion) { - TRACE("WlxNegotiate(%lx, %p)\n", dwWinlogonVersion, pdwDllVersion); + TRACE("WlxNegotiate(%lx, %p)\n", dwWinlogonVersion, pdwDllVersion); - if(!pdwDllVersion || (dwWinlogonVersion < WLX_VERSION_1_3)) - return FALSE; + if(!pdwDllVersion || (dwWinlogonVersion < WLX_VERSION_1_3)) + return FALSE; - *pdwDllVersion = WLX_VERSION_1_3; + *pdwDllVersion = WLX_VERSION_1_3; - return TRUE; + return TRUE; } static LONG ReadRegSzKey( - IN HKEY hKey, - IN LPCWSTR pszKey, - OUT LPWSTR* pValue) + IN HKEY hKey, + IN LPCWSTR pszKey, + OUT LPWSTR* pValue) { - LONG rc; - DWORD dwType; - DWORD cbData = 0; - LPWSTR Value; + LONG rc; + DWORD dwType; + DWORD cbData = 0; + LPWSTR Value; - if (!pValue) - return ERROR_INVALID_PARAMETER; + if (!pValue) + return ERROR_INVALID_PARAMETER; - *pValue = NULL; - rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); - if (rc != ERROR_SUCCESS) - return rc; - if (dwType != REG_SZ) - return ERROR_FILE_NOT_FOUND; - Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); - if (!Value) - return ERROR_NOT_ENOUGH_MEMORY; - rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData); - if (rc != ERROR_SUCCESS) - { - HeapFree(GetProcessHeap(), 0, Value); - return rc; - } - /* NULL-terminate the string */ - Value[cbData / sizeof(WCHAR)] = '\0'; + *pValue = NULL; + rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData); + if (rc != ERROR_SUCCESS) + return rc; + if (dwType != REG_SZ) + return ERROR_FILE_NOT_FOUND; + Value = HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR)); + if (!Value) + return ERROR_NOT_ENOUGH_MEMORY; + rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData); + if (rc != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, Value); + return rc; + } + /* NULL-terminate the string */ + Value[cbData / sizeof(WCHAR)] = '\0'; - *pValue = Value; - return ERROR_SUCCESS; + *pValue = Value; + return ERROR_SUCCESS; } static VOID ChooseGinaUI(VOID) { - HKEY ControlKey = NULL; - LPWSTR SystemStartOptions = NULL; - LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */ - BOOL ConsoleBoot = FALSE; - LONG rc; + HKEY ControlKey = NULL; + LPWSTR SystemStartOptions = NULL; + LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */ + BOOL ConsoleBoot = FALSE; + LONG rc; - rc = RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - L"SYSTEM\\CurrentControlSet\\Control", - 0, - KEY_QUERY_VALUE, - &ControlKey); + rc = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + L"SYSTEM\\CurrentControlSet\\Control", + 0, + KEY_QUERY_VALUE, + &ControlKey); - rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions); - if (rc != ERROR_SUCCESS) - goto cleanup; + rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions); + if (rc != ERROR_SUCCESS) + goto cleanup; - /* Check for CONSOLE switch in SystemStartOptions */ - CurrentOption = SystemStartOptions; - while (CurrentOption) - { - NextOption = wcschr(CurrentOption, L' '); - if (NextOption) - *NextOption = L'\0'; - if (wcsicmp(CurrentOption, L"CONSOLE") == 0) - { - TRACE("Found %S. Switching to console boot\n", CurrentOption); - ConsoleBoot = TRUE; - goto cleanup; - } - CurrentOption = NextOption ? NextOption + 1 : NULL; - } + /* Check for CONSOLE switch in SystemStartOptions */ + CurrentOption = SystemStartOptions; + while (CurrentOption) + { + NextOption = wcschr(CurrentOption, L' '); + if (NextOption) + *NextOption = L'\0'; + if (wcsicmp(CurrentOption, L"CONSOLE") == 0) + { + TRACE("Found %S. Switching to console boot\n", CurrentOption); + ConsoleBoot = TRUE; + goto cleanup; + } + CurrentOption = NextOption ? NextOption + 1 : NULL; + } cleanup: - if (ConsoleBoot) - pGinaUI = &GinaTextUI; - else - pGinaUI = &GinaGraphicalUI; + if (ConsoleBoot) + pGinaUI = &GinaTextUI; + else + pGinaUI = &GinaGraphicalUI; - if (ControlKey != NULL) - RegCloseKey(ControlKey); - HeapFree(GetProcessHeap(), 0, SystemStartOptions); + if (ControlKey != NULL) + RegCloseKey(ControlKey); + HeapFree(GetProcessHeap(), 0, SystemStartOptions); } /* @@ -140,50 +140,50 @@ cleanup: */ BOOL WINAPI WlxInitialize( - LPWSTR lpWinsta, - HANDLE hWlx, - PVOID pvReserved, - PVOID pWinlogonFunctions, - PVOID *pWlxContext) + LPWSTR lpWinsta, + HANDLE hWlx, + PVOID pvReserved, + PVOID pWinlogonFunctions, + PVOID *pWlxContext) { - PGINA_CONTEXT pgContext; + PGINA_CONTEXT pgContext; - UNREFERENCED_PARAMETER(pvReserved); + UNREFERENCED_PARAMETER(pvReserved); - pgContext = (PGINA_CONTEXT)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(GINA_CONTEXT)); - if(!pgContext) - { - WARN("LocalAlloc() failed\n"); - return FALSE; - } + pgContext = (PGINA_CONTEXT)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(GINA_CONTEXT)); + if(!pgContext) + { + WARN("LocalAlloc() failed\n"); + return FALSE; + } - /* Return the context to winlogon */ - *pWlxContext = (PVOID)pgContext; - pgContext->hDllInstance = hDllInstance; + /* Return the context to winlogon */ + *pWlxContext = (PVOID)pgContext; + pgContext->hDllInstance = hDllInstance; - /* Save pointer to dispatch table */ - pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION_1_3)pWinlogonFunctions; + /* Save pointer to dispatch table */ + pgContext->pWlxFuncs = (PWLX_DISPATCH_VERSION_1_3)pWinlogonFunctions; - /* Save the winlogon handle used to call the dispatch functions */ - pgContext->hWlx = hWlx; + /* Save the winlogon handle used to call the dispatch functions */ + pgContext->hWlx = hWlx; - /* Save window station */ - pgContext->station = lpWinsta; + /* Save window station */ + pgContext->station = lpWinsta; - /* Clear status window handle */ - pgContext->hStatusWindow = 0; + /* Clear status window handle */ + pgContext->hStatusWindow = 0; - /* Notify winlogon that we will use the default SAS */ - pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx); + /* Notify winlogon that we will use the default SAS */ + pgContext->pWlxFuncs->WlxUseCtrlAltDel(hWlx); - /* Locates the authentification package */ - //LsaRegisterLogonProcess(...); + /* Locates the authentification package */ + //LsaRegisterLogonProcess(...); - /* Check autologon settings the first time */ - pgContext->AutoLogonState = AUTOLOGON_CHECK_REGISTRY; + /* Check autologon settings the first time */ + pgContext->AutoLogonState = AUTOLOGON_CHECK_REGISTRY; - ChooseGinaUI(); - return pGinaUI->Initialize(pgContext); + ChooseGinaUI(); + return pGinaUI->Initialize(pgContext); } /* @@ -252,65 +252,65 @@ WlxScreenSaverNotify( */ BOOL WINAPI WlxStartApplication( - PVOID pWlxContext, - PWSTR pszDesktopName, - PVOID pEnvironment, - PWSTR pszCmdLine) + PVOID pWlxContext, + PWSTR pszDesktopName, + PVOID pEnvironment, + PWSTR pszCmdLine) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - STARTUPINFOW StartupInfo; - PROCESS_INFORMATION ProcessInformation; - WCHAR CurrentDirectory[MAX_PATH]; - HANDLE hAppToken; - UINT len; - BOOL ret; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + STARTUPINFOW StartupInfo; + PROCESS_INFORMATION ProcessInformation; + WCHAR CurrentDirectory[MAX_PATH]; + HANDLE hAppToken; + UINT len; + BOOL ret; - len = GetWindowsDirectoryW(CurrentDirectory, MAX_PATH); - if (len == 0 || len > MAX_PATH) - { - ERR("GetWindowsDirectoryW() failed\n"); - return FALSE; - } + len = GetWindowsDirectoryW(CurrentDirectory, MAX_PATH); + if (len == 0 || len > MAX_PATH) + { + ERR("GetWindowsDirectoryW() failed\n"); + return FALSE; + } - ret = DuplicateTokenEx(pgContext->UserToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hAppToken); - if (!ret) - { - ERR("DuplicateTokenEx() failed with error %lu\n", GetLastError()); - return FALSE; - } + ret = DuplicateTokenEx(pgContext->UserToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hAppToken); + if (!ret) + { + ERR("DuplicateTokenEx() failed with error %lu\n", GetLastError()); + return FALSE; + } - ZeroMemory(&StartupInfo, sizeof(StartupInfo)); - ZeroMemory(&ProcessInformation, sizeof(ProcessInformation)); - StartupInfo.cb = sizeof(StartupInfo); - StartupInfo.lpTitle = pszCmdLine; - StartupInfo.dwFlags = STARTF_USESHOWWINDOW; - StartupInfo.wShowWindow = SW_SHOW; - StartupInfo.lpDesktop = pszDesktopName; + ZeroMemory(&StartupInfo, sizeof(StartupInfo)); + ZeroMemory(&ProcessInformation, sizeof(ProcessInformation)); + StartupInfo.cb = sizeof(StartupInfo); + StartupInfo.lpTitle = pszCmdLine; + StartupInfo.dwFlags = STARTF_USESHOWWINDOW; + StartupInfo.wShowWindow = SW_SHOW; + StartupInfo.lpDesktop = pszDesktopName; - len = GetWindowsDirectoryW(CurrentDirectory, MAX_PATH); - if (len == 0 || len > MAX_PATH) - { - ERR("GetWindowsDirectoryW() failed\n"); - return FALSE; - } - ret = CreateProcessAsUserW( - hAppToken, - pszCmdLine, - NULL, - NULL, - NULL, - FALSE, - CREATE_UNICODE_ENVIRONMENT, - pEnvironment, - CurrentDirectory, - &StartupInfo, - &ProcessInformation); - CloseHandle(ProcessInformation.hProcess); - CloseHandle(ProcessInformation.hThread); - CloseHandle(hAppToken); - if (!ret) - ERR("CreateProcessAsUserW() failed with error %lu\n", GetLastError()); - return ret; + len = GetWindowsDirectoryW(CurrentDirectory, MAX_PATH); + if (len == 0 || len > MAX_PATH) + { + ERR("GetWindowsDirectoryW() failed\n"); + return FALSE; + } + ret = CreateProcessAsUserW( + hAppToken, + pszCmdLine, + NULL, + NULL, + NULL, + FALSE, + CREATE_UNICODE_ENVIRONMENT, + pEnvironment, + CurrentDirectory, + &StartupInfo, + &ProcessInformation); + CloseHandle(ProcessInformation.hProcess); + CloseHandle(ProcessInformation.hThread); + CloseHandle(hAppToken); + if (!ret) + ERR("CreateProcessAsUserW() failed with error %lu\n", GetLastError()); + return ret; } /* @@ -318,61 +318,61 @@ WlxStartApplication( */ BOOL WINAPI WlxActivateUserShell( - PVOID pWlxContext, - PWSTR pszDesktopName, - PWSTR pszMprLogonScript, - PVOID pEnvironment) + PVOID pWlxContext, + PWSTR pszDesktopName, + PWSTR pszMprLogonScript, + PVOID pEnvironment) { - HKEY hKey; - DWORD BufSize, ValueType; - WCHAR pszUserInitApp[MAX_PATH + 1]; - WCHAR pszExpUserInitApp[MAX_PATH]; - DWORD len; - LONG rc; + HKEY hKey; + DWORD BufSize, ValueType; + WCHAR pszUserInitApp[MAX_PATH + 1]; + WCHAR pszExpUserInitApp[MAX_PATH]; + DWORD len; + LONG rc; - TRACE("WlxActivateUserShell()\n"); + TRACE("WlxActivateUserShell()\n"); - UNREFERENCED_PARAMETER(pszMprLogonScript); + UNREFERENCED_PARAMETER(pszMprLogonScript); - /* Get the path of userinit */ - rc = RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", - 0, - KEY_QUERY_VALUE, - &hKey); - if (rc != ERROR_SUCCESS) - { - WARN("RegOpenKeyExW() failed with error %lu\n", rc); - return FALSE; - } + /* Get the path of userinit */ + rc = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", + 0, + KEY_QUERY_VALUE, + &hKey); + if (rc != ERROR_SUCCESS) + { + WARN("RegOpenKeyExW() failed with error %lu\n", rc); + return FALSE; + } - /* Query userinit application */ - BufSize = sizeof(pszUserInitApp) - sizeof(UNICODE_NULL); - rc = RegQueryValueExW( - hKey, - L"Userinit", - NULL, - &ValueType, - (LPBYTE)pszUserInitApp, - &BufSize); - RegCloseKey(hKey); - if (rc != ERROR_SUCCESS || (ValueType != REG_SZ && ValueType != REG_EXPAND_SZ)) - { - WARN("RegQueryValueExW() failed with error %lu\n", rc); - return FALSE; - } - pszUserInitApp[MAX_PATH] = UNICODE_NULL; + /* Query userinit application */ + BufSize = sizeof(pszUserInitApp) - sizeof(UNICODE_NULL); + rc = RegQueryValueExW( + hKey, + L"Userinit", + NULL, + &ValueType, + (LPBYTE)pszUserInitApp, + &BufSize); + RegCloseKey(hKey); + if (rc != ERROR_SUCCESS || (ValueType != REG_SZ && ValueType != REG_EXPAND_SZ)) + { + WARN("RegQueryValueExW() failed with error %lu\n", rc); + return FALSE; + } + pszUserInitApp[MAX_PATH] = UNICODE_NULL; - len = ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, MAX_PATH); - if (len > MAX_PATH) - { - WARN("ExpandEnvironmentStringsW() failed. Required size %lu\n", len); - return FALSE; - } + len = ExpandEnvironmentStringsW(pszUserInitApp, pszExpUserInitApp, MAX_PATH); + if (len > MAX_PATH) + { + WARN("ExpandEnvironmentStringsW() failed. Required size %lu\n", len); + return FALSE; + } - /* Start userinit app */ - return WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp); + /* Start userinit app */ + return WlxStartApplication(pWlxContext, pszDesktopName, pEnvironment, pszExpUserInitApp); } /* @@ -380,43 +380,43 @@ WlxActivateUserShell( */ int WINAPI WlxLoggedOnSAS( - PVOID pWlxContext, - DWORD dwSasType, - PVOID pReserved) + PVOID pWlxContext, + DWORD dwSasType, + PVOID pReserved) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - INT SasAction = WLX_SAS_ACTION_NONE; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + INT SasAction = WLX_SAS_ACTION_NONE; - TRACE("WlxLoggedOnSAS(0x%lx)\n", dwSasType); + TRACE("WlxLoggedOnSAS(0x%lx)\n", dwSasType); - UNREFERENCED_PARAMETER(pReserved); + UNREFERENCED_PARAMETER(pReserved); - switch (dwSasType) - { - case WLX_SAS_TYPE_CTRL_ALT_DEL: - case WLX_SAS_TYPE_TIMEOUT: - { - SasAction = pGinaUI->LoggedOnSAS(pgContext, dwSasType); - break; - } - case WLX_SAS_TYPE_SC_INSERT: - { - FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n"); - break; - } - case WLX_SAS_TYPE_SC_REMOVE: - { - FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n"); - break; - } - default: - { - WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType); - break; - } - } + switch (dwSasType) + { + case WLX_SAS_TYPE_CTRL_ALT_DEL: + case WLX_SAS_TYPE_TIMEOUT: + { + SasAction = pGinaUI->LoggedOnSAS(pgContext, dwSasType); + break; + } + case WLX_SAS_TYPE_SC_INSERT: + { + FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_INSERT not supported!\n"); + break; + } + case WLX_SAS_TYPE_SC_REMOVE: + { + FIXME("WlxLoggedOnSAS: SasType WLX_SAS_TYPE_SC_REMOVE not supported!\n"); + break; + } + default: + { + WARN("WlxLoggedOnSAS: Unknown SasType: 0x%x\n", dwSasType); + break; + } + } - return SasAction; + return SasAction; } /* @@ -424,17 +424,17 @@ WlxLoggedOnSAS( */ BOOL WINAPI WlxDisplayStatusMessage( - IN PVOID pWlxContext, - IN HDESK hDesktop, - IN DWORD dwOptions, - IN PWSTR pTitle, - IN PWSTR pMessage) + IN PVOID pWlxContext, + IN HDESK hDesktop, + IN DWORD dwOptions, + IN PWSTR pTitle, + IN PWSTR pMessage) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - TRACE("WlxDisplayStatusMessage(\"%S\")\n", pMessage); + TRACE("WlxDisplayStatusMessage(\"%S\")\n", pMessage); - return pGinaUI->DisplayStatusMessage(pgContext, hDesktop, dwOptions, pTitle, pMessage); + return pGinaUI->DisplayStatusMessage(pgContext, hDesktop, dwOptions, pTitle, pMessage); } /* @@ -442,231 +442,231 @@ WlxDisplayStatusMessage( */ BOOL WINAPI WlxRemoveStatusMessage( - IN PVOID pWlxContext) + IN PVOID pWlxContext) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - TRACE("WlxRemoveStatusMessage()\n"); + TRACE("WlxRemoveStatusMessage()\n"); - return pGinaUI->RemoveStatusMessage(pgContext); + return pGinaUI->RemoveStatusMessage(pgContext); } static PWSTR DuplicationString(PWSTR Str) { - DWORD cb; - PWSTR NewStr; + DWORD cb; + PWSTR NewStr; - if (Str == NULL) return NULL; + if (Str == NULL) return NULL; - cb = (wcslen(Str) + 1) * sizeof(WCHAR); - if ((NewStr = LocalAlloc(LMEM_FIXED, cb))) - memcpy(NewStr, Str, cb); - return NewStr; + cb = (wcslen(Str) + 1) * sizeof(WCHAR); + if ((NewStr = LocalAlloc(LMEM_FIXED, cb))) + memcpy(NewStr, Str, cb); + return NewStr; } BOOL DoLoginTasks( - IN OUT PGINA_CONTEXT pgContext, - IN PWSTR UserName, - IN PWSTR Domain, - IN PWSTR Password) + IN OUT PGINA_CONTEXT pgContext, + IN PWSTR UserName, + IN PWSTR Domain, + IN PWSTR Password) { - LPWSTR ProfilePath = NULL; - LPWSTR lpEnvironment = NULL; - TOKEN_STATISTICS Stats; - PWLX_PROFILE_V2_0 pProfile = NULL; - DWORD cbStats, cbSize; - DWORD dwLength; - BOOL bResult; + LPWSTR ProfilePath = NULL; + LPWSTR lpEnvironment = NULL; + TOKEN_STATISTICS Stats; + PWLX_PROFILE_V2_0 pProfile = NULL; + DWORD cbStats, cbSize; + DWORD dwLength; + BOOL bResult; - if (!LogonUserW(UserName, Domain, Password, - LOGON32_LOGON_INTERACTIVE, - LOGON32_PROVIDER_DEFAULT, - &pgContext->UserToken)) - { - WARN("LogonUserW() failed\n"); - goto cleanup; - } + if (!LogonUserW(UserName, Domain, Password, + LOGON32_LOGON_INTERACTIVE, + LOGON32_PROVIDER_DEFAULT, + &pgContext->UserToken)) + { + WARN("LogonUserW() failed\n"); + goto cleanup; + } - /* Store the logon time in the context */ - GetLocalTime(&pgContext->LogonTime); + /* Store the logon time in the context */ + GetLocalTime(&pgContext->LogonTime); - /* Store user and domain in the context */ - wcscpy(pgContext->UserName, UserName); - if (Domain == NULL || wcslen(Domain) == 0) - { - dwLength = 256; - GetComputerNameW(pgContext->Domain, &dwLength); - } - else - { - wcscpy(pgContext->Domain, Domain); - } + /* Store user and domain in the context */ + wcscpy(pgContext->UserName, UserName); + if (Domain == NULL || wcslen(Domain) == 0) + { + dwLength = 256; + GetComputerNameW(pgContext->Domain, &dwLength); + } + else + { + wcscpy(pgContext->Domain, Domain); + } - /* Get profile path */ - cbSize = 0; - bResult = GetProfilesDirectoryW(NULL, &cbSize); - if (!bResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - ProfilePath = HeapAlloc(GetProcessHeap(), 0, cbSize * sizeof(WCHAR)); - if (!ProfilePath) - { - WARN("HeapAlloc() failed\n"); - goto cleanup; - } - bResult = GetProfilesDirectoryW(ProfilePath, &cbSize); - } - if (!bResult) - { - WARN("GetUserProfileDirectoryW() failed\n"); - goto cleanup; - } + /* Get profile path */ + cbSize = 0; + bResult = GetProfilesDirectoryW(NULL, &cbSize); + if (!bResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + ProfilePath = HeapAlloc(GetProcessHeap(), 0, cbSize * sizeof(WCHAR)); + if (!ProfilePath) + { + WARN("HeapAlloc() failed\n"); + goto cleanup; + } + bResult = GetProfilesDirectoryW(ProfilePath, &cbSize); + } + if (!bResult) + { + WARN("GetUserProfileDirectoryW() failed\n"); + goto cleanup; + } - /* Allocate memory for profile */ - pProfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLX_PROFILE_V2_0)); - if (!pProfile) - { - WARN("HeapAlloc() failed\n"); - goto cleanup; - } - pProfile->dwType = WLX_PROFILE_TYPE_V2_0; - pProfile->pszProfile = ProfilePath; + /* Allocate memory for profile */ + pProfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLX_PROFILE_V2_0)); + if (!pProfile) + { + WARN("HeapAlloc() failed\n"); + goto cleanup; + } + pProfile->dwType = WLX_PROFILE_TYPE_V2_0; + pProfile->pszProfile = ProfilePath; - lpEnvironment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - (wcslen(pgContext->Domain)+ 14 + 1) * sizeof(WCHAR)); - if (!lpEnvironment) - { - WARN("HeapAlloc() failed\n"); - goto cleanup; - } + lpEnvironment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + (wcslen(pgContext->Domain)+ 14 + 1) * sizeof(WCHAR)); + if (!lpEnvironment) + { + WARN("HeapAlloc() failed\n"); + goto cleanup; + } - wsprintfW(lpEnvironment, L"LOGONSERVER=\\\\%s", pgContext->Domain); + wsprintfW(lpEnvironment, L"LOGONSERVER=\\\\%s", pgContext->Domain); - pProfile->pszEnvironment = lpEnvironment; + pProfile->pszEnvironment = lpEnvironment; - if (!GetTokenInformation(pgContext->UserToken, - TokenStatistics, - (PVOID)&Stats, - sizeof(TOKEN_STATISTICS), - &cbStats)) - { - WARN("Couldn't get Authentication id from user token!\n"); - goto cleanup; - } + if (!GetTokenInformation(pgContext->UserToken, + TokenStatistics, + (PVOID)&Stats, + sizeof(TOKEN_STATISTICS), + &cbStats)) + { + WARN("Couldn't get Authentication id from user token!\n"); + goto cleanup; + } - *pgContext->pAuthenticationId = Stats.AuthenticationId; - pgContext->pMprNotifyInfo->pszUserName = DuplicationString(UserName); - pgContext->pMprNotifyInfo->pszDomain = DuplicationString(Domain); - pgContext->pMprNotifyInfo->pszPassword = DuplicationString(Password); - pgContext->pMprNotifyInfo->pszOldPassword = NULL; - *pgContext->pdwOptions = 0; - *pgContext->pProfile = pProfile; - return TRUE; + *pgContext->pAuthenticationId = Stats.AuthenticationId; + pgContext->pMprNotifyInfo->pszUserName = DuplicationString(UserName); + pgContext->pMprNotifyInfo->pszDomain = DuplicationString(Domain); + pgContext->pMprNotifyInfo->pszPassword = DuplicationString(Password); + pgContext->pMprNotifyInfo->pszOldPassword = NULL; + *pgContext->pdwOptions = 0; + *pgContext->pProfile = pProfile; + return TRUE; cleanup: - if (pProfile) - { - HeapFree(GetProcessHeap(), 0, pProfile->pszEnvironment); - } - HeapFree(GetProcessHeap(), 0, pProfile); - HeapFree(GetProcessHeap(), 0, ProfilePath); - return FALSE; + if (pProfile) + { + HeapFree(GetProcessHeap(), 0, pProfile->pszEnvironment); + } + HeapFree(GetProcessHeap(), 0, pProfile); + HeapFree(GetProcessHeap(), 0, ProfilePath); + return FALSE; } static BOOL DoAutoLogon( - IN PGINA_CONTEXT pgContext) + IN PGINA_CONTEXT pgContext) { - HKEY WinLogonKey = NULL; - LPWSTR AutoLogon = NULL; - LPWSTR AutoCount = NULL; - LPWSTR IgnoreShiftOverride = NULL; - LPWSTR UserName = NULL; - LPWSTR DomainName = NULL; - LPWSTR Password = NULL; - BOOL result = FALSE; - LONG rc; + HKEY WinLogonKey = NULL; + LPWSTR AutoLogon = NULL; + LPWSTR AutoCount = NULL; + LPWSTR IgnoreShiftOverride = NULL; + LPWSTR UserName = NULL; + LPWSTR DomainName = NULL; + LPWSTR Password = NULL; + BOOL result = FALSE; + LONG rc; - TRACE("DoAutoLogon(): AutoLogonState = %lu\n", - pgContext->AutoLogonState); + TRACE("DoAutoLogon(): AutoLogonState = %lu\n", + pgContext->AutoLogonState); - if (pgContext->AutoLogonState == AUTOLOGON_DISABLED) - return FALSE; + if (pgContext->AutoLogonState == AUTOLOGON_DISABLED) + return FALSE; - rc = RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon", - 0, - KEY_QUERY_VALUE, - &WinLogonKey); - if (rc != ERROR_SUCCESS) - goto cleanup; + rc = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\WinLogon", + 0, + KEY_QUERY_VALUE, + &WinLogonKey); + if (rc != ERROR_SUCCESS) + goto cleanup; - if (pgContext->AutoLogonState == AUTOLOGON_CHECK_REGISTRY) - { - /* Set it by default to disabled, we might reenable it again later */ - pgContext->AutoLogonState = AUTOLOGON_DISABLED; + if (pgContext->AutoLogonState == AUTOLOGON_CHECK_REGISTRY) + { + /* Set it by default to disabled, we might reenable it again later */ + pgContext->AutoLogonState = AUTOLOGON_DISABLED; - rc = ReadRegSzKey(WinLogonKey, L"AutoAdminLogon", &AutoLogon); - if (rc != ERROR_SUCCESS) - goto cleanup; - if (wcscmp(AutoLogon, L"1") != 0) - goto cleanup; + rc = ReadRegSzKey(WinLogonKey, L"AutoAdminLogon", &AutoLogon); + if (rc != ERROR_SUCCESS) + goto cleanup; + if (wcscmp(AutoLogon, L"1") != 0) + goto cleanup; - rc = ReadRegSzKey(WinLogonKey, L"AutoLogonCount", &AutoCount); - if (rc == ERROR_SUCCESS && wcscmp(AutoCount, L"0") == 0) - goto cleanup; - else if (rc != ERROR_FILE_NOT_FOUND) - goto cleanup; + rc = ReadRegSzKey(WinLogonKey, L"AutoLogonCount", &AutoCount); + if (rc == ERROR_SUCCESS && wcscmp(AutoCount, L"0") == 0) + goto cleanup; + else if (rc != ERROR_FILE_NOT_FOUND) + goto cleanup; - rc = ReadRegSzKey(WinLogonKey, L"IgnoreShiftOverride", &UserName); - if (rc == ERROR_SUCCESS) - { - if (wcscmp(AutoLogon, L"1") != 0 && GetKeyState(VK_SHIFT) < 0) - goto cleanup; - } - else if (GetKeyState(VK_SHIFT) < 0) - { - /* User pressed SHIFT */ - goto cleanup; - } + rc = ReadRegSzKey(WinLogonKey, L"IgnoreShiftOverride", &UserName); + if (rc == ERROR_SUCCESS) + { + if (wcscmp(AutoLogon, L"1") != 0 && GetKeyState(VK_SHIFT) < 0) + goto cleanup; + } + else if (GetKeyState(VK_SHIFT) < 0) + { + /* User pressed SHIFT */ + goto cleanup; + } - pgContext->AutoLogonState = AUTOLOGON_ONCE; - result = TRUE; - } - else /* pgContext->AutoLogonState == AUTOLOGON_ONCE */ - { - pgContext->AutoLogonState = AUTOLOGON_DISABLED; + pgContext->AutoLogonState = AUTOLOGON_ONCE; + result = TRUE; + } + else /* pgContext->AutoLogonState == AUTOLOGON_ONCE */ + { + pgContext->AutoLogonState = AUTOLOGON_DISABLED; - rc = ReadRegSzKey(WinLogonKey, L"DefaultUserName", &UserName); - if (rc != ERROR_SUCCESS) - goto cleanup; - rc = ReadRegSzKey(WinLogonKey, L"DefaultDomainName", &DomainName); - if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) - goto cleanup; - rc = ReadRegSzKey(WinLogonKey, L"DefaultPassword", &Password); - if (rc != ERROR_SUCCESS) - goto cleanup; + rc = ReadRegSzKey(WinLogonKey, L"DefaultUserName", &UserName); + if (rc != ERROR_SUCCESS) + goto cleanup; + rc = ReadRegSzKey(WinLogonKey, L"DefaultDomainName", &DomainName); + if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) + goto cleanup; + rc = ReadRegSzKey(WinLogonKey, L"DefaultPassword", &Password); + if (rc != ERROR_SUCCESS) + goto cleanup; - result = DoLoginTasks(pgContext, UserName, DomainName, Password); + result = DoLoginTasks(pgContext, UserName, DomainName, Password); - if (result == TRUE) - NotifyBootConfigStatus(TRUE); - } + if (result == TRUE) + NotifyBootConfigStatus(TRUE); + } cleanup: - if (WinLogonKey != NULL) - RegCloseKey(WinLogonKey); - HeapFree(GetProcessHeap(), 0, AutoLogon); - HeapFree(GetProcessHeap(), 0, AutoCount); - HeapFree(GetProcessHeap(), 0, IgnoreShiftOverride); - HeapFree(GetProcessHeap(), 0, UserName); - HeapFree(GetProcessHeap(), 0, DomainName); - HeapFree(GetProcessHeap(), 0, Password); - TRACE("DoAutoLogon(): AutoLogonState = %lu, returning %d\n", - pgContext->AutoLogonState, result); - return result; + if (WinLogonKey != NULL) + RegCloseKey(WinLogonKey); + HeapFree(GetProcessHeap(), 0, AutoLogon); + HeapFree(GetProcessHeap(), 0, AutoCount); + HeapFree(GetProcessHeap(), 0, IgnoreShiftOverride); + HeapFree(GetProcessHeap(), 0, UserName); + HeapFree(GetProcessHeap(), 0, DomainName); + HeapFree(GetProcessHeap(), 0, Password); + TRACE("DoAutoLogon(): AutoLogonState = %lu, returning %d\n", + pgContext->AutoLogonState, result); + return result; } /* @@ -674,32 +674,32 @@ cleanup: */ VOID WINAPI WlxDisplaySASNotice( - IN PVOID pWlxContext) + IN PVOID pWlxContext) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - TRACE("WlxDisplaySASNotice(%p)\n", pWlxContext); + TRACE("WlxDisplaySASNotice(%p)\n", pWlxContext); - if (GetSystemMetrics(SM_REMOTESESSION)) - { - /* User is remotely logged on. Don't display a notice */ - pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); - return; - } + if (GetSystemMetrics(SM_REMOTESESSION)) + { + /* User is remotely logged on. Don't display a notice */ + pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); + return; + } - if (DoAutoLogon(pgContext)) - { - /* Don't display the window, we want to do an automatic logon */ - pgContext->AutoLogonState = AUTOLOGON_ONCE; - pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); - return; - } - else - pgContext->AutoLogonState = AUTOLOGON_DISABLED; + if (DoAutoLogon(pgContext)) + { + /* Don't display the window, we want to do an automatic logon */ + pgContext->AutoLogonState = AUTOLOGON_ONCE; + pgContext->pWlxFuncs->WlxSasNotify(pgContext->hWlx, WLX_SAS_TYPE_CTRL_ALT_DEL); + return; + } + else + pgContext->AutoLogonState = AUTOLOGON_DISABLED; - pGinaUI->DisplaySASNotice(pgContext); + pGinaUI->DisplaySASNotice(pgContext); - TRACE("WlxDisplaySASNotice() done\n"); + TRACE("WlxDisplaySASNotice() done\n"); } /* @@ -707,40 +707,40 @@ WlxDisplaySASNotice( */ INT WINAPI WlxLoggedOutSAS( - IN PVOID pWlxContext, - IN DWORD dwSasType, - OUT PLUID pAuthenticationId, - IN OUT PSID pLogonSid, - OUT PDWORD pdwOptions, - OUT PHANDLE phToken, - OUT PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, - OUT PVOID *pProfile) + IN PVOID pWlxContext, + IN DWORD dwSasType, + OUT PLUID pAuthenticationId, + IN OUT PSID pLogonSid, + OUT PDWORD pdwOptions, + OUT PHANDLE phToken, + OUT PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, + OUT PVOID *pProfile) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - INT res; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + INT res; - TRACE("WlxLoggedOutSAS()\n"); + TRACE("WlxLoggedOutSAS()\n"); - UNREFERENCED_PARAMETER(dwSasType); - UNREFERENCED_PARAMETER(pLogonSid); + UNREFERENCED_PARAMETER(dwSasType); + UNREFERENCED_PARAMETER(pLogonSid); - pgContext->pAuthenticationId = pAuthenticationId; - pgContext->pdwOptions = pdwOptions; - pgContext->pMprNotifyInfo = pMprNotifyInfo; - pgContext->pProfile = pProfile; + pgContext->pAuthenticationId = pAuthenticationId; + pgContext->pdwOptions = pdwOptions; + pgContext->pMprNotifyInfo = pMprNotifyInfo; + pgContext->pProfile = pProfile; - if (0 == GetSystemMetrics(SM_REMOTESESSION) && - DoAutoLogon(pgContext)) - { - /* User is local and registry contains information - * to log on him automatically */ - *phToken = pgContext->UserToken; - return WLX_SAS_ACTION_LOGON; - } + if (0 == GetSystemMetrics(SM_REMOTESESSION) && + DoAutoLogon(pgContext)) + { + /* User is local and registry contains information + * to log on him automatically */ + *phToken = pgContext->UserToken; + return WLX_SAS_ACTION_LOGON; + } - res = pGinaUI->LoggedOutSAS(pgContext); - *phToken = pgContext->UserToken; - return res; + res = pGinaUI->LoggedOutSAS(pgContext); + *phToken = pgContext->UserToken; + return res; } /* @@ -748,16 +748,16 @@ WlxLoggedOutSAS( */ int WINAPI WlxWkstaLockedSAS( - PVOID pWlxContext, - DWORD dwSasType) + PVOID pWlxContext, + DWORD dwSasType) { - PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; + PGINA_CONTEXT pgContext = (PGINA_CONTEXT)pWlxContext; - TRACE("WlxWkstaLockedSAS()\n"); + TRACE("WlxWkstaLockedSAS()\n"); - UNREFERENCED_PARAMETER(dwSasType); + UNREFERENCED_PARAMETER(dwSasType); - return pGinaUI->LockedSAS(pgContext); + return pGinaUI->LockedSAS(pgContext); } @@ -781,7 +781,7 @@ WlxDisplayLockedNotice(PVOID pWlxContext) */ BOOL WINAPI WlxIsLogoffOk( - PVOID pWlxContext) + PVOID pWlxContext) { TRACE("WlxIsLogoffOk()\n"); UNREFERENCED_PARAMETER(pWlxContext); @@ -790,14 +790,14 @@ WlxIsLogoffOk( BOOL WINAPI DllMain( - IN HINSTANCE hinstDLL, - IN DWORD dwReason, - IN LPVOID lpvReserved) + IN HINSTANCE hinstDLL, + IN DWORD dwReason, + IN LPVOID lpvReserved) { - UNREFERENCED_PARAMETER(lpvReserved); + UNREFERENCED_PARAMETER(lpvReserved); - if (dwReason == DLL_PROCESS_ATTACH) - hDllInstance = hinstDLL; + if (dwReason == DLL_PROCESS_ATTACH) + hDllInstance = hinstDLL; - return TRUE; + return TRUE; } diff --git a/reactos/dll/win32/msgina/msgina.h b/reactos/dll/win32/msgina/msgina.h index a9ab3e4fcc6..e79d40ee779 100644 --- a/reactos/dll/win32/msgina/msgina.h +++ b/reactos/dll/win32/msgina/msgina.h @@ -23,25 +23,25 @@ typedef struct { - HANDLE hWlx; - LPWSTR station; - PWLX_DISPATCH_VERSION_1_3 pWlxFuncs; - HANDLE hDllInstance; - HWND hStatusWindow; - DWORD AutoLogonState; + HANDLE hWlx; + LPWSTR station; + PWLX_DISPATCH_VERSION_1_3 pWlxFuncs; + HANDLE hDllInstance; + HWND hStatusWindow; + DWORD AutoLogonState; - /* Informations to be filled during logon */ - WCHAR UserName[256]; - WCHAR Domain[256]; - SYSTEMTIME LogonTime; - HANDLE UserToken; - PLUID pAuthenticationId; - PDWORD pdwOptions; - PWLX_MPR_NOTIFY_INFO pMprNotifyInfo; - PVOID *pProfile; + /* Informations to be filled during logon */ + WCHAR UserName[256]; + WCHAR Domain[256]; + SYSTEMTIME LogonTime; + HANDLE UserToken; + PLUID pAuthenticationId; + PDWORD pdwOptions; + PWLX_MPR_NOTIFY_INFO pMprNotifyInfo; + PVOID *pProfile; - /* Current logo to display */ - HBITMAP hBitmap; + /* Current logo to display */ + HBITMAP hBitmap; } GINA_CONTEXT, *PGINA_CONTEXT; extern HINSTANCE hDllInstance; @@ -57,23 +57,23 @@ typedef VOID (*PFGINA_DISPLAYLOCKEDNOTICE)(PGINA_CONTEXT); typedef struct _GINA_UI { - PFGINA_INITIALIZE Initialize; - PFGINA_DISPLAYSTATUSMESSAGE DisplayStatusMessage; - PFGINA_REMOVESTATUSMESSAGE RemoveStatusMessage; - PFGINA_DISPLAYSASNOTICE DisplaySASNotice; - PFGINA_LOGGEDONSAS LoggedOnSAS; - PFGINA_LOGGEDOUTSAS LoggedOutSAS; - PFGINA_LOCKEDSAS LockedSAS; - PFGINA_DISPLAYLOCKEDNOTICE DisplayLockedNotice; + PFGINA_INITIALIZE Initialize; + PFGINA_DISPLAYSTATUSMESSAGE DisplayStatusMessage; + PFGINA_REMOVESTATUSMESSAGE RemoveStatusMessage; + PFGINA_DISPLAYSASNOTICE DisplaySASNotice; + PFGINA_LOGGEDONSAS LoggedOnSAS; + PFGINA_LOGGEDOUTSAS LoggedOutSAS; + PFGINA_LOCKEDSAS LockedSAS; + PFGINA_DISPLAYLOCKEDNOTICE DisplayLockedNotice; } GINA_UI, *PGINA_UI; /* msgina.c */ BOOL DoLoginTasks( - IN OUT PGINA_CONTEXT pgContext, - IN PWSTR UserName, - IN PWSTR Domain, - IN PWSTR Password); + IN OUT PGINA_CONTEXT pgContext, + IN PWSTR UserName, + IN PWSTR Domain, + IN PWSTR Password); /* EOF */ diff --git a/reactos/dll/win32/msgina/stubs.c b/reactos/dll/win32/msgina/stubs.c index 19fd551e2b8..3223a52d689 100644 --- a/reactos/dll/win32/msgina/stubs.c +++ b/reactos/dll/win32/msgina/stubs.c @@ -22,20 +22,20 @@ ShellShutdownDialog( DWORD Unknown, BOOL bHideLogoff) { - UNREFERENCED_PARAMETER(hParent); - UNREFERENCED_PARAMETER(Unknown); - UNREFERENCED_PARAMETER(bHideLogoff); + UNREFERENCED_PARAMETER(hParent); + UNREFERENCED_PARAMETER(Unknown); + UNREFERENCED_PARAMETER(bHideLogoff); - /* Return values: - * 0x00: Cancelled/Help - * 0x01: Log off user - * 0x02: Shutdown - * 0x04: Reboot - * 0x10: Standby - * 0x40: Hibernate - */ - UNIMPLEMENTED; - return FALSE; + /* Return values: + * 0x00: Cancelled/Help + * 0x01: Log off user + * 0x02: Shutdown + * 0x04: Reboot + * 0x10: Standby + * 0x40: Hibernate + */ + UNIMPLEMENTED; + return FALSE; } @@ -44,12 +44,12 @@ ShellShutdownDialog( */ BOOL WINAPI WlxIsLockOk( - PVOID pWlxContext) + PVOID pWlxContext) { - UNREFERENCED_PARAMETER(pWlxContext); + UNREFERENCED_PARAMETER(pWlxContext); - UNIMPLEMENTED; - return TRUE; + UNIMPLEMENTED; + return TRUE; } @@ -58,11 +58,11 @@ WlxIsLockOk( */ VOID WINAPI WlxLogoff( - PVOID pWlxContext) + PVOID pWlxContext) { - UNREFERENCED_PARAMETER(pWlxContext); + UNREFERENCED_PARAMETER(pWlxContext); - UNIMPLEMENTED; + UNIMPLEMENTED; } @@ -71,13 +71,13 @@ WlxLogoff( */ VOID WINAPI WlxShutdown( - PVOID pWlxContext, - DWORD ShutdownType) + PVOID pWlxContext, + DWORD ShutdownType) { - UNREFERENCED_PARAMETER(pWlxContext); - UNREFERENCED_PARAMETER(ShutdownType); + UNREFERENCED_PARAMETER(pWlxContext); + UNREFERENCED_PARAMETER(ShutdownType); - UNIMPLEMENTED; + UNIMPLEMENTED; } @@ -86,18 +86,18 @@ WlxShutdown( */ BOOL WINAPI WlxGetStatusMessage( - PVOID pWlxContext, - DWORD *pdwOptions, - PWSTR pMessage, - DWORD dwBufferSize) + PVOID pWlxContext, + DWORD *pdwOptions, + PWSTR pMessage, + DWORD dwBufferSize) { - UNREFERENCED_PARAMETER(pWlxContext); - UNREFERENCED_PARAMETER(pdwOptions); - UNREFERENCED_PARAMETER(pMessage); - UNREFERENCED_PARAMETER(dwBufferSize); + UNREFERENCED_PARAMETER(pWlxContext); + UNREFERENCED_PARAMETER(pdwOptions); + UNREFERENCED_PARAMETER(pMessage); + UNREFERENCED_PARAMETER(dwBufferSize); - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } @@ -106,14 +106,14 @@ WlxGetStatusMessage( */ BOOL WINAPI WlxNetworkProviderLoad( - PVOID pWlxContext, - PWLX_MPR_NOTIFY_INFO pNprNotifyInfo) + PVOID pWlxContext, + PWLX_MPR_NOTIFY_INFO pNprNotifyInfo) { - UNREFERENCED_PARAMETER(pWlxContext); - UNREFERENCED_PARAMETER(pNprNotifyInfo); + UNREFERENCED_PARAMETER(pWlxContext); + UNREFERENCED_PARAMETER(pNprNotifyInfo); - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } @@ -122,11 +122,11 @@ WlxNetworkProviderLoad( */ VOID WINAPI WlxDisconnectNotify( - PVOID pWlxContext) + PVOID pWlxContext) { - UNREFERENCED_PARAMETER(pWlxContext); + UNREFERENCED_PARAMETER(pWlxContext); - UNIMPLEMENTED; + UNIMPLEMENTED; } @@ -135,13 +135,13 @@ WlxDisconnectNotify( */ BOOL WINAPI WlxGetConsoleSwitchCredentials( - PVOID pWlxContext, - PVOID pCredInfo) + PVOID pWlxContext, + PVOID pCredInfo) { - UNREFERENCED_PARAMETER(pWlxContext); - UNREFERENCED_PARAMETER(pCredInfo); + UNREFERENCED_PARAMETER(pWlxContext); + UNREFERENCED_PARAMETER(pCredInfo); - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } diff --git a/reactos/dll/win32/msgina/tui.c b/reactos/dll/win32/msgina/tui.c index 6ddb8da6114..81eaa70407a 100644 --- a/reactos/dll/win32/msgina/tui.c +++ b/reactos/dll/win32/msgina/tui.c @@ -11,255 +11,255 @@ WINE_DEFAULT_DEBUG_CHANNEL(msgina); static BOOL TUIInitialize( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - TRACE("TUIInitialize(%p)\n", pgContext); + TRACE("TUIInitialize(%p)\n", pgContext); - return AllocConsole(); + return AllocConsole(); } static BOOL TUIDisplayStatusMessage( - IN PGINA_CONTEXT pgContext, - IN HDESK hDesktop, - IN DWORD dwOptions, - IN PWSTR pTitle, - IN PWSTR pMessage) + IN PGINA_CONTEXT pgContext, + IN HDESK hDesktop, + IN DWORD dwOptions, + IN PWSTR pTitle, + IN PWSTR pMessage) { - static LPCWSTR newLine = L"\n"; - DWORD result; + static LPCWSTR newLine = L"\n"; + DWORD result; - TRACE("TUIDisplayStatusMessage(%ws)\n", pMessage); + TRACE("TUIDisplayStatusMessage(%ws)\n", pMessage); - UNREFERENCED_PARAMETER(pgContext); - UNREFERENCED_PARAMETER(hDesktop); - UNREFERENCED_PARAMETER(dwOptions); - UNREFERENCED_PARAMETER(pTitle); + UNREFERENCED_PARAMETER(pgContext); + UNREFERENCED_PARAMETER(hDesktop); + UNREFERENCED_PARAMETER(dwOptions); + UNREFERENCED_PARAMETER(pTitle); - return - WriteConsoleW( - GetStdHandle(STD_OUTPUT_HANDLE), - pMessage, - wcslen(pMessage), - &result, - NULL) && - WriteConsoleW( - GetStdHandle(STD_OUTPUT_HANDLE), - newLine, - wcslen(newLine), - &result, - NULL); + return + WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + pMessage, + wcslen(pMessage), + &result, + NULL) && + WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + newLine, + wcslen(newLine), + &result, + NULL); } static BOOL TUIRemoveStatusMessage( - IN PGINA_CONTEXT pgContext) + IN PGINA_CONTEXT pgContext) { - UNREFERENCED_PARAMETER(pgContext); + UNREFERENCED_PARAMETER(pgContext); - /* Nothing to do */ - return TRUE; + /* Nothing to do */ + return TRUE; } static BOOL DisplayResourceText( - IN UINT uIdResourceText, - IN BOOL AddNewLine) + IN UINT uIdResourceText, + IN BOOL AddNewLine) { - WCHAR Prompt[256]; - static LPCWSTR newLine = L"\n"; - DWORD count; + WCHAR Prompt[256]; + static LPCWSTR newLine = L"\n"; + DWORD count; - if (0 == LoadStringW(hDllInstance, uIdResourceText, Prompt, 256)) - return FALSE; - if (!WriteConsoleW( - GetStdHandle(STD_OUTPUT_HANDLE), - Prompt, wcslen(Prompt), - &count, NULL)) - { - return FALSE; - } - if (AddNewLine) - { - if (!WriteConsoleW( - GetStdHandle(STD_OUTPUT_HANDLE), - newLine, wcslen(newLine), - &count, NULL)) - { - return FALSE; - } - } - return TRUE; + if (0 == LoadStringW(hDllInstance, uIdResourceText, Prompt, 256)) + return FALSE; + if (!WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + Prompt, wcslen(Prompt), + &count, NULL)) + { + return FALSE; + } + if (AddNewLine) + { + if (!WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + newLine, wcslen(newLine), + &count, NULL)) + { + return FALSE; + } + } + return TRUE; } static VOID TUIDisplaySASNotice( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - TRACE("TUIDisplaySASNotice()\n"); + TRACE("TUIDisplaySASNotice()\n"); - UNREFERENCED_PARAMETER(pgContext); + UNREFERENCED_PARAMETER(pgContext); - DisplayResourceText(IDS_LOGGEDOUTSAS, TRUE); - DisplayResourceText(IDS_PRESSCTRLALTDELETE, TRUE); + DisplayResourceText(IDS_LOGGEDOUTSAS, TRUE); + DisplayResourceText(IDS_PRESSCTRLALTDELETE, TRUE); } static INT TUILoggedOnSAS( - IN OUT PGINA_CONTEXT pgContext, - IN DWORD dwSasType) + IN OUT PGINA_CONTEXT pgContext, + IN DWORD dwSasType) { - TRACE("TUILoggedOnSAS()\n"); + TRACE("TUILoggedOnSAS()\n"); - UNREFERENCED_PARAMETER(pgContext); + UNREFERENCED_PARAMETER(pgContext); - if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL) - { - /* Nothing to do for WLX_SAS_TYPE_TIMEOUT */ - return WLX_SAS_ACTION_NONE; - } + if (dwSasType != WLX_SAS_TYPE_CTRL_ALT_DEL) + { + /* Nothing to do for WLX_SAS_TYPE_TIMEOUT */ + return WLX_SAS_ACTION_NONE; + } - FIXME("FIXME: TUILoggedOnSAS(): Let's suppose the user wants to log off...\n"); - return WLX_SAS_ACTION_LOGOFF; + FIXME("FIXME: TUILoggedOnSAS(): Let's suppose the user wants to log off...\n"); + return WLX_SAS_ACTION_LOGOFF; } static BOOL ReadString( - IN UINT uIdResourcePrompt, - IN OUT PWSTR Buffer, - IN DWORD BufferLength, - IN BOOL ShowString) + IN UINT uIdResourcePrompt, + IN OUT PWSTR Buffer, + IN DWORD BufferLength, + IN BOOL ShowString) { - DWORD count, i; - WCHAR charToDisplay[] = { 0, UNICODE_NULL }; + DWORD count, i; + WCHAR charToDisplay[] = { 0, UNICODE_NULL }; - if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0)) - return FALSE; + if (!SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), 0)) + return FALSE; - if (!FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE))) - return FALSE; + if (!FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE))) + return FALSE; - if (!DisplayResourceText(uIdResourcePrompt, FALSE)) - return FALSE; + if (!DisplayResourceText(uIdResourcePrompt, FALSE)) + return FALSE; - i = 0; - for (;;) - { - WCHAR readChar; - if (!ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), &readChar, 1, &count, NULL)) - return FALSE; - if (readChar == '\r' || readChar == '\n') - { - /* End of string */ - charToDisplay[0] = L'\n'; - WriteConsoleW( - GetStdHandle(STD_OUTPUT_HANDLE), - charToDisplay, - wcslen(charToDisplay), - &count, - NULL); - break; - } - if (ShowString) - { - /* Display the char */ - charToDisplay[0] = readChar; - WriteConsoleW( - GetStdHandle(STD_OUTPUT_HANDLE), - charToDisplay, - wcslen(charToDisplay), - &count, - NULL); - } - Buffer[i++] = readChar; - /* FIXME: buffer overflow if the user writes too many chars! */ - UNREFERENCED_PARAMETER(BufferLength); - /* FIXME: handle backspace */ - } - Buffer[i] = UNICODE_NULL; + i = 0; + for (;;) + { + WCHAR readChar; + if (!ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), &readChar, 1, &count, NULL)) + return FALSE; + if (readChar == '\r' || readChar == '\n') + { + /* End of string */ + charToDisplay[0] = L'\n'; + WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + charToDisplay, + wcslen(charToDisplay), + &count, + NULL); + break; + } + if (ShowString) + { + /* Display the char */ + charToDisplay[0] = readChar; + WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + charToDisplay, + wcslen(charToDisplay), + &count, + NULL); + } + Buffer[i++] = readChar; + /* FIXME: buffer overflow if the user writes too many chars! */ + UNREFERENCED_PARAMETER(BufferLength); + /* FIXME: handle backspace */ + } + Buffer[i] = UNICODE_NULL; - if (!ShowString) - { - /* Still display the \n */ - static LPCWSTR newLine = L"\n"; - DWORD result; - WriteConsoleW( - GetStdHandle(STD_OUTPUT_HANDLE), - newLine, - wcslen(newLine), - &result, - NULL); - } - return TRUE; + if (!ShowString) + { + /* Still display the \n */ + static LPCWSTR newLine = L"\n"; + DWORD result; + WriteConsoleW( + GetStdHandle(STD_OUTPUT_HANDLE), + newLine, + wcslen(newLine), + &result, + NULL); + } + return TRUE; } static INT TUILoggedOutSAS( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - WCHAR UserName[256]; - WCHAR Password[256]; + WCHAR UserName[256]; + WCHAR Password[256]; - TRACE("TUILoggedOutSAS()\n"); + TRACE("TUILoggedOutSAS()\n"); - /* Ask the user for credentials */ - if (!ReadString(IDS_ASKFORUSER, UserName, 256, TRUE)) - return WLX_SAS_ACTION_NONE; - if (!ReadString(IDS_ASKFORPASSWORD, Password, 256, FALSE)) - return WLX_SAS_ACTION_NONE; + /* Ask the user for credentials */ + if (!ReadString(IDS_ASKFORUSER, UserName, 256, TRUE)) + return WLX_SAS_ACTION_NONE; + if (!ReadString(IDS_ASKFORPASSWORD, Password, 256, FALSE)) + return WLX_SAS_ACTION_NONE; - if (DoLoginTasks(pgContext, UserName, NULL, Password)) - return WLX_SAS_ACTION_LOGON; - else - return WLX_SAS_ACTION_NONE; + if (DoLoginTasks(pgContext, UserName, NULL, Password)) + return WLX_SAS_ACTION_LOGON; + else + return WLX_SAS_ACTION_NONE; } static INT TUILockedSAS( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { - HANDLE hToken; - WCHAR UserName[256]; - WCHAR Password[256]; + HANDLE hToken; + WCHAR UserName[256]; + WCHAR Password[256]; - TRACE("TUILockedSAS()\n"); + TRACE("TUILockedSAS()\n"); - UNREFERENCED_PARAMETER(pgContext); + UNREFERENCED_PARAMETER(pgContext); - if (!DisplayResourceText(IDS_LOGGEDOUTSAS, TRUE)) - return WLX_SAS_ACTION_UNLOCK_WKSTA; + if (!DisplayResourceText(IDS_LOGGEDOUTSAS, TRUE)) + return WLX_SAS_ACTION_UNLOCK_WKSTA; - /* Ask the user for credentials */ - if (!ReadString(IDS_ASKFORUSER, UserName, 256, TRUE)) - return WLX_SAS_ACTION_NONE; - if (!ReadString(IDS_ASKFORPASSWORD, Password, 256, FALSE)) - return WLX_SAS_ACTION_NONE; + /* Ask the user for credentials */ + if (!ReadString(IDS_ASKFORUSER, UserName, 256, TRUE)) + return WLX_SAS_ACTION_NONE; + if (!ReadString(IDS_ASKFORPASSWORD, Password, 256, FALSE)) + return WLX_SAS_ACTION_NONE; - if (!LogonUserW(UserName, NULL, Password, - LOGON32_LOGON_UNLOCK, - LOGON32_PROVIDER_DEFAULT, - &hToken)) - { - TRACE("LogonUserW() failed\n"); - return WLX_SAS_ACTION_NONE; - } - CloseHandle(hToken); - return WLX_SAS_ACTION_UNLOCK_WKSTA; + if (!LogonUserW(UserName, NULL, Password, + LOGON32_LOGON_UNLOCK, + LOGON32_PROVIDER_DEFAULT, + &hToken)) + { + TRACE("LogonUserW() failed\n"); + return WLX_SAS_ACTION_NONE; + } + CloseHandle(hToken); + return WLX_SAS_ACTION_UNLOCK_WKSTA; } static VOID TUIDisplayLockedNotice( - IN OUT PGINA_CONTEXT pgContext) + IN OUT PGINA_CONTEXT pgContext) { } GINA_UI GinaTextUI = { - TUIInitialize, - TUIDisplayStatusMessage, - TUIRemoveStatusMessage, - TUIDisplaySASNotice, - TUILoggedOnSAS, - TUILoggedOutSAS, - TUILockedSAS, - TUIDisplayLockedNotice, + TUIInitialize, + TUIDisplayStatusMessage, + TUIRemoveStatusMessage, + TUIDisplaySASNotice, + TUILoggedOnSAS, + TUILoggedOutSAS, + TUILockedSAS, + TUIDisplayLockedNotice, }; From 018f8110912d5b1bb1a1280726c98158c163cd32 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 8 May 2013 10:26:24 +0000 Subject: [PATCH 63/67] [XDK/DDK] * The event parameter in IoBuildDeviceIoControlRequest is optional. Spotted by Nikolay Borisov. CORE-7172 #resolve svn path=/trunk/; revision=58965 --- reactos/include/ddk/wdm.h | 2 +- reactos/include/xdk/iofuncs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/include/ddk/wdm.h b/reactos/include/ddk/wdm.h index 86f90b2fcfc..7be0457196b 100644 --- a/reactos/include/ddk/wdm.h +++ b/reactos/include/ddk/wdm.h @@ -12603,7 +12603,7 @@ IoBuildDeviceIoControlRequest( _Out_opt_ PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl, - _In_ PKEVENT Event, + _In_opt_ PKEVENT Event, _Out_ PIO_STATUS_BLOCK IoStatusBlock); _IRQL_requires_max_(DISPATCH_LEVEL) diff --git a/reactos/include/xdk/iofuncs.h b/reactos/include/xdk/iofuncs.h index 98ec1500558..3059cb85890 100644 --- a/reactos/include/xdk/iofuncs.h +++ b/reactos/include/xdk/iofuncs.h @@ -716,7 +716,7 @@ IoBuildDeviceIoControlRequest( _Out_opt_ PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl, - _In_ PKEVENT Event, + _In_opt_ PKEVENT Event, _Out_ PIO_STATUS_BLOCK IoStatusBlock); _IRQL_requires_max_(DISPATCH_LEVEL) From 90cb6ce333d8897d4b265c1ad832d3a1519446cf Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 8 May 2013 10:55:46 +0000 Subject: [PATCH 64/67] [AFD] * Add some function annotations. * Fix several debug print specifiers. * Properly mark some unreferenced parameters as such. * This fixes several warnings emitted by the MSVC static analyzer. * Brought to you by Nikolay Borisov, with minor consistency styling changes by me. CORE-7171 svn path=/trunk/; revision=58966 --- reactos/drivers/network/afd/afd/bind.c | 4 +- reactos/drivers/network/afd/afd/connect.c | 27 ++++++++++--- reactos/drivers/network/afd/afd/context.c | 6 +++ reactos/drivers/network/afd/afd/info.c | 15 +++++-- reactos/drivers/network/afd/afd/listen.c | 27 ++++++++----- reactos/drivers/network/afd/afd/lock.c | 12 ++++-- reactos/drivers/network/afd/afd/main.c | 48 +++++++++++++++++------ reactos/drivers/network/afd/afd/read.c | 48 +++++++++++++---------- reactos/drivers/network/afd/afd/select.c | 32 +++++++++------ reactos/drivers/network/afd/afd/tdi.c | 34 ++++++++-------- reactos/drivers/network/afd/afd/write.c | 31 ++++++++++----- reactos/drivers/network/afd/include/afd.h | 16 ++------ 12 files changed, 195 insertions(+), 105 deletions(-) diff --git a/reactos/drivers/network/afd/afd/bind.c b/reactos/drivers/network/afd/afd/bind.c index 0c5b33d69ce..ec895faaf5d 100644 --- a/reactos/drivers/network/afd/afd/bind.c +++ b/reactos/drivers/network/afd/afd/bind.c @@ -13,7 +13,7 @@ NTSTATUS WarmSocketForBind( PAFD_FCB FCB, ULONG ShareType ) { NTSTATUS Status; - AFD_DbgPrint(MID_TRACE,("Called (AF %d)\n", + AFD_DbgPrint(MID_TRACE,("Called (AF %u)\n", FCB->LocalAddress->Address[0].AddressType)); if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) { @@ -78,6 +78,8 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PAFD_BIND_DATA BindReq; + UNREFERENCED_PARAMETER(DeviceObject); + AFD_DbgPrint(MID_TRACE,("Called\n")); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); diff --git a/reactos/drivers/network/afd/afd/connect.c b/reactos/drivers/network/afd/afd/connect.c index 36dd2907dcc..bd394a3abc2 100644 --- a/reactos/drivers/network/afd/afd/connect.c +++ b/reactos/drivers/network/afd/afd/connect.c @@ -18,6 +18,8 @@ AfdGetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (FCB->ConnectOptionsSize == 0) @@ -47,6 +49,8 @@ AfdSetConnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID ConnectOptions = LockRequest(Irp, IrpSp, FALSE, NULL); UINT ConnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!ConnectOptions) @@ -83,6 +87,8 @@ AfdSetConnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PUINT ConnectOptionsSize = LockRequest(Irp, IrpSp, FALSE, NULL); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!ConnectOptionsSize) @@ -118,6 +124,8 @@ AfdGetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (FCB->ConnectDataSize == 0) @@ -147,6 +155,8 @@ AfdSetConnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID ConnectData = LockRequest(Irp, IrpSp, FALSE, NULL); UINT ConnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!ConnectData) @@ -182,6 +192,8 @@ AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PUINT ConnectDataSize = LockRequest(Irp, IrpSp, FALSE, NULL); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!ConnectDataSize) @@ -287,6 +299,7 @@ MakeSocketIntoConnection(PAFD_FCB FCB) { return Status; } +static IO_COMPLETION_ROUTINE StreamSocketConnectComplete; static NTSTATUS NTAPI @@ -297,7 +310,7 @@ StreamSocketConnectComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PLIST_ENTRY NextIrpEntry; PIRP NextIrp; - AFD_DbgPrint(MID_TRACE,("Called: FCB %x, FO %x\n", + AFD_DbgPrint(MID_TRACE,("Called: FCB %p, FO %p\n", Context, FCB->FileObject)); /* I was wrong about this before as we can have pending writes to a not @@ -338,7 +351,7 @@ StreamSocketConnectComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); - AFD_DbgPrint(MID_TRACE,("Completing connect %x\n", NextIrp)); + AFD_DbgPrint(MID_TRACE,("Completing connect %p\n", NextIrp)); NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); @@ -374,7 +387,7 @@ StreamSocketConnectComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); - AFD_DbgPrint(MID_TRACE,("Launching send request %x\n", NextIrp)); + AFD_DbgPrint(MID_TRACE,("Launching send request %p\n", NextIrp)); Status = AfdConnectedSocketWriteData ( DeviceObject, NextIrp, @@ -403,7 +416,9 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PAFD_CONNECT_INFO ConnectReq; - AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); + AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); + + UNREFERENCED_PARAMETER(DeviceObject); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); if( !(ConnectReq = LockRequest( Irp, IrpSp, FALSE, NULL )) ) @@ -494,7 +509,7 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->State = SOCKET_STATE_CONNECTING; - AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp)); + AFD_DbgPrint(MID_TRACE,("Queueing IRP %p\n", Irp)); Status = QueueUserModeIrp( FCB, Irp, FUNCTION_CONNECT ); if (Status == STATUS_PENDING) { @@ -517,7 +532,7 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, break; default: - AFD_DbgPrint(MIN_TRACE,("Inappropriate socket state %d for connect\n", + AFD_DbgPrint(MIN_TRACE,("Inappropriate socket state %u for connect\n", FCB->State)); break; } diff --git a/reactos/drivers/network/afd/afd/context.c b/reactos/drivers/network/afd/afd/context.c index 9dec195c079..5cc8ac766bc 100644 --- a/reactos/drivers/network/afd/afd/context.c +++ b/reactos/drivers/network/afd/afd/context.c @@ -17,6 +17,8 @@ AfdGetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; UINT ContextSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); if( FCB->ContextSize < ContextSize ) ContextSize = FCB->ContextSize; @@ -40,6 +42,8 @@ AfdGetContextSize( PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; + UNREFERENCED_PARAMETER(DeviceObject); + if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) @@ -62,6 +66,8 @@ AfdSetContext( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PVOID Context = LockRequest(Irp, IrpSp, FALSE, NULL); + UNREFERENCED_PARAMETER(DeviceObject); + if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); if (!Context) diff --git a/reactos/drivers/network/afd/afd/info.c b/reactos/drivers/network/afd/afd/info.c index 68cbe2e4bcf..e92acb8e7f1 100644 --- a/reactos/drivers/network/afd/afd/info.c +++ b/reactos/drivers/network/afd/afd/info.c @@ -18,7 +18,9 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PLIST_ENTRY CurrentEntry; - AFD_DbgPrint(MID_TRACE,("Called %x %x\n", InfoReq, + UNREFERENCED_PARAMETER(DeviceObject); + + AFD_DbgPrint(MID_TRACE,("Called %p %x\n", InfoReq, InfoReq ? InfoReq->InformationClass : 0)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); @@ -34,13 +36,13 @@ AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, case AFD_INFO_SEND_WINDOW_SIZE: InfoReq->Information.Ulong = FCB->Send.Size; - AFD_DbgPrint(MID_TRACE,("Send window size %d\n", FCB->Send.Size)); + AFD_DbgPrint(MID_TRACE,("Send window size %u\n", FCB->Send.Size)); break; case AFD_INFO_GROUP_ID_TYPE: InfoReq->Information.LargeInteger.u.HighPart = FCB->GroupType; InfoReq->Information.LargeInteger.u.LowPart = FCB->GroupID; - AFD_DbgPrint(MID_TRACE, ("Group ID: %d Group Type: %d\n", FCB->GroupID, FCB->GroupType)); + AFD_DbgPrint(MID_TRACE, ("Group ID: %u Group Type: %u\n", FCB->GroupID, FCB->GroupType)); break; case AFD_INFO_BLOCKING_MODE: @@ -104,6 +106,8 @@ AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PCHAR NewBuffer; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!InfoReq) @@ -171,7 +175,7 @@ AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, } break; default: - AFD_DbgPrint(MIN_TRACE,("Unknown request %d\n", InfoReq->InformationClass)); + AFD_DbgPrint(MIN_TRACE,("Unknown request %u\n", InfoReq->InformationClass)); break; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -192,6 +196,8 @@ AfdGetSockName( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PMDL Mdl = NULL; + UNREFERENCED_PARAMETER(DeviceObject); + if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); if( FCB->AddressFile.Object == NULL && FCB->Connection.Object == NULL ) { @@ -232,6 +238,7 @@ AfdGetPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; + UNREFERENCED_PARAMETER(DeviceObject); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); diff --git a/reactos/drivers/network/afd/afd/listen.c b/reactos/drivers/network/afd/afd/listen.c index 5c17fe05dd8..00f8e7537df 100644 --- a/reactos/drivers/network/afd/afd/listen.c +++ b/reactos/drivers/network/afd/afd/listen.c @@ -16,11 +16,13 @@ static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt, PAFD_FCB FCB = NewFileObject->FsContext; NTSTATUS Status; + UNREFERENCED_PARAMETER(DeviceExt); + if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); /* Transfer the connection to the new socket, launch the opening read */ - AFD_DbgPrint(MID_TRACE,("Completing a real accept (FCB %x)\n", FCB)); + AFD_DbgPrint(MID_TRACE,("Completing a real accept (FCB %p)\n", FCB)); FCB->Connection = Qelt->Object; @@ -49,8 +51,8 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) { ListenReceive->SequenceNumber = Qelt->Seq; - AFD_DbgPrint(MID_TRACE,("Giving SEQ %d to userland\n", Qelt->Seq)); - AFD_DbgPrint(MID_TRACE,("Socket Address (K) %x (U) %x\n", + AFD_DbgPrint(MID_TRACE,("Giving SEQ %u to userland\n", Qelt->Seq)); + AFD_DbgPrint(MID_TRACE,("Socket Address (K) %p (U) %p\n", &ListenReceive->Address, Qelt->ConnInfo->RemoteAddress)); @@ -61,9 +63,9 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) { AFD_DbgPrint(MID_TRACE,("IPAddr->TAAddressCount %d\n", IPAddr->TAAddressCount)); - AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressType %d\n", + AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressType %u\n", IPAddr->Address[0].AddressType)); - AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressLength %d\n", + AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressLength %u\n", IPAddr->Address[0].AddressLength)); AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_port %x\n", IPAddr->Address[0].Address[0].sin_port)); @@ -79,6 +81,7 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) { return STATUS_SUCCESS; } +static IO_COMPLETION_ROUTINE ListenComplete; static NTSTATUS NTAPI ListenComplete( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { @@ -88,6 +91,8 @@ static NTSTATUS NTAPI ListenComplete( PDEVICE_OBJECT DeviceObject, PLIST_ENTRY NextIrpEntry; PIRP NextIrp; + UNREFERENCED_PARAMETER(DeviceObject); + if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; @@ -141,7 +146,7 @@ static NTSTATUS NTAPI ListenComplete( PDEVICE_OBJECT DeviceObject, Qelt->Object = FCB->Connection; Qelt->Seq = FCB->ConnSeq++; - AFD_DbgPrint(MID_TRACE,("Address Type: %d (RA %x)\n", + AFD_DbgPrint(MID_TRACE,("Address Type: %u (RA %p)\n", AddressType, FCB->ListenIrp. ConnectionReturnInfo->RemoteAddress)); @@ -213,7 +218,9 @@ NTSTATUS AfdListenSocket( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; PAFD_LISTEN_DATA ListenReq; - AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); + UNREFERENCED_PARAMETER(DeviceObject); + + AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); @@ -229,7 +236,7 @@ NTSTATUS AfdListenSocket( PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->DelayedAccept = ListenReq->UseDelayedAcceptance; - AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle)); + AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %p\n", FCB->AddressFile.Handle)); Status = WarmSocketForConnection( FCB ); @@ -277,6 +284,8 @@ NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; NTSTATUS Status; + UNREFERENCED_PARAMETER(DeviceObject); + AFD_DbgPrint(MID_TRACE,("Called\n")); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); @@ -335,7 +344,7 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_TDI_OBJECT_QELT PendingConnObj = CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry ); - AFD_DbgPrint(MID_TRACE,("Comparing Seq %d to Q %d\n", + AFD_DbgPrint(MID_TRACE,("Comparing Seq %u to Q %u\n", AcceptData->SequenceNumber, PendingConnObj->Seq)); diff --git a/reactos/drivers/network/afd/afd/lock.c b/reactos/drivers/network/afd/afd/lock.c index 4fcfba0a471..dee5b71c3da 100644 --- a/reactos/drivers/network/afd/afd/lock.c +++ b/reactos/drivers/network/afd/afd/lock.c @@ -14,6 +14,8 @@ PVOID GetLockedData(PIRP Irp, PIO_STACK_LOCATION IrpSp) ASSERT(Irp->MdlAddress); ASSERT(Irp->Tail.Overlay.DriverContext[0]); + UNREFERENCED_PARAMETER(IrpSp); + return Irp->Tail.Overlay.DriverContext[0]; } @@ -173,6 +175,8 @@ VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) ASSERT(Irp->MdlAddress); ASSERT(Irp->Tail.Overlay.DriverContext[0]); + UNREFERENCED_PARAMETER(IrpSp); + /* Check if we need to copy stuff back */ if (Irp->Tail.Overlay.DriverContext[1] != NULL) { @@ -203,7 +207,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, BOOLEAN LockFailed = FALSE; PAFD_MAPBUF MapBuf; - AFD_DbgPrint(MID_TRACE,("Called(%08x)\n", NewBuf)); + AFD_DbgPrint(MID_TRACE,("Called(%p)\n", NewBuf)); if( NewBuf ) { RtlZeroMemory(NewBuf, Size); @@ -223,14 +227,14 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { AFD_DbgPrint(MIN_TRACE,("Access violation copying buffer info " - "from userland (%x %x)\n", + "from userland (%p %p)\n", Buf, AddressLen)); ExFreePool( NewBuf ); _SEH2_YIELD(return NULL); } _SEH2_END; for( i = 0; i < Count; i++ ) { - AFD_DbgPrint(MID_TRACE,("Locking buffer %d (%x:%d)\n", + AFD_DbgPrint(MID_TRACE,("Locking buffer %u (%p:%u)\n", i, NewBuf[i].buf, NewBuf[i].len)); if( NewBuf[i].buf && NewBuf[i].len ) { @@ -244,7 +248,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, continue; } - AFD_DbgPrint(MID_TRACE,("NewMdl @ %x\n", MapBuf[i].Mdl)); + AFD_DbgPrint(MID_TRACE,("NewMdl @ %p\n", MapBuf[i].Mdl)); if( MapBuf[i].Mdl ) { AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n")); diff --git a/reactos/drivers/network/afd/afd/main.c b/reactos/drivers/network/afd/afd/main.c index 4fa43c82309..97da39ba500 100644 --- a/reactos/drivers/network/afd/afd/main.c +++ b/reactos/drivers/network/afd/afd/main.c @@ -46,6 +46,8 @@ AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (FCB->DisconnectOptionsSize == 0) @@ -75,6 +77,8 @@ AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID DisconnectOptions = LockRequest(Irp, IrpSp, FALSE, NULL); UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!DisconnectOptions) @@ -111,6 +115,8 @@ AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PUINT DisconnectOptionsSize = LockRequest(Irp, IrpSp, FALSE, NULL); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!DisconnectOptionsSize) @@ -145,6 +151,8 @@ AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_FCB FCB = FileObject->FsContext; UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (FCB->DisconnectDataSize == 0) @@ -175,6 +183,8 @@ AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID DisconnectData = LockRequest(Irp, IrpSp, FALSE, NULL); UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!DisconnectData) @@ -211,6 +221,8 @@ AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp, PUINT DisconnectDataSize = LockRequest(Irp, IrpSp, FALSE, NULL); UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!DisconnectDataSize) @@ -247,6 +259,8 @@ AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp, PULONG HandleFlags = LockRequest(Irp, IrpSp, TRUE, NULL); PAFD_TDI_HANDLE_DATA HandleData = Irp->UserBuffer; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!HandleFlags) @@ -299,7 +313,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, //EaLength = sizeof(FILE_FULL_EA_INFORMATION) + EaInfo->EaNameLength + EaInfo->EaValueLength; - AFD_DbgPrint(MID_TRACE,("EaInfo: %x, EaInfoValue: %x\n", + AFD_DbgPrint(MID_TRACE,("EaInfo: %p, EaInfoValue: %p\n", EaInfo, EaInfoValue)); } @@ -312,7 +326,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, return STATUS_NO_MEMORY; } - AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n", + AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %p (FileObject %p Flags %x)\n", FCB, FileObject, ConnectInfo ? ConnectInfo->EndpointFlags : 0)); RtlZeroMemory( FCB, sizeof( *FCB ) ); @@ -335,7 +349,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, InitializeListHead( &FCB->DatagramList ); InitializeListHead( &FCB->PendingConnections ); - AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB)); + AFD_DbgPrint(MID_TRACE,("%p: Checking command channel\n", FCB)); if( ConnectInfo ) { FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName; @@ -395,6 +409,8 @@ AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, UINT Function; PIRP CurrentIrp; + UNREFERENCED_PARAMETER(DeviceObject); + if( !SocketAcquireStateLock( FCB ) ) return LostSocket(Irp); for (Function = 0; Function < MAX_FUNCTIONS; Function++) @@ -445,7 +461,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, /* Cancel our pending requests */ for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) { if( InFlightRequest[i]->InFlightRequest ) { - AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n", + AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %u (%p)\n", i, InFlightRequest[i]->InFlightRequest)); IoCancelIrp(InFlightRequest[i]->InFlightRequest); } @@ -526,7 +542,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, { if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE) { - DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB->AddressFile.Handle, FCB->AddressFile.Object); + DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %p %p\n", FCB->AddressFile.Handle, FCB->AddressFile.Object); } } @@ -534,7 +550,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, { if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE) { - DbgPrint("INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB->Connection.Handle, FCB->Connection.Object); + DbgPrint("INVALID CONNECTION HANDLE VALUE: %p %p\n", FCB->Connection.Handle, FCB->Connection.Object); } } @@ -552,6 +568,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, return STATUS_SUCCESS; } +static IO_COMPLETION_ROUTINE DisconnectComplete; static NTSTATUS NTAPI @@ -563,6 +580,8 @@ DisconnectComplete(PDEVICE_OBJECT DeviceObject, PIRP CurrentIrp; PLIST_ENTRY CurrentEntry; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return STATUS_FILE_CLOSED; @@ -679,6 +698,8 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PLIST_ENTRY CurrentEntry; PIRP CurrentIrp; + UNREFERENCED_PARAMETER(DeviceObject); + if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); if (!(DisReq = LockRequest(Irp, IrpSp, FALSE, NULL))) @@ -809,6 +830,7 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); } +static DRIVER_DISPATCH AfdDispatch; static NTSTATUS NTAPI AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { @@ -818,9 +840,9 @@ AfdDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) PFILE_OBJECT FileObject = IrpSp->FileObject; #endif - AFD_DbgPrint(MID_TRACE,("AfdDispatch: %d\n", IrpSp->MajorFunction)); + AFD_DbgPrint(MID_TRACE,("AfdDispatch: %u\n", IrpSp->MajorFunction)); if( IrpSp->MajorFunction != IRP_MJ_CREATE) { - AFD_DbgPrint(MID_TRACE,("FO %x, IrpSp->FO %x\n", + AFD_DbgPrint(MID_TRACE,("FO %p, IrpSp->FO %p\n", FileObject, IrpSp->FileObject)); ASSERT(FileObject == IrpSp->FileObject); } @@ -1082,7 +1104,8 @@ CleanupPendingIrp(PAFD_FCB FCB, PIRP Irp, PIO_STACK_LOCATION IrpSp, PAFD_ACTIVE_ } } -VOID NTAPI +VOID +NTAPI AfdCancelHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) { @@ -1199,12 +1222,14 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject, SocketStateUnlock(FCB); - DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %d)\n", Function); + DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (Function: %u)\n", Function); } +static DRIVER_UNLOAD AfdUnload; static VOID NTAPI AfdUnload(PDRIVER_OBJECT DriverObject) { + UNREFERENCED_PARAMETER(DriverObject); } NTSTATUS NTAPI @@ -1215,6 +1240,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) PAFD_DEVICE_EXTENSION DeviceExt; NTSTATUS Status; + UNREFERENCED_PARAMETER(RegistryPath); /* register driver routines */ DriverObject->MajorFunction[IRP_MJ_CLOSE] = AfdDispatch; DriverObject->MajorFunction[IRP_MJ_CREATE] = AfdDispatch; @@ -1242,7 +1268,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) KeInitializeSpinLock( &DeviceExt->Lock ); InitializeListHead( &DeviceExt->Polls ); - AFD_DbgPrint(MID_TRACE,("Device created: object %x ext %x\n", + AFD_DbgPrint(MID_TRACE,("Device created: object %p ext %p\n", DeviceObject, DeviceExt)); return Status; diff --git a/reactos/drivers/network/afd/afd/read.c b/reactos/drivers/network/afd/afd/read.c index 090aed0c072..9ba5c31fe13 100644 --- a/reactos/drivers/network/afd/afd/read.c +++ b/reactos/drivers/network/afd/afd/read.c @@ -101,15 +101,14 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, *TotalBytesCopied = 0; - AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n", - BytesAvailable)); + AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %u\n", BytesAvailable)); if( CantReadMore(FCB) ) return STATUS_SUCCESS; if( !BytesAvailable ) return STATUS_PENDING; Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount); - AFD_DbgPrint(MID_TRACE,("Buffer Count: %d @ %x\n", + AFD_DbgPrint(MID_TRACE,("Buffer Count: %u @ %p\n", RecvReq->BufferCount, RecvReq->BufferArray)); for( i = 0; @@ -123,7 +122,7 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, if( Map[i].Mdl ) { Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode ); - AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n", + AFD_DbgPrint(MID_TRACE,("Buffer %u: %p:%u\n", i, Map[i].BufferAddress, BytesToCopy)); @@ -157,9 +156,9 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { UINT TotalBytesCopied = 0, RetBytesCopied = 0; NTSTATUS Status = STATUS_SUCCESS, RetStatus = STATUS_PENDING; - AFD_DbgPrint(MID_TRACE,("%x %x\n", FCB, Irp)); + AFD_DbgPrint(MID_TRACE,("%p %p\n", FCB, Irp)); - AFD_DbgPrint(MID_TRACE,("FCB %x Receive data waiting %d\n", + AFD_DbgPrint(MID_TRACE,("FCB %p Receive data waiting %u\n", FCB, FCB->Recv.Content)); if( CantReadMore( FCB ) ) { @@ -172,7 +171,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); RecvReq = GetLockedData(NextIrp, NextIrpSp); - AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, + AFD_DbgPrint(MID_TRACE,("Completing recv %p (%u)\n", NextIrp, TotalBytesCopied)); UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE ); @@ -198,7 +197,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { /* Kick the user that receive would be possible now */ /* XXX Not implemented yet */ - AFD_DbgPrint(MID_TRACE,("FCB %x Receive data waiting %d\n", + AFD_DbgPrint(MID_TRACE,("FCB %p Receive data waiting %u\n", FCB, FCB->Recv.Content)); /*OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );*/ @@ -209,18 +208,18 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); RecvReq = GetLockedData(NextIrp, NextIrpSp); - AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq)); + AFD_DbgPrint(MID_TRACE,("RecvReq @ %p\n", RecvReq)); Status = TryToSatisfyRecvRequestFromBuffer ( FCB, RecvReq, &TotalBytesCopied ); if( Status == STATUS_PENDING ) { - AFD_DbgPrint(MID_TRACE,("Ran out of data for %x\n", NextIrp)); + AFD_DbgPrint(MID_TRACE,("Ran out of data for %p\n", NextIrp)); InsertHeadList(&FCB->PendingIrpList[FUNCTION_RECV], &NextIrp->Tail.Overlay.ListEntry); break; } else { - AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, + AFD_DbgPrint(MID_TRACE,("Completing recv %p (%u)\n", NextIrp, TotalBytesCopied)); UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE ); @@ -263,7 +262,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { PollReeval(FCB->DeviceExt, FCB->FileObject); } - AFD_DbgPrint(MID_TRACE,("RetStatus for irp %x is %x\n", Irp, RetStatus)); + AFD_DbgPrint(MID_TRACE,("RetStatus for irp %p is %x\n", Irp, RetStatus)); /* Sometimes we're called with a NULL Irp */ if( Irp ) { @@ -284,6 +283,8 @@ NTSTATUS NTAPI ReceiveComplete PAFD_RECV_INFO RecvReq; PIO_STACK_LOCATION NextIrpSp; + UNREFERENCED_PARAMETER(DeviceObject); + AFD_DbgPrint(MID_TRACE,("Called\n")); if( !SocketAcquireStateLock( FCB ) ) @@ -341,7 +342,7 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp, BytesToCopy = MIN( RecvReq->BufferArray[0].len, BytesAvailable ); - AFD_DbgPrint(MID_TRACE,("BytesToCopy: %d len %d\n", BytesToCopy, + AFD_DbgPrint(MID_TRACE,("BytesToCopy: %u len %u\n", BytesToCopy, RecvReq->BufferArray[0].len)); if( Map[0].Mdl ) { @@ -362,7 +363,7 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp, sizeof(USHORT), RecvReq->BufferArray[1].len); - AFD_DbgPrint(MID_TRACE,("Copying %d bytes of address\n", AddrLen)); + AFD_DbgPrint(MID_TRACE,("Copying %u bytes of address\n", AddrLen)); Map[1].BufferAddress = MmMapLockedPages( Map[1].Mdl, KernelMode ); @@ -385,7 +386,7 @@ SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp, Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode ); - AFD_DbgPrint(MID_TRACE,("Buffer %d: %x:%d\n", + AFD_DbgPrint(MID_TRACE,("Buffer %d: %p:%u\n", 0, Map[0].BufferAddress, BytesToCopy)); @@ -436,7 +437,10 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PLIST_ENTRY ListEntry; KPROCESSOR_MODE LockMode; - AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Short); + + AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); @@ -558,7 +562,9 @@ PacketSocketRecvComplete( UINT DGSize = Irp->IoStatus.Information + sizeof( AFD_STORED_DATAGRAM ); PLIST_ENTRY NextIrpEntry, DatagramRecvEntry; - AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); + UNREFERENCED_PARAMETER(DeviceObject); + + AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; @@ -611,7 +617,7 @@ PacketSocketRecvComplete( DatagramRecv->Len = Irp->IoStatus.Information; RtlCopyMemory( DatagramRecv->Buffer, FCB->Recv.Window, DatagramRecv->Len ); - AFD_DbgPrint(MID_TRACE,("Received (A %x)\n", + AFD_DbgPrint(MID_TRACE,("Received (A %p)\n", FCB->AddressFrom->RemoteAddress)); DatagramRecv->Address = TaCopyTransportAddress( FCB->AddressFrom->RemoteAddress ); @@ -642,7 +648,7 @@ PacketSocketRecvComplete( NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); RecvReq = GetLockedData(NextIrp, NextIrpSp); - AFD_DbgPrint(MID_TRACE,("RecvReq: %x, DatagramRecv: %x\n", + AFD_DbgPrint(MID_TRACE,("RecvReq: %p, DatagramRecv: %p\n", RecvReq, DatagramRecv)); AFD_DbgPrint(MID_TRACE,("Satisfying\n")); @@ -705,7 +711,9 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_STORED_DATAGRAM DatagramRecv; KPROCESSOR_MODE LockMode; - AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); + UNREFERENCED_PARAMETER(DeviceObject); + + AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); diff --git a/reactos/drivers/network/afd/afd/select.c b/reactos/drivers/network/afd/afd/select.c index ceda022ed49..9af7ae57722 100644 --- a/reactos/drivers/network/afd/afd/select.c +++ b/reactos/drivers/network/afd/afd/select.c @@ -101,6 +101,10 @@ static VOID SelectTimeout( PKDPC Dpc, KIRQL OldIrql; PAFD_DEVICE_EXTENSION DeviceExt; + UNREFERENCED_PARAMETER(Dpc); + UNREFERENCED_PARAMETER(SystemArgument1); + UNREFERENCED_PARAMETER(SystemArgument2); + AFD_DbgPrint(MID_TRACE,("Called\n")); Irp = Poll->Irp; @@ -127,7 +131,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, PAFD_HANDLE HandleArray; UINT i; - AFD_DbgPrint(MID_TRACE,("Killing selects that refer to %x\n", FileObject)); + AFD_DbgPrint(MID_TRACE,("Killing selects that refer to %p\n", FileObject)); KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql ); @@ -140,7 +144,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, HandleArray = AFD_HANDLES(PollReq); for( i = 0; i < PollReq->HandleCount; i++ ) { - AFD_DbgPrint(MAX_TRACE,("Req: %x, This %x\n", + AFD_DbgPrint(MAX_TRACE,("Req: %p, This %p\n", HandleArray[i].Handle, FileObject)); if( (PVOID)HandleArray[i].Handle == FileObject && (!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) { @@ -167,7 +171,9 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, UINT i, Signalled = 0; ULONG Exclusive = PollReq->Exclusive; - AFD_DbgPrint(MID_TRACE,("Called (HandleCount %d Timeout %d)\n", + UNREFERENCED_PARAMETER(IrpSp); + + AFD_DbgPrint(MID_TRACE,("Called (HandleCount %u Timeout %d)\n", PollReq->HandleCount, (INT)(PollReq->Timeout.QuadPart))); @@ -206,7 +212,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PollReq->Handles[i].Status = PollReq->Handles[i].Events & FCB->PollState; if( PollReq->Handles[i].Status ) { - AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n", + AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", FCB, FCB->PollState)); Signalled++; } @@ -262,6 +268,8 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, (PAFD_EVENT_SELECT_INFO)LockRequest( Irp, IrpSp, FALSE, NULL ); PAFD_FCB FCB = FileObject->FsContext; + UNREFERENCED_PARAMETER(DeviceObject); + if( !SocketAcquireStateLock( FCB ) ) { return LostSocket( Irp ); } @@ -270,7 +278,7 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 ); } - AFD_DbgPrint(MID_TRACE,("Called (Event %x Triggers %x)\n", + AFD_DbgPrint(MID_TRACE,("Called (Event %p Triggers %d)\n", EventSelectInfo->EventObject, EventSelectInfo->Events)); @@ -302,7 +310,7 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, if((FCB->EventSelect) && (FCB->PollState & (FCB->EventSelectTriggers & ~FCB->EventSelectDisabled))) { - AFD_DbgPrint(MID_TRACE,("Setting event %x\n", FCB->EventSelect)); + AFD_DbgPrint(MID_TRACE,("Setting event %p\n", FCB->EventSelect)); /* Set the application's event */ KeSetEvent( FCB->EventSelect, IO_NETWORK_INCREMENT, FALSE ); @@ -324,7 +332,9 @@ AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp, PKEVENT UserEvent; NTSTATUS Status; - AFD_DbgPrint(MID_TRACE,("Called (FCB %x)\n", FCB)); + UNREFERENCED_PARAMETER(DeviceObject); + + AFD_DbgPrint(MID_TRACE,("Called (FCB %p)\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) { return LostSocket( Irp ); @@ -379,7 +389,7 @@ static BOOLEAN UpdatePollWithFCB( PAFD_ACTIVE_POLL Poll, PFILE_OBJECT FileObject PollReq->Handles[i].Status = PollReq->Handles[i].Events & FCB->PollState; if( PollReq->Handles[i].Status ) { - AFD_DbgPrint(MID_TRACE,("Signalling %x with %x\n", + AFD_DbgPrint(MID_TRACE,("Signalling %p with %x\n", FCB, FCB->PollState)); Signalled++; } @@ -395,7 +405,7 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) { KIRQL OldIrql; PAFD_POLL_INFO PollReq; - AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %x FileObject %x\n", + AFD_DbgPrint(MID_TRACE,("Called: DeviceExt %p FileObject %p\n", DeviceExt, FileObject)); KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql ); @@ -414,7 +424,7 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) { while( ThePollEnt != &DeviceExt->Polls ) { Poll = CONTAINING_RECORD( ThePollEnt, AFD_ACTIVE_POLL, ListEntry ); PollReq = Poll->Irp->AssociatedIrp.SystemBuffer; - AFD_DbgPrint(MID_TRACE,("Checking poll %x\n", Poll)); + AFD_DbgPrint(MID_TRACE,("Checking poll %p\n", Poll)); if( UpdatePollWithFCB( Poll, FileObject ) ) { ThePollEnt = ThePollEnt->Flink; @@ -429,7 +439,7 @@ VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject ) { if((FCB->EventSelect) && (FCB->PollState & (FCB->EventSelectTriggers & ~FCB->EventSelectDisabled))) { - AFD_DbgPrint(MID_TRACE,("Setting event %x\n", FCB->EventSelect)); + AFD_DbgPrint(MID_TRACE,("Setting event %p\n", FCB->EventSelect)); /* Set the application's event */ KeSetEvent( FCB->EventSelect, IO_NETWORK_INCREMENT, FALSE ); diff --git a/reactos/drivers/network/afd/afd/tdi.c b/reactos/drivers/network/afd/afd/tdi.c index f99186a861b..fcdb77bb39c 100644 --- a/reactos/drivers/network/afd/afd/tdi.c +++ b/reactos/drivers/network/afd/afd/tdi.c @@ -64,7 +64,7 @@ static NTSTATUS TdiCall( AFD_DbgPrint(MID_TRACE, ("Called\n")); - AFD_DbgPrint(MID_TRACE, ("Irp->UserEvent = %x\n", Irp->UserEvent)); + AFD_DbgPrint(MID_TRACE, ("Irp->UserEvent = %p\n", Irp->UserEvent)); Status = IoCallDriver(DeviceObject, Irp); AFD_DbgPrint(MID_TRACE, ("IoCallDriver: %08x\n", Status)); @@ -109,7 +109,7 @@ static NTSTATUS TdiOpenDevice( NTSTATUS Status; ULONG ShareAccess; - AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ, %d)\n", DeviceName, ShareType)); + AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ, %u)\n", DeviceName, ShareType)); /* Determine the share access */ if (ShareType != AFD_SHARE_REUSE) @@ -152,7 +152,7 @@ static NTSTATUS TdiOpenDevice( AFD_DbgPrint(MIN_TRACE, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status)); ZwClose(*Handle); } else { - AFD_DbgPrint(MAX_TRACE, ("Got handle (0x%X) Object (0x%X)\n", + AFD_DbgPrint(MAX_TRACE, ("Got handle (%p) Object (%p)\n", *Handle, *Object)); } } else { @@ -189,7 +189,7 @@ NTSTATUS TdiOpenAddressFile( ULONG EaLength; PTRANSPORT_ADDRESS Address; - AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ) Name (0x%X)\n", + AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ) Name (%p)\n", DeviceName, Name)); /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */ @@ -399,7 +399,7 @@ NTSTATUS TdiAssociateAddressFile( KEVENT Event; PIRP Irp; - AFD_DbgPrint(MAX_TRACE, ("Called. AddressHandle (0x%X) ConnectionObject (0x%X)\n", + AFD_DbgPrint(MAX_TRACE, ("Called. AddressHandle (%p) ConnectionObject (%p)\n", AddressHandle, ConnectionObject)); if (!ConnectionObject) { @@ -448,7 +448,7 @@ NTSTATUS TdiDisassociateAddressFile( KEVENT Event; PIRP Irp; - AFD_DbgPrint(MAX_TRACE, ("Called. ConnectionObject (0x%X)\n", ConnectionObject)); + AFD_DbgPrint(MAX_TRACE, ("Called. ConnectionObject (%p)\n", ConnectionObject)); if (!ConnectionObject) { AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); @@ -803,7 +803,7 @@ NTSTATUS TdiQueryAddress( /* Locate an IP entity */ EntityCount = BufferSize / sizeof(TDIEntityID); - AFD_DbgPrint(MAX_TRACE, ("EntityCount = %d\n", EntityCount)); + AFD_DbgPrint(MAX_TRACE, ("EntityCount = %u\n", EntityCount)); for (i = 0; i < EntityCount; i++) { if (Entities[i].tei_entity == CL_NL_ENTITY) { @@ -923,7 +923,7 @@ NTSTATUS TdiSend( return STATUS_INSUFFICIENT_RESOURCES; } - AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); + AFD_DbgPrint(MID_TRACE, ("Allocating irp for %p:%u\n", Buffer,BufferLength)); Mdl = IoAllocateMdl(Buffer, /* Virtual address */ BufferLength, /* Length of buffer */ @@ -947,7 +947,7 @@ NTSTATUS TdiSend( _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); } _SEH2_END; - AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); + AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\n", Mdl)); TdiBuildSend(*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ @@ -1002,7 +1002,7 @@ NTSTATUS TdiReceive( return STATUS_INSUFFICIENT_RESOURCES; } - AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); + AFD_DbgPrint(MID_TRACE, ("Allocating irp for %p:%u\n", Buffer,BufferLength)); Mdl = IoAllocateMdl(Buffer, /* Virtual address */ BufferLength, /* Length of buffer */ @@ -1028,7 +1028,7 @@ NTSTATUS TdiReceive( _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); } _SEH2_END; - AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); + AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\n", Mdl)); TdiBuildReceive(*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ @@ -1097,7 +1097,7 @@ NTSTATUS TdiReceiveDatagram( return STATUS_INSUFFICIENT_RESOURCES; } - AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); + AFD_DbgPrint(MID_TRACE, ("Allocating irp for %p:%u\n", Buffer,BufferLength)); Mdl = IoAllocateMdl(Buffer, /* Virtual address */ BufferLength, /* Length of buffer */ @@ -1121,7 +1121,7 @@ NTSTATUS TdiReceiveDatagram( _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); } _SEH2_END; - AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); + AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\n", Mdl)); TdiBuildReceiveDatagram(*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ @@ -1173,7 +1173,7 @@ NTSTATUS TdiSendDatagram( return STATUS_INVALID_PARAMETER; } - AFD_DbgPrint(MID_TRACE,("Called(TransportObject %x)\n", TransportObject)); + AFD_DbgPrint(MID_TRACE,("Called(TransportObject %p)\n", TransportObject)); DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { @@ -1192,7 +1192,7 @@ NTSTATUS TdiSendDatagram( return STATUS_INSUFFICIENT_RESOURCES; } - AFD_DbgPrint(MID_TRACE, ("Allocating irp for %x:%d\n", Buffer,BufferLength)); + AFD_DbgPrint(MID_TRACE, ("Allocating irp for %p:%u\n", Buffer,BufferLength)); Mdl = IoAllocateMdl(Buffer, /* Virtual address */ BufferLength, /* Length of buffer */ @@ -1217,7 +1217,7 @@ NTSTATUS TdiSendDatagram( _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); } _SEH2_END; - AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %x\n", Mdl)); + AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\n", Mdl)); TdiBuildSendDatagram(*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ @@ -1252,7 +1252,7 @@ NTSTATUS TdiDisconnect( return STATUS_INVALID_PARAMETER; } - AFD_DbgPrint(MID_TRACE,("Called(TransportObject %x)\n", TransportObject)); + AFD_DbgPrint(MID_TRACE,("Called(TransportObject %p)\n", TransportObject)); DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { diff --git a/reactos/drivers/network/afd/afd/write.c b/reactos/drivers/network/afd/afd/write.c index a9afed08b32..6b2c23c787c 100644 --- a/reactos/drivers/network/afd/afd/write.c +++ b/reactos/drivers/network/afd/afd/write.c @@ -9,6 +9,7 @@ */ #include "afd.h" +static IO_COMPLETION_ROUTINE SendComplete; static NTSTATUS NTAPI SendComplete ( PDEVICE_OBJECT DeviceObject, PIRP Irp, @@ -24,6 +25,8 @@ static NTSTATUS NTAPI SendComplete UINT SendLength, BytesCopied; BOOLEAN HaltSendQueue; + UNREFERENCED_PARAMETER(DeviceObject); + /* * The Irp parameter passed in is the IRP of the stream between AFD and * TDI driver. It's not very usefull to us. We need the IRPs of the stream @@ -33,7 +36,7 @@ static NTSTATUS NTAPI SendComplete * processed). */ - AFD_DbgPrint(MID_TRACE,("Called, status %x, %d bytes used\n", + AFD_DbgPrint(MID_TRACE,("Called, status %x, %u bytes used\n", Irp->IoStatus.Status, Irp->IoStatus.Information)); @@ -159,7 +162,7 @@ static NTSTATUS NTAPI SendComplete SendReq = GetLockedData(NextIrp, NextIrpSp); Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount); - AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq)); + AFD_DbgPrint(MID_TRACE,("SendReq @ %p\n", SendReq)); SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; TotalBytesCopied = 0; @@ -254,6 +257,7 @@ static NTSTATUS NTAPI SendComplete return STATUS_SUCCESS; } +static IO_COMPLETION_ROUTINE PacketSocketSendComplete; static NTSTATUS NTAPI PacketSocketSendComplete ( PDEVICE_OBJECT DeviceObject, PIRP Irp, @@ -263,7 +267,9 @@ static NTSTATUS NTAPI PacketSocketSendComplete PIRP NextIrp; PAFD_SEND_INFO SendReq; - AFD_DbgPrint(MID_TRACE,("Called, status %x, %d bytes used\n", + UNREFERENCED_PARAMETER(DeviceObject); + + AFD_DbgPrint(MID_TRACE,("Called, status %x, %u bytes used\n", Irp->IoStatus.Status, Irp->IoStatus.Information)); @@ -329,7 +335,10 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, UINT TotalBytesCopied = 0, i, SpaceAvail = 0, BytesCopied, SendLength; KPROCESSOR_MODE LockMode; - AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Short); + + AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); @@ -431,7 +440,7 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, Irp, 0 ); } - AFD_DbgPrint(MID_TRACE,("Socket state %d\n", FCB->State)); + AFD_DbgPrint(MID_TRACE,("Socket state %u\n", FCB->State)); if( FCB->State != SOCKET_STATE_CONNECTED ) { if (!(SendReq->AfdFlags & AFD_OVERLAPPED) && @@ -445,12 +454,12 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, } } - AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %d\n", + AFD_DbgPrint(MID_TRACE,("FCB->Send.BytesUsed = %u\n", FCB->Send.BytesUsed)); SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; - AFD_DbgPrint(MID_TRACE,("We can accept %d bytes\n", + AFD_DbgPrint(MID_TRACE,("We can accept %u bytes\n", SpaceAvail)); /* Count the total transfer size */ @@ -493,7 +502,7 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, { BytesCopied = MIN(SendReq->BufferArray[i].len, SpaceAvail); - AFD_DbgPrint(MID_TRACE,("Copying Buffer %d, %x:%d to %x\n", + AFD_DbgPrint(MID_TRACE,("Copying Buffer %u, %p:%u to %p\n", i, SendReq->BufferArray[i].buf, BytesCopied, @@ -559,7 +568,9 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PAFD_SEND_INFO_UDP SendReq; KPROCESSOR_MODE LockMode; - AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); + UNREFERENCED_PARAMETER(DeviceObject); + + AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); @@ -611,7 +622,7 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp, Irp, 0 ); AFD_DbgPrint - (MID_TRACE,("RemoteAddress #%d Type %d\n", + (MID_TRACE,("RemoteAddress #%d Type %u\n", ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)-> TAAddressCount, ((PTRANSPORT_ADDRESS)SendReq->TdiConnection.RemoteAddress)-> diff --git a/reactos/drivers/network/afd/include/afd.h b/reactos/drivers/network/afd/include/afd.h index c05eaede6bc..d06bf46b51c 100644 --- a/reactos/drivers/network/afd/include/afd.h +++ b/reactos/drivers/network/afd/include/afd.h @@ -319,26 +319,18 @@ NTSTATUS QueueUserModeIrp(PAFD_FCB FCB, PIRP Irp, UINT Function); VOID OskitDumpBuffer( PCHAR Buffer, UINT Len ); VOID DestroySocket( PAFD_FCB FCB ); -VOID NTAPI AfdCancelHandler(PDEVICE_OBJECT DeviceObject, - PIRP Irp); +DRIVER_CANCEL AfdCancelHandler; VOID RetryDisconnectCompletion(PAFD_FCB FCB); BOOLEAN CheckUnlockExtraBuffers(PAFD_FCB FCB, PIO_STACK_LOCATION IrpSp); /* read.c */ -NTSTATUS NTAPI ReceiveComplete -( PDEVICE_OBJECT DeviceObject, - PIRP Irp, - PVOID Context ); +IO_COMPLETION_ROUTINE ReceiveComplete; -NTSTATUS NTAPI PacketSocketRecvComplete -( PDEVICE_OBJECT DeviceObject, - PIRP Irp, - PVOID Context ); +IO_COMPLETION_ROUTINE PacketSocketRecvComplete; NTSTATUS NTAPI -AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, - PIO_STACK_LOCATION IrpSp, BOOLEAN Short); +AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN Short); NTSTATUS NTAPI AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp ); From 8901f8a911ba3cbd6b63b2fa2e789757d7a8a7f8 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 8 May 2013 11:33:13 +0000 Subject: [PATCH 65/67] [AFD] * Fix more debug print specifiers. svn path=/trunk/; revision=58967 --- reactos/drivers/network/afd/afd/info.c | 2 +- reactos/drivers/network/afd/afd/lock.c | 2 +- reactos/drivers/network/afd/afd/select.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/drivers/network/afd/afd/info.c b/reactos/drivers/network/afd/afd/info.c index e92acb8e7f1..acba575e6d3 100644 --- a/reactos/drivers/network/afd/afd/info.c +++ b/reactos/drivers/network/afd/afd/info.c @@ -116,7 +116,7 @@ AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, _SEH2_TRY { switch (InfoReq->InformationClass) { case AFD_INFO_BLOCKING_MODE: - AFD_DbgPrint(MID_TRACE,("Blocking mode set to %d\n", InfoReq->Information.Boolean)); + AFD_DbgPrint(MID_TRACE,("Blocking mode set to %c\n", InfoReq->Information.Boolean)); FCB->NonBlocking = InfoReq->Information.Boolean; break; case AFD_INFO_INLINING_MODE: diff --git a/reactos/drivers/network/afd/afd/lock.c b/reactos/drivers/network/afd/afd/lock.c index dee5b71c3da..5b0ed2280be 100644 --- a/reactos/drivers/network/afd/afd/lock.c +++ b/reactos/drivers/network/afd/afd/lock.c @@ -274,7 +274,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, } } - AFD_DbgPrint(MID_TRACE,("Leaving %x\n", NewBuf)); + AFD_DbgPrint(MID_TRACE,("Leaving %p\n", NewBuf)); return NewBuf; } diff --git a/reactos/drivers/network/afd/afd/select.c b/reactos/drivers/network/afd/afd/select.c index 9af7ae57722..b662f838b73 100644 --- a/reactos/drivers/network/afd/afd/select.c +++ b/reactos/drivers/network/afd/afd/select.c @@ -144,7 +144,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, HandleArray = AFD_HANDLES(PollReq); for( i = 0; i < PollReq->HandleCount; i++ ) { - AFD_DbgPrint(MAX_TRACE,("Req: %p, This %p\n", + AFD_DbgPrint(MAX_TRACE,("Req: %u, This %p\n", HandleArray[i].Handle, FileObject)); if( (PVOID)HandleArray[i].Handle == FileObject && (!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) { @@ -278,7 +278,7 @@ AfdEventSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 ); } - AFD_DbgPrint(MID_TRACE,("Called (Event %p Triggers %d)\n", + AFD_DbgPrint(MID_TRACE,("Called (Event %p Triggers %u)\n", EventSelectInfo->EventObject, EventSelectInfo->Events)); From 689682751e6981a9d69dd5647495d545e664e184 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 8 May 2013 11:55:37 +0000 Subject: [PATCH 66/67] [BEEP] * Properly mark some unreferenced parameters as such. [AFD] * Properly fix a debug print specifier. svn path=/trunk/; revision=58968 --- reactos/drivers/base/beep/beep.c | 6 ++++++ reactos/drivers/network/afd/afd/info.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/reactos/drivers/base/beep/beep.c b/reactos/drivers/base/beep/beep.c index 45addc6f50f..444f0f07c86 100644 --- a/reactos/drivers/base/beep/beep.c +++ b/reactos/drivers/base/beep/beep.c @@ -38,6 +38,10 @@ BeepDPC(IN PKDPC Dpc, { PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + UNREFERENCED_PARAMETER(Dpc); + UNREFERENCED_PARAMETER(SystemArgument1); + UNREFERENCED_PARAMETER(SystemArgument2); + /* Stop the beep */ HalMakeBeep(0); @@ -368,6 +372,8 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Beep"); NTSTATUS Status; + UNREFERENCED_PARAMETER(RegistryPath); + /* Create the device */ Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), diff --git a/reactos/drivers/network/afd/afd/info.c b/reactos/drivers/network/afd/afd/info.c index acba575e6d3..60955240a2d 100644 --- a/reactos/drivers/network/afd/afd/info.c +++ b/reactos/drivers/network/afd/afd/info.c @@ -116,7 +116,7 @@ AfdSetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp, _SEH2_TRY { switch (InfoReq->InformationClass) { case AFD_INFO_BLOCKING_MODE: - AFD_DbgPrint(MID_TRACE,("Blocking mode set to %c\n", InfoReq->Information.Boolean)); + AFD_DbgPrint(MID_TRACE,("Blocking mode set to %u\n", InfoReq->Information.Boolean)); FCB->NonBlocking = InfoReq->Information.Boolean; break; case AFD_INFO_INLINING_MODE: From a1f6ab439160b9538ad9aabf8bf0a8e8e0524880 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Wed, 8 May 2013 12:12:15 +0000 Subject: [PATCH 67/67] [AFD] * Mark SelectTimeout as a KDEFERRED_ROUTINE and fix its calling convention. This fixes a potential stack corruption. * Brought to you by Nikolay Borisov and the MSVC static analyzer ;) CORE-7171 #resolve svn path=/trunk/; revision=58969 --- reactos/drivers/network/afd/afd/select.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/reactos/drivers/network/afd/afd/select.c b/reactos/drivers/network/afd/afd/select.c index b662f838b73..a19ec5775d9 100644 --- a/reactos/drivers/network/afd/afd/select.c +++ b/reactos/drivers/network/afd/afd/select.c @@ -91,7 +91,8 @@ VOID SignalSocket( AFD_DbgPrint(MID_TRACE,("Done\n")); } -static VOID SelectTimeout( PKDPC Dpc, +static KDEFERRED_ROUTINE SelectTimeout; +static VOID NTAPI SelectTimeout( PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2 ) { @@ -235,9 +236,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, KeInitializeTimerEx( &Poll->Timer, NotificationTimer ); - KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc, - (PKDEFERRED_ROUTINE)SelectTimeout, - Poll ); + KeInitializeDpc( (PRKDPC)&Poll->TimeoutDpc, SelectTimeout, Poll ); InsertTailList( &DeviceExt->Polls, &Poll->ListEntry );