From d129a33badf4c9b38b340b248d57acffbcad33b8 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 10 Nov 2009 01:47:09 +0000 Subject: [PATCH 001/140] fix a preprocessor bug svn path=/trunk/; revision=44068 --- reactos/boot/freeldr/freeldr/options.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/boot/freeldr/freeldr/options.c b/reactos/boot/freeldr/freeldr/options.c index 2c1f6c68648..4dabc89c6f4 100644 --- a/reactos/boot/freeldr/freeldr/options.c +++ b/reactos/boot/freeldr/freeldr/options.c @@ -113,6 +113,7 @@ VOID DoOptionsMenu(VOID) case REBOOT: OptionMenuReboot(); break; - } #endif + } } + From dcb13362032a97529225fab9d5243a42b5c70f09 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 10 Nov 2009 10:01:25 +0000 Subject: [PATCH 002/140] [PORTCLS] - Implement handling of enabling / disabling events - Implement firing of events when certain position is reached - Code not yet used as ks needs more work svn path=/trunk/; revision=44074 --- .../wdm/audio/backpln/portcls/guids.cpp | 3 + .../wdm/audio/backpln/portcls/interfaces.hpp | 5 + .../audio/backpln/portcls/pin_wavecyclic.cpp | 239 +++++++++++++++--- .../wdm/audio/backpln/portcls/private.hpp | 14 + .../wdm/audio/backpln/portcls/undoc.cpp | 28 ++ 5 files changed, 256 insertions(+), 33 deletions(-) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp b/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp index abc5325cf63..457868d2c62 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/guids.cpp @@ -80,6 +80,9 @@ const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, { const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSPROPTYPESETID_General = {0x97E99BA0L, 0xBDEA, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSEVENTSETID_LoopedStreaming = {0x4682B940L, 0xC6EF, 0x11D0, {0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D}}; +const GUID KSEVENTSETID_Connection = {0x7f4bcbe0L, 0x9ea5, 0x11cf, {0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00}}; + const GUID IID_IAllocatorMXF = {0xa5f0d62cL, 0xb30f, 0x11d2, {0xb7, 0xa3, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}}; const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp index bf9057b3fb2..7aefc882ee4 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp @@ -209,6 +209,11 @@ typedef struct ULONG FilterPropertySetCount; PKSPROPERTY_SET FilterPropertySet; + ULONG EventSetCount; + PKSEVENT_SET EventSet; + PLIST_ENTRY EventList; + PKSPIN_LOCK EventListLock; + PPCFILTER_DESCRIPTOR DeviceDescriptor; KSTOPOLOGY* Topology; LIST_ENTRY SymbolicLinkList; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index 38a6ae91ff5..62a2094bba8 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -41,6 +41,7 @@ protected: VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount); VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount); + VOID GeneratePositionEvents(IN ULONG OldCommonBufferOffset, IN ULONG NewCommonBufferOffset); NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); @@ -49,6 +50,8 @@ protected: friend NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); friend NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); friend NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); + friend NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); + friend NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); IPortWaveCyclic * m_Port; IPortFilterWaveCyclic * m_Filter; @@ -76,6 +79,9 @@ protected: KSALLOCATOR_FRAMING m_AllocatorFraming; SUBDEVICE_DESCRIPTOR m_Descriptor; + KSPIN_LOCK m_EventListLock; + LIST_ENTRY m_EventList; + ULONG m_Delay; LONG m_Ref; @@ -84,19 +90,49 @@ protected: typedef struct { - CPortPinWaveCyclic *Pin; - PIO_WORKITEM WorkItem; - KSSTATE State; -}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; + ULONG bLoopedStreaming; + ULONGLONG Position; +}LOOPEDSTREAMING_EVENT_CONTEXT, *PLOOPEDSTREAMING_EVENT_CONTEXT; + +typedef struct +{ + ULONG bLoopedStreaming; +}ENDOFSTREAM_EVENT_CONTEXT, *PENDOFSTREAM_EVENT_CONTEXT; + + NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); +NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); +NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); + DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat, PinWaveCyclicAllocatorFraming); DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition); +KSEVENT_ITEM PinWaveCyclicConnectionEventSet = +{ + KSEVENT_CONNECTION_ENDOFSTREAM, + sizeof(KSEVENTDATA), + sizeof(ENDOFSTREAM_EVENT_CONTEXT), + PinWaveCyclicAddEndOfStreamEvent, + 0, + 0 +}; + +KSEVENT_ITEM PinWaveCyclicStreamingEventSet = +{ + KSEVENT_LOOPEDSTREAMING_POSITION, + sizeof(LOOPEDSTREAMING_POSITION_EVENT_DATA), + sizeof(LOOPEDSTREAMING_EVENT_CONTEXT), + PinWaveCyclicAddLoopedStreamEvent, + 0, + 0 +}; + + KSPROPERTY_SET PinWaveCyclicPropertySet[] = { { @@ -115,6 +151,21 @@ KSPROPERTY_SET PinWaveCyclicPropertySet[] = } }; +KSEVENT_SET PinWaveCyclicEventSet[] = +{ + { + &KSEVENTSETID_LoopedStreaming, + sizeof(PinWaveCyclicStreamingEventSet) / sizeof(KSEVENT_ITEM), + (const KSEVENT_ITEM*)&PinWaveCyclicStreamingEventSet + }, + { + &KSEVENTSETID_Connection, + sizeof(PinWaveCyclicConnectionEventSet) / sizeof(KSEVENT_ITEM), + (const KSEVENT_ITEM*)&PinWaveCyclicConnectionEventSet + } +}; + + //================================================================================================================================== NTSTATUS @@ -143,6 +194,80 @@ CPortPinWaveCyclic::QueryInterface( return STATUS_UNSUCCESSFUL; } +NTSTATUS +NTAPI +PinWaveCyclicAddEndOfStreamEvent( + IN PIRP Irp, + IN PKSEVENTDATA EventData, + IN PKSEVENT_ENTRY EventEntry) +{ + PENDOFSTREAM_EVENT_CONTEXT Entry; + PSUBDEVICE_DESCRIPTOR Descriptor; + CPortPinWaveCyclic *Pin; + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + // cast to pin impl + Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; + + // get extra size + Entry = (PENDOFSTREAM_EVENT_CONTEXT)(EventEntry + 1); + + // not a looped event + Entry->bLoopedStreaming = FALSE; + + // insert item + (void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock); + + // done + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PinWaveCyclicAddLoopedStreamEvent( + IN PIRP Irp, + IN PKSEVENTDATA EventData, + IN PKSEVENT_ENTRY EventEntry) +{ + PLOOPEDSTREAMING_POSITION_EVENT_DATA Data; + PLOOPEDSTREAMING_EVENT_CONTEXT Entry; + PSUBDEVICE_DESCRIPTOR Descriptor; + CPortPinWaveCyclic *Pin; + + // get sub device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSEVENT_ITEM_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->PortPin); + PC_ASSERT_IRQL(DISPATCH_LEVEL); + + // cast to pin impl + Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; + + // cast to looped event + Data = (PLOOPEDSTREAMING_POSITION_EVENT_DATA)EventData; + + // get extra size + Entry = (PLOOPEDSTREAMING_EVENT_CONTEXT)(EventEntry + 1); + + Entry->bLoopedStreaming = TRUE; + Entry->Position = Data->Position; + + // insert item + (void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock); + + // done + return STATUS_SUCCESS; +} + NTSTATUS NTAPI PinWaveCyclicAllocatorFraming( @@ -154,7 +279,7 @@ PinWaveCyclicAllocatorFraming( PSUBDEVICE_DESCRIPTOR Descriptor; // get sub device descriptor - Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSEVENT_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); @@ -413,6 +538,58 @@ PinWaveCyclicDataFormat( return STATUS_NOT_SUPPORTED; } +VOID +CPortPinWaveCyclic::GeneratePositionEvents( + IN ULONG OldCommonBufferOffset, + IN ULONG NewCommonBufferOffset) +{ + PLIST_ENTRY Entry; + PKSEVENT_ENTRY EventEntry; + PLOOPEDSTREAMING_EVENT_CONTEXT Context; + + // acquire event lock + KeAcquireSpinLockAtDpcLevel(&m_EventListLock); + + // point to first entry + Entry = m_EventList.Flink; + + while(Entry != &m_EventList) + { + // get event entry + EventEntry = (PKSEVENT_ENTRY)CONTAINING_RECORD(Entry, KSEVENT_ENTRY, ListEntry); + + // get event entry context + Context = (PLOOPEDSTREAMING_EVENT_CONTEXT)(EventEntry + 1); + + if (Context->bLoopedStreaming == TRUE) + { + if (NewCommonBufferOffset > OldCommonBufferOffset) + { + /* buffer progress no overlap */ + if (OldCommonBufferOffset < Context->Position && Context->Position <= NewCommonBufferOffset) + { + /* generate event */ + KsGenerateEvent(EventEntry); + } + } + else + { + /* buffer wrap-arround */ + if (OldCommonBufferOffset < Context->Position || NewCommonBufferOffset > Context->Position) + { + /* generate event */ + KsGenerateEvent(EventEntry); + } + } + } + + // move to next entry + Entry = Entry->Flink; + } + + // release lock + KeReleaseSpinLockFromDpcLevel(&m_EventListLock); +} VOID CPortPinWaveCyclic::UpdateCommonBuffer( @@ -516,6 +693,7 @@ CPortPinWaveCyclic::RequestService() NTSTATUS Status; PUCHAR Buffer; ULONG BufferSize; + ULONG OldCommonBufferOffset; PC_ASSERT_IRQL(DISPATCH_LEVEL); @@ -528,6 +706,8 @@ CPortPinWaveCyclic::RequestService() Status = m_Stream->GetPosition(&Position); DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture); + OldCommonBufferOffset = m_CommonBufferOffset; + if (Position < m_CommonBufferOffset) { UpdateCommonBufferOverlap(Position, m_FrameSize); @@ -536,6 +716,8 @@ CPortPinWaveCyclic::RequestService() { UpdateCommonBuffer(Position, m_FrameSize); } + + GeneratePositionEvents(OldCommonBufferOffset, m_CommonBufferOffset); } NTSTATUS @@ -569,16 +751,6 @@ CPortPinWaveCyclic::HandleKsProperty( IoStack = IoGetCurrentIrpStackLocation(Irp); - if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) - { - DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength); - - Irp->IoStatus.Status = STATUS_SUCCESS; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } - Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); if (Status == STATUS_NOT_FOUND) @@ -629,6 +801,7 @@ CPortPinWaveCyclic::DeviceIoControl( IN PIRP Irp) { PIO_STACK_LOCATION IoStack; + NTSTATUS Status = STATUS_NOT_SUPPORTED; IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -639,13 +812,11 @@ CPortPinWaveCyclic::DeviceIoControl( } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) { - /// FIXME - /// handle enable event + Status = PcHandleEnableEventWithTable(Irp, &m_Descriptor); } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT) { - /// FIXME - /// handle disable event + Status = PcHandleDisableEventWithTable(Irp, &m_Descriptor); } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) { @@ -661,13 +832,13 @@ CPortPinWaveCyclic::DeviceIoControl( return KsDefaultDeviceIoCompletion(DeviceObject, Irp); } - UNIMPLEMENTED + if (Status != STATUS_PENDING) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_UNSUCCESSFUL; + return Status; } NTSTATUS @@ -912,8 +1083,8 @@ CPortPinWaveCyclic::Init( } #endif - DPRINT("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture); - DPRINT("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize); + DPRINT1("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture); + DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize); if (!NT_SUCCESS(Status)) return Status; @@ -933,6 +1104,10 @@ CPortPinWaveCyclic::Init( return Status; } + /* initialize event management */ + InitializeListHead(&m_EventList); + KeInitializeSpinLock(&m_EventListLock); + /* set up subdevice descriptor */ RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); m_Descriptor.FilterPropertySet = PinWaveCyclicPropertySet; @@ -941,6 +1116,10 @@ CPortPinWaveCyclic::Init( m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor; m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; m_Descriptor.PortPin = (PVOID)this; + m_Descriptor.EventSetCount = sizeof(PinWaveCyclicEventSet) / sizeof(KSEVENT_SET); + m_Descriptor.EventSet = PinWaveCyclicEventSet; + m_Descriptor.EventList = &m_EventList; + m_Descriptor.EventListLock = &m_EventListLock; // release subdevice descriptor Subdevice->Release(); @@ -993,12 +1172,6 @@ CPortPinWaveCyclic::Init( RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); - PKSDATAFORMAT_WAVEFORMATEX Wave = (PKSDATAFORMAT_WAVEFORMATEX)m_Format; - - DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", Wave->WaveFormatEx.wBitsPerSample, Wave->WaveFormatEx.nSamplesPerSec, Wave->WaveFormatEx.nChannels, Wave->WaveFormatEx.wFormatTag, m_FrameSize); - - - Port->AddRef(); Filter->AddRef(); diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.hpp b/reactos/drivers/wdm/audio/backpln/portcls/private.hpp index 1df2b4b9540..45e6092e6e3 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.hpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.hpp @@ -316,6 +316,20 @@ PcHandlePropertyWithTable( IN PKSPROPERTY_SET PropertySet, IN PSUBDEVICE_DESCRIPTOR Descriptor); +NTSTATUS +NTAPI +PcHandleEnableEventWithTable( + IN PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR Descriptor); + +NTSTATUS +NTAPI +PcHandleDisableEventWithTable( + IN PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR Descriptor); + + + #define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\ PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\ DEFINE_KSPROPERTY_TABLE(PinSet) {\ diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp index 56c25973745..21e2bf1ec2d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -59,6 +59,34 @@ KsoGetIrpTargetFromIrp( return (IIrpTarget*)CreateItem->Context; } +NTSTATUS +NTAPI +PcHandleEnableEventWithTable( + IN PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR Descriptor) +{ + // store descriptor + KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor; + + // FIXME seh probing + return KsEnableEvent(Irp, Descriptor->EventSetCount, Descriptor->EventSet, NULL, KSEVENTS_NONE, NULL); +} + +NTSTATUS +NTAPI +PcHandleDisableEventWithTable( + IN PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR Descriptor) +{ + // store descriptor + KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor; + + // FIXME seh probing + + return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock); +} + + NTSTATUS NTAPI PcHandlePropertyWithTable( From c3eaa577c45621d5bbb1bc47d9b88a788367b675 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 10 Nov 2009 10:04:33 +0000 Subject: [PATCH 003/140] - Remove ASSERT && add param checks svn path=/trunk/; revision=44075 --- reactos/dll/directx/dsound_new/classfactory.c | 3 +++ reactos/dll/directx/dsound_new/directsound.c | 7 +++++++ reactos/dll/directx/dsound_new/dsound.c | 5 ++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/reactos/dll/directx/dsound_new/classfactory.c b/reactos/dll/directx/dsound_new/classfactory.c index ee31e6154cd..64d2f8f6192 100644 --- a/reactos/dll/directx/dsound_new/classfactory.c +++ b/reactos/dll/directx/dsound_new/classfactory.c @@ -86,6 +86,9 @@ IClassFactory_fnCreateInstance( { IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + if (!ppvObject) + return E_INVALIDARG; + *ppvObject = NULL; if ( This->riidInst==NULL || IsEqualCLSID(riid, This->riidInst) || IsEqualCLSID(riid, &IID_IUnknown) ) diff --git a/reactos/dll/directx/dsound_new/directsound.c b/reactos/dll/directx/dsound_new/directsound.c index 12b03cf024c..754f56b0028 100644 --- a/reactos/dll/directx/dsound_new/directsound.c +++ b/reactos/dll/directx/dsound_new/directsound.c @@ -442,6 +442,13 @@ NewDirectSound( LPOLESTR pStr; LPCDirectSoundImpl This; + /* check param */ + if (!ppvObject) + { + /* invalid param */ + return E_INVALIDARG; + } + /* check requested interface */ if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IDirectSound) && !IsEqualIID(riid, &IID_IDirectSound8)) { diff --git a/reactos/dll/directx/dsound_new/dsound.c b/reactos/dll/directx/dsound_new/dsound.c index e8322ebbc31..c88fc00e528 100644 --- a/reactos/dll/directx/dsound_new/dsound.c +++ b/reactos/dll/directx/dsound_new/dsound.c @@ -124,8 +124,7 @@ WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, - LPVOID* ppv -) + LPVOID* ppv) { LPOLESTR pStr, pStr2; UINT i; @@ -153,7 +152,7 @@ DllGetClassObject( DPRINT("No Class Available for %ws IID %ws\n", pStr, pStr2); CoTaskMemFree(pStr); CoTaskMemFree(pStr2); - ASSERT(0); + //ASSERT(0); return CLASS_E_CLASSNOTAVAILABLE; } From 9a2bba4740e555c488a3ce59017c5c709d8b3319 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 10 Nov 2009 10:50:57 +0000 Subject: [PATCH 004/140] [KS] - Implement KsGenerateEvent svn path=/trunk/; revision=44076 --- reactos/drivers/ksfilter/ks/event.c | 36 ++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/event.c b/reactos/drivers/ksfilter/ks/event.c index eae342a6ebe..fedb507a9b9 100644 --- a/reactos/drivers/ksfilter/ks/event.c +++ b/reactos/drivers/ksfilter/ks/event.c @@ -285,7 +285,7 @@ KsFreeEventList( /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -293,8 +293,38 @@ NTAPI KsGenerateEvent( IN PKSEVENT_ENTRY EntryEvent) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + if (EntryEvent->NotificationType == KSEVENTF_EVENT_HANDLE || EntryEvent->NotificationType == KSEVENTF_EVENT_OBJECT) + { + // signal event + KeSetEvent(EntryEvent->Object, 0, FALSE); + } + else if (EntryEvent->NotificationType == KSEVENTF_SEMAPHORE_HANDLE || EntryEvent->NotificationType == KSEVENTF_SEMAPHORE_OBJECT) + { + // release semaphore + KeReleaseSemaphore(EntryEvent->Object, 0, EntryEvent->SemaphoreAdjustment, FALSE); + } + else if (EntryEvent->NotificationType == KSEVENTF_DPC) + { + // queue dpc + KeInsertQueueDpc((PRKDPC)EntryEvent->Object, NULL, NULL); + } + else if (EntryEvent->NotificationType == KSEVENTF_WORKITEM) + { + // queue work item + ExQueueWorkItem((PWORK_QUEUE_ITEM)EntryEvent->Object, PtrToUlong(EntryEvent->BufferItem)); + } + else if (EntryEvent->NotificationType == KSEVENTF_KSWORKITEM) + { + // queue work item of ks worker + return KsQueueWorkItem((PKSWORKER)EntryEvent->Object, (PWORK_QUEUE_ITEM)EntryEvent->DpcItem); + } + else + { + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; + } + + return STATUS_SUCCESS; } /* From ee750905e93e64e00db433a6ca81a7462b843778 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Tue, 10 Nov 2009 14:23:44 +0000 Subject: [PATCH 005/140] - Fix missing initialization of KdComPortInUse, containing the base address of the port used by kdcom. The serial driver checks this variable to determine if it can use the port or if it should stay (the fuck) off. KdCom no longer hangs after serial driver initialization in second stage. svn path=/trunk/; revision=44077 --- reactos/drivers/base/kddll/kdcom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/drivers/base/kddll/kdcom.c b/reactos/drivers/base/kddll/kdcom.c index 22d806c0720..343bce88004 100644 --- a/reactos/drivers/base/kddll/kdcom.c +++ b/reactos/drivers/base/kddll/kdcom.c @@ -204,6 +204,7 @@ KdDebuggerInitialize0( /* Get base address */ ComPortBase = UlongToPtr(BaseArray[ComPortNumber]); + KdComPortInUse = ComPortBase; /* Initialize the port */ return KdpPortInitialize(); From 31baf39ed3736a3f204d0527697b872089287a44 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Tue, 10 Nov 2009 16:42:31 +0000 Subject: [PATCH 006/140] - Correct author of freeze.c (code was copied from cpu.c). svn path=/trunk/; revision=44078 --- reactos/ntoskrnl/ke/freeze.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/ke/freeze.c b/reactos/ntoskrnl/ke/freeze.c index 68250ce3050..4d13cc75fa5 100644 --- a/reactos/ntoskrnl/ke/freeze.c +++ b/reactos/ntoskrnl/ke/freeze.c @@ -4,7 +4,7 @@ * FILE: ntoskrnl/ke/freeze.c * PURPOSE: Routines for freezing and unfreezing processors for * kernel debugger synchronization. - * PROGRAMMERS: Stefan Ginsberg (stefan.ginsberg@reactos.org) + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ /* INCLUDES *******************************************************************/ From 1526c2358d0eaed95b8cc7ca026e3d2cb0fcd11b Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 10 Nov 2009 20:09:00 +0000 Subject: [PATCH 007/140] sync shell32/shelllink to wine 1.1.32 svn path=/trunk/; revision=44079 --- reactos/dll/win32/shell32/shelllink.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/reactos/dll/win32/shell32/shelllink.c b/reactos/dll/win32/shell32/shelllink.c index 67c678d5c7d..6ad7b174d38 100644 --- a/reactos/dll/win32/shell32/shelllink.c +++ b/reactos/dll/win32/shell32/shelllink.c @@ -219,35 +219,35 @@ static HRESULT ShellLink_QueryInterface( IShellLinkImpl *This, REFIID riid, LPV } else if(IsEqualIID(riid, &IID_IShellLinkW)) { - *ppvObj = (void *)&(This->lpvtblw); + *ppvObj = &(This->lpvtblw); } else if(IsEqualIID(riid, &IID_IPersistFile)) { - *ppvObj = (void *)&(This->lpvtblPersistFile); + *ppvObj = &(This->lpvtblPersistFile); } else if(IsEqualIID(riid, &IID_IPersistStream)) { - *ppvObj = (void *)&(This->lpvtblPersistStream); + *ppvObj = &(This->lpvtblPersistStream); } else if(IsEqualIID(riid, &IID_IShellLinkDataList)) { - *ppvObj = (void *)&(This->lpvtblShellLinkDataList); + *ppvObj = &(This->lpvtblShellLinkDataList); } else if(IsEqualIID(riid, &IID_IShellExtInit)) { - *ppvObj = (void *)&(This->lpvtblShellExtInit); + *ppvObj = &(This->lpvtblShellExtInit); } else if(IsEqualIID(riid, &IID_IContextMenu)) { - *ppvObj = (void *)&(This->lpvtblContextMenu); + *ppvObj = &(This->lpvtblContextMenu); } else if(IsEqualIID(riid, &IID_IObjectWithSite)) { - *ppvObj = (void *)&(This->lpvtblObjectWithSite); + *ppvObj = &(This->lpvtblObjectWithSite); } else if(IsEqualIID(riid, &IID_IShellPropSheetExt)) { - *ppvObj = (void *)&(This->lpvtblPropSheetExt); + *ppvObj = &(This->lpvtblPropSheetExt); } if(*ppvObj) @@ -299,7 +299,7 @@ static ULONG ShellLink_Release( IShellLinkImpl *This ) if (This->pPidl) ILFree(This->pPidl); - LocalFree((HANDLE)This); + LocalFree(This); return 0; } @@ -308,7 +308,7 @@ static HRESULT ShellLink_GetClassID( IShellLinkImpl *This, CLSID *pclsid ) { TRACE("%p %p\n", This, pclsid); - memcpy( pclsid, &CLSID_ShellLink, sizeof (CLSID) ); + *pclsid = CLSID_ShellLink; return S_OK; } @@ -1651,6 +1651,8 @@ static HRESULT WINAPI IShellLinkA_fnSetPath(IShellLinkA * iface, LPCSTR pszFile) TRACE("(%p)->(path=%s)\n",This, pszFile); + if (!pszFile) return E_INVALIDARG; + str = HEAP_strdupAtoW(GetProcessHeap(), 0, pszFile); if( !str ) return E_OUTOFMEMORY; From 8f8f2a36c0e618a1a4d921bd87868b08f7f6fd33 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 10 Nov 2009 20:35:07 +0000 Subject: [PATCH 008/140] fix ILCreateControlPanel and ILCreatePrinters svn path=/trunk/; revision=44080 --- reactos/dll/win32/shell32/pidl.c | 35 ++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/reactos/dll/win32/shell32/pidl.c b/reactos/dll/win32/shell32/pidl.c index 72c712bc61c..0b4f226031b 100644 --- a/reactos/dll/win32/shell32/pidl.c +++ b/reactos/dll/win32/shell32/pidl.c @@ -138,6 +138,9 @@ BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR pa return SUCCEEDED(ret); } +/************************************************************************* + * ILGetDisplayNameEx [SHELL32.186] + */ BOOL WINAPI ILGetDisplayNameEx(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPVOID path, DWORD type) { TRACE_(shell)("%p %p %p %d\n", psf, pidl, path, type); @@ -1367,14 +1370,31 @@ LPITEMIDLIST _ILCreateIExplore(void) LPITEMIDLIST _ILCreateControlPanel(void) { - LPITEMIDLIST ret = NULL; - LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer); + LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL; TRACE("()\n"); - if (parent) { - LPITEMIDLIST printers = _ILCreateGuid(PT_YAGUID, &CLSID_ControlPanel); + LPITEMIDLIST cpl = _ILCreateGuid(PT_SHELLEXT, &CLSID_ControlPanel); + + if (cpl) + { + ret = ILCombine(parent, cpl); + SHFree(cpl); + } + SHFree(parent); + } + return ret; +} + +LPITEMIDLIST _ILCreatePrinters(void) +{ + LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL; + + TRACE("()\n"); + if (parent) + { + LPITEMIDLIST printers = _ILCreateGuid(PT_YAGUID, &CLSID_Printers); if (printers) { @@ -1384,13 +1404,6 @@ LPITEMIDLIST _ILCreateControlPanel(void) SHFree(parent); } return ret; - - return _ILCreateGuid(PT_SHELLEXT, &CLSID_ControlPanel); -} - -LPITEMIDLIST _ILCreatePrinters(void) -{ - return _ILCreateGuid(PT_YAGUID, &CLSID_Printers); } LPITEMIDLIST _ILCreateNetwork(void) From e8c61b4a528ed3f3c703e82f58856f7d3362a2dd Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 10 Nov 2009 21:29:56 +0000 Subject: [PATCH 009/140] partial shell32 sync to wine 1.1.32 svn path=/trunk/; revision=44081 --- reactos/dll/win32/shell32/shellitem.c | 4 ++-- reactos/dll/win32/shell32/shellole.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/reactos/dll/win32/shell32/shellitem.c b/reactos/dll/win32/shell32/shellitem.c index 75560aa640a..620f854efed 100644 --- a/reactos/dll/win32/shell32/shellitem.c +++ b/reactos/dll/win32/shell32/shellitem.c @@ -337,13 +337,13 @@ HRESULT WINAPI SHCreateShellItem(LPCITEMIDLIST pidlParent, { IPersistFolder2* ppf2Parent; - if (!SUCCEEDED(IPersistFolder2_QueryInterface(psfParent, &IID_IPersistFolder2, (void**)&ppf2Parent))) + if (FAILED(IPersistFolder2_QueryInterface(psfParent, &IID_IPersistFolder2, (void**)&ppf2Parent))) { FIXME("couldn't get IPersistFolder2 interface of parent\n"); return E_NOINTERFACE; } - if (!SUCCEEDED(IPersistFolder2_GetCurFolder(ppf2Parent, &temp_parent))) + if (FAILED(IPersistFolder2_GetCurFolder(ppf2Parent, &temp_parent))) { FIXME("couldn't get parent PIDL\n"); IPersistFolder2_Release(ppf2Parent); diff --git a/reactos/dll/win32/shell32/shellole.c b/reactos/dll/win32/shell32/shellole.c index 5a5033f31c1..37a3334d310 100644 --- a/reactos/dll/win32/shell32/shellole.c +++ b/reactos/dll/win32/shell32/shellole.c @@ -41,6 +41,7 @@ static const struct { } InterfaceTable[] = { {&CLSID_ShellFSFolder, &IFSFolder_Constructor}, {&CLSID_MyComputer, &ISF_MyComputer_Constructor}, + {&CLSID_NetworkPlaces, &ISF_NetworkPlaces_Constructor}, {&CLSID_ShellDesktop, &ISF_Desktop_Constructor}, {&CLSID_ShellItem, &IShellItem_Constructor}, {&CLSID_ShellLink, &IShellLink_Constructor}, @@ -53,7 +54,6 @@ static const struct { {&CLSID_FolderShortcut, &FolderShortcut_Constructor}, #endif {&CLSID_MyDocuments, &ISF_MyDocuments_Constructor}, - {&CLSID_NetworkPlaces, &ISF_NetworkPlaces_Constructor}, {&CLSID_FontsFolderShortcut, &ISF_Fonts_Constructor}, {&CLSID_Printers, &ISF_Printers_Constructor}, {&CLSID_AdminFolderShortcut, &ISF_AdminTools_Constructor}, @@ -181,7 +181,7 @@ HRESULT WINAPI SHCoCreateInstance( FreeLibrary( hLibrary ); hres = E_ACCESSDENIED; goto end; - } else if (! SUCCEEDED(hres = DllGetClassObject(myclsid, &IID_IClassFactory, (LPVOID*)&pcf))) { + } else if (FAILED(hres = DllGetClassObject(myclsid, &IID_IClassFactory, (LPVOID*)&pcf))) { TRACE("GetClassObject failed 0x%08x\n", hres); goto end; } @@ -538,7 +538,7 @@ void WINAPI DragAcceptFiles(HWND hWnd, BOOL b) void WINAPI DragFinish(HDROP h) { TRACE("\n"); - GlobalFree((HGLOBAL)h); + GlobalFree(h); } /************************************************************************* @@ -551,7 +551,7 @@ BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p) TRACE("\n"); - lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop); + lpDropFileStruct = GlobalLock(hDrop); *p = lpDropFileStruct->pt; bRet = lpDropFileStruct->fNC; @@ -572,7 +572,7 @@ UINT WINAPI DragQueryFileA( { LPSTR lpDrop; UINT i = 0; - DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop); + DROPFILES *lpDropFileStruct = GlobalLock(hDrop); TRACE("(%p, %x, %p, %u)\n", hDrop,lFile,lpszFile,lLength); @@ -627,7 +627,7 @@ UINT WINAPI DragQueryFileW( { LPWSTR lpwDrop; UINT i = 0; - DROPFILES *lpDropFileStruct = (DROPFILES *) GlobalLock(hDrop); + DROPFILES *lpDropFileStruct = GlobalLock(hDrop); TRACE("(%p, %x, %p, %u)\n", hDrop,lFile,lpszwFile,lLength); From 2afeb94e207a9c847c7acefaa0d23258740dd510 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 10 Nov 2009 21:31:37 +0000 Subject: [PATCH 010/140] sync SHGetFileInfo and CommandLineToArgvW to wine 1.1.32 svn path=/trunk/; revision=44082 --- reactos/dll/win32/shell32/shell32_main.c | 33 +++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/reactos/dll/win32/shell32/shell32_main.c b/reactos/dll/win32/shell32/shell32_main.c index cc81761a021..f07818829bf 100644 --- a/reactos/dll/win32/shell32/shell32_main.c +++ b/reactos/dll/win32/shell32/shell32_main.c @@ -84,7 +84,7 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs) } argv[0]=(LPWSTR)(argv+1); if (numargs) - *numargs=2; + *numargs=1; return argv; } @@ -323,8 +323,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, (flags & SHGFI_PIDL)? "pidl" : debugstr_w(path), dwFileAttributes, psfi, psfi->dwAttributes, sizeofpsfi, flags); - if ( (flags & SHGFI_USEFILEATTRIBUTES) && - (flags & (SHGFI_ATTRIBUTES|SHGFI_EXETYPE|SHGFI_PIDL))) + if (!path) return FALSE; /* windows initializes these values regardless of the flags */ @@ -403,7 +402,8 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, { psfi->dwAttributes = 0xffffffff; } - IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast, + if (psfParent) + IShellFolder_GetAttributesOf( psfParent, 1, (LPCITEMIDLIST*)&pidlLast, &(psfi->dwAttributes) ); } @@ -520,7 +520,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, &uDummy, (LPVOID*)&pei); if (SUCCEEDED(hr)) { - hr = pei->lpVtbl->GetIconLocation(pei, uGilFlags, + hr = IExtractIconW_GetIconLocation(pei, uGilFlags, szLocation, MAX_PATH, &iIndex, &uFlags); if (uFlags & GIL_NOTFILENAME) @@ -530,7 +530,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, wcscpy (psfi->szDisplayName, szLocation); psfi->iIcon = iIndex; } - pei->lpVtbl->Release(pei); + IExtractIconW_Release(pei); } } } @@ -553,7 +553,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, static const WCHAR p1W[] = {'%','1',0}; psfi->iIcon = 0; - szExt = (LPWSTR) PathFindExtensionW(sTemp); + szExt = PathFindExtensionW(sTemp); if ( szExt && HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) && HCR_GetDefaultIconW(sTemp, sTemp, MAX_PATH, &icon_idx)) @@ -569,18 +569,22 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, } else { - IconNotYetLoaded=FALSE; + UINT ret; if (flags & SHGFI_SMALLICON) - PrivateExtractIconsW( sTemp,icon_idx, + ret = PrivateExtractIconsW( sTemp,icon_idx, GetSystemMetrics( SM_CXSMICON ), GetSystemMetrics( SM_CYSMICON ), &psfi->hIcon, 0, 1, 0); else - PrivateExtractIconsW( sTemp, icon_idx, + ret = PrivateExtractIconsW( sTemp, icon_idx, GetSystemMetrics( SM_CXICON), GetSystemMetrics( SM_CYICON), &psfi->hIcon, 0, 1, 0); - psfi->iIcon = icon_idx; + if (ret != 0 && ret != 0xFFFFFFFF) + { + IconNotYetLoaded=FALSE; + psfi->iIcon = icon_idx; + } } } } @@ -593,7 +597,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, ret = FALSE; } } - if (ret) + if (ret && (flags & SHGFI_SYSICONINDEX)) { if (flags & SHGFI_SMALLICON) ret = (DWORD_PTR) ShellSmallIconList; @@ -633,6 +637,11 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes, /************************************************************************* * SHGetFileInfoA [SHELL32.@] + * + * Note: + * MSVBVM60.__vbaNew2 expects this function to return a value in range + * 1 .. 0x7fff when the function succeeds and flags does not contain + * SHGFI_EXETYPE or SHGFI_SYSICONINDEX (see bug 7701) */ DWORD_PTR WINAPI SHGetFileInfoA(LPCSTR path,DWORD dwFileAttributes, SHFILEINFOA *psfi, UINT sizeofpsfi, From a72dd3434cbb05c9d4044b5a86e94ee2810516c7 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 10 Nov 2009 21:36:55 +0000 Subject: [PATCH 011/140] sync shlwapi to wine 1.1.32 svn path=/trunk/; revision=44083 --- reactos/dll/win32/shlwapi/regstream.c | 4 +- reactos/dll/win32/shlwapi/url.c | 93 +++++++++++---------------- 2 files changed, 38 insertions(+), 59 deletions(-) diff --git a/reactos/dll/win32/shlwapi/regstream.c b/reactos/dll/win32/shlwapi/regstream.c index eb906a7dc8d..4dc15ad38dc 100644 --- a/reactos/dll/win32/shlwapi/regstream.c +++ b/reactos/dll/win32/shlwapi/regstream.c @@ -221,7 +221,7 @@ static HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, D return STG_E_INVALIDFUNCTION; /* we cut off the high part here */ - This->dwPos = tmp.LowPart; + This->dwPos = tmp.u.LowPart; if (plibNewPosition) plibNewPosition->QuadPart = This->dwPos; @@ -240,7 +240,7 @@ static HRESULT WINAPI IStream_fnSetSize (IStream * iface, ULARGE_INTEGER libNewS TRACE("(%p, %s)\n", This, wine_dbgstr_longlong(libNewSize.QuadPart)); /* we cut off the high part here */ - newLen = libNewSize.LowPart; + newLen = libNewSize.u.LowPart; newBuf = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pbBuffer, newLen); if (!newBuf) return STG_E_INSUFFICIENTMEMORY; diff --git a/reactos/dll/win32/shlwapi/url.c b/reactos/dll/win32/shlwapi/url.c index f03129748c4..2b7a8cd1686 100644 --- a/reactos/dll/win32/shlwapi/url.c +++ b/reactos/dll/win32/shlwapi/url.c @@ -145,40 +145,29 @@ static DWORD get_scheme_code(LPCWSTR scheme, DWORD scheme_len) HRESULT WINAPI ParseURLA(LPCSTR x, PARSEDURLA *y) { WCHAR scheme[INTERNET_MAX_SCHEME_LENGTH]; - DWORD cnt, len; + const char *ptr = x; + int len; - y->nScheme = URL_SCHEME_INVALID; - if (y->cbSize != sizeof(*y)) return E_INVALIDARG; - /* FIXME: leading white space generates error of 0x80041001 which - * is undefined - */ - if (*x <= ' ') return 0x80041001; - cnt = 0; - y->cchProtocol = 0; - y->pszProtocol = x; - while (*x) { - if (*x == ':') { - y->cchProtocol = cnt; - cnt = -1; - y->pszSuffix = x+1; - break; - } - x++; - cnt++; - } + TRACE("%s %p\n", debugstr_a(x), y); - /* check for no scheme in string start */ - /* (apparently schemes *must* be larger than a single character) */ - if ((*x == '\0') || (y->cchProtocol <= 1)) { + if(y->cbSize != sizeof(*y)) + return E_INVALIDARG; + + while(*ptr && (isalnum(*ptr) || *ptr == '-')) + ptr++; + + if (*ptr != ':' || ptr <= x+1) { y->pszProtocol = NULL; return 0x80041001; } - /* found scheme, set length of remainder */ - y->cchSuffix = lstrlenA(y->pszSuffix); + y->pszProtocol = x; + y->cchProtocol = ptr-x; + y->pszSuffix = ptr+1; + y->cchSuffix = strlen(y->pszSuffix); - len = MultiByteToWideChar(CP_ACP, 0, y->pszProtocol, y->cchProtocol, - scheme, sizeof(scheme)/sizeof(WCHAR)); + len = MultiByteToWideChar(CP_ACP, 0, x, ptr-x, + scheme, sizeof(scheme)/sizeof(WCHAR)); y->nScheme = get_scheme_code(scheme, len); return S_OK; @@ -191,38 +180,26 @@ HRESULT WINAPI ParseURLA(LPCSTR x, PARSEDURLA *y) */ HRESULT WINAPI ParseURLW(LPCWSTR x, PARSEDURLW *y) { - DWORD cnt; + const WCHAR *ptr = x; - y->nScheme = URL_SCHEME_INVALID; - if (y->cbSize != sizeof(*y)) return E_INVALIDARG; - /* FIXME: leading white space generates error of 0x80041001 which - * is undefined - */ - if (*x <= ' ') return 0x80041001; - cnt = 0; - y->cchProtocol = 0; - y->pszProtocol = x; - while (*x) { - if (*x == ':') { - y->cchProtocol = cnt; - cnt = -1; - y->pszSuffix = x+1; - break; - } - x++; - cnt++; - } + TRACE("%s %p\n", debugstr_w(x), y); - /* check for no scheme in string start */ - /* (apparently schemes *must* be larger than a single character) */ - if ((*x == '\0') || (y->cchProtocol <= 1)) { + if(y->cbSize != sizeof(*y)) + return E_INVALIDARG; + + while(*ptr && (isalnumW(*ptr) || *ptr == '-')) + ptr++; + + if (*ptr != ':' || ptr <= x+1) { y->pszProtocol = NULL; return 0x80041001; } - /* found scheme, set length of remainder */ - y->cchSuffix = lstrlenW(y->pszSuffix); - y->nScheme = get_scheme_code(y->pszProtocol, y->cchProtocol); + y->pszProtocol = x; + y->cchProtocol = ptr-x; + y->pszSuffix = ptr+1; + y->cchSuffix = strlenW(y->pszSuffix); + y->nScheme = get_scheme_code(x, ptr-x); return S_OK; } @@ -2141,6 +2118,7 @@ HRESULT WINAPI UrlGetPartW(LPCWSTR pszIn, LPWSTR pszOut, LPDWORD pcchOut, BOOL WINAPI PathIsURLA(LPCSTR lpstrPath) { PARSEDURLA base; + HRESULT hres; TRACE("%s\n", debugstr_a(lpstrPath)); @@ -2148,8 +2126,8 @@ BOOL WINAPI PathIsURLA(LPCSTR lpstrPath) /* get protocol */ base.cbSize = sizeof(base); - ParseURLA(lpstrPath, &base); - return (base.nScheme != URL_SCHEME_INVALID); + hres = ParseURLA(lpstrPath, &base); + return hres == S_OK && (base.nScheme != URL_SCHEME_INVALID); } /************************************************************************* @@ -2160,6 +2138,7 @@ BOOL WINAPI PathIsURLA(LPCSTR lpstrPath) BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath) { PARSEDURLW base; + HRESULT hres; TRACE("%s\n", debugstr_w(lpstrPath)); @@ -2167,8 +2146,8 @@ BOOL WINAPI PathIsURLW(LPCWSTR lpstrPath) /* get protocol */ base.cbSize = sizeof(base); - ParseURLW(lpstrPath, &base); - return (base.nScheme != URL_SCHEME_INVALID); + hres = ParseURLW(lpstrPath, &base); + return hres == S_OK && (base.nScheme != URL_SCHEME_INVALID); } /************************************************************************* From a6c89f30fa824a5adfaecb8c9214ab3393f98ef4 Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Tue, 10 Nov 2009 22:52:41 +0000 Subject: [PATCH 012/140] Fix Japanese bug #4776. svn path=/trunk/; revision=44084 --- reactos/dll/win32/user32/windows/menu.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/user32/windows/menu.c b/reactos/dll/win32/user32/windows/menu.c index 899b778ef81..3f3916c6481 100644 --- a/reactos/dll/win32/user32/windows/menu.c +++ b/reactos/dll/win32/user32/windows/menu.c @@ -1224,8 +1224,16 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode ) } else /* Not a popup */ { - if (*str == 0) - flags = MF_SEPARATOR; + if(!unicode) + { + if (*str == 0) + flags = MF_SEPARATOR; + } + else + { + if (*(LPCWSTR)str == 0) + flags = MF_SEPARATOR; + } if (flags & MF_SEPARATOR) { From 662ba31e988fd9ee9fda1944deaef13b7fb7d68a Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Tue, 10 Nov 2009 23:00:51 +0000 Subject: [PATCH 013/140] - Fix HalDisableSystemInterrupt -- it doesn't return anything. - Fix VideoPortEnable/DisableInterrupt -- they should only fail if the driver didn't provide an ISR (documented). svn path=/trunk/; revision=44085 --- reactos/hal/hal/hal.c | 11 ++++------- reactos/hal/halarm/generic/hal.c | 11 ++++------- reactos/hal/halppc/generic/irql.c | 9 ++++++--- reactos/hal/halx86/mp/mpsirql.c | 12 +++++++----- reactos/include/ndk/halfuncs.h | 2 +- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/reactos/hal/hal/hal.c b/reactos/hal/hal/hal.c index 5833bc6bace..cb255fc997f 100644 --- a/reactos/hal/hal/hal.c +++ b/reactos/hal/hal/hal.c @@ -213,15 +213,12 @@ HalCalibratePerformanceCounter( } -BOOLEAN +VOID NTAPI -HalDisableSystemInterrupt( - ULONG Vector, - KIRQL Irql) +HalDisableSystemInterrupt(ULONG Vector, + KIRQL Irql) { - UNIMPLEMENTED; - - return TRUE; + UNIMPLEMENTED; } diff --git a/reactos/hal/halarm/generic/hal.c b/reactos/hal/halarm/generic/hal.c index 43510df2074..a3d70b88b5f 100644 --- a/reactos/hal/halarm/generic/hal.c +++ b/reactos/hal/halarm/generic/hal.c @@ -276,15 +276,12 @@ HalCalibratePerformanceCounter( } -BOOLEAN +VOID NTAPI -HalDisableSystemInterrupt( - ULONG Vector, - KIRQL Irql) +HalDisableSystemInterrupt(ULONG Vector, + KIRQL Irql) { - UNIMPLEMENTED; - - return TRUE; + UNIMPLEMENTED; } VOID diff --git a/reactos/hal/halppc/generic/irql.c b/reactos/hal/halppc/generic/irql.c index bc1604e6c31..2a3b404f596 100644 --- a/reactos/hal/halppc/generic/irql.c +++ b/reactos/hal/halppc/generic/irql.c @@ -356,7 +356,7 @@ VOID NTAPI HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2) HalpEndSystemInterrupt(Irql); } -BOOLEAN +VOID NTAPI HalDisableSystemInterrupt( ULONG Vector, @@ -365,7 +365,10 @@ HalDisableSystemInterrupt( ULONG irq; if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS) - return FALSE; + { + ASSERT(FALSE); + return; + } irq = Vector - IRQ_BASE; pic_mask.both |= (1 << irq); @@ -378,7 +381,7 @@ HalDisableSystemInterrupt( WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave)); } - return TRUE; + return; } diff --git a/reactos/hal/halx86/mp/mpsirql.c b/reactos/hal/halx86/mp/mpsirql.c index d8b447583b3..957cffd8f98 100644 --- a/reactos/hal/halx86/mp/mpsirql.c +++ b/reactos/hal/halx86/mp/mpsirql.c @@ -336,9 +336,10 @@ HalEndSystemInterrupt (KIRQL Irql, HalpLowerIrql (Irql, TRUE); } -BOOLEAN NTAPI -HalDisableSystemInterrupt (ULONG Vector, - KIRQL Irql) +VOID +NTAPI +HalDisableSystemInterrupt(ULONG Vector, + KIRQL Irql) { ULONG irq; @@ -348,13 +349,14 @@ HalDisableSystemInterrupt (ULONG Vector, Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) { DPRINT1("Not a device interrupt, vector=%x\n", Vector); - return FALSE; + ASSERT(FALSE); + return; } irq = VECTOR2IRQ (Vector); IOAPICMaskIrq (irq); - return TRUE; + return; } diff --git a/reactos/include/ndk/halfuncs.h b/reactos/include/ndk/halfuncs.h index 7e318156a29..c4121cc3ddf 100644 --- a/reactos/include/ndk/halfuncs.h +++ b/reactos/include/ndk/halfuncs.h @@ -144,7 +144,7 @@ HalClearSoftwareInterrupt( ); NTHALAPI -BOOLEAN +VOID NTAPI HalDisableSystemInterrupt( ULONG Vector, From 0c19771290db33da0d145ccb51ce30729904840f Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Tue, 10 Nov 2009 23:01:42 +0000 Subject: [PATCH 014/140] - Missed in previous commit: Fix VideoPortEnable/DisableInterrupt -- they should only fail if the driver didn't provide an ISR (documented). svn path=/trunk/; revision=44086 --- reactos/drivers/video/videoprt/interrupt.c | 58 ++++++++++++++-------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/reactos/drivers/video/videoprt/interrupt.c b/reactos/drivers/video/videoprt/interrupt.c index 67efe8fe93d..54a5b9566cb 100644 --- a/reactos/drivers/video/videoprt/interrupt.c +++ b/reactos/drivers/video/videoprt/interrupt.c @@ -106,42 +106,56 @@ IntVideoPortSetupInterrupt( /* * @implemented */ - -VP_STATUS NTAPI +VP_STATUS +NTAPI VideoPortEnableInterrupt(IN PVOID HwDeviceExtension) { - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - BOOLEAN Status; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + BOOLEAN InterruptValid; - TRACE_(VIDEOPRT, "VideoPortEnableInterrupt\n"); + /* Get the device extension */ + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); - DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + /* Fail if the driver didn't register an ISR */ + if (!DeviceExtension->DriverExtension->InitializationData.HwInterrupt) + { + /* No ISR, no interrupts */ + return ERROR_INVALID_FUNCTION; + } - Status = HalEnableSystemInterrupt( - DeviceExtension->InterruptVector, - 0, - DeviceExtension->InterruptLevel); + /* Re-enable the interrupt and return */ + InterruptValid = HalEnableSystemInterrupt(DeviceExtension->InterruptVector, + 0, + DeviceExtension->InterruptLevel); - return Status ? NO_ERROR : ERROR_INVALID_PARAMETER; + /* Make sure the interrupt was valid */ + ASSERT(InterruptValid == TRUE); + + /* Return to caller */ + return NO_ERROR; } /* * @implemented */ - -VP_STATUS NTAPI +VP_STATUS +NTAPI VideoPortDisableInterrupt(IN PVOID HwDeviceExtension) { - PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - BOOLEAN Status; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; - TRACE_(VIDEOPRT, "VideoPortDisableInterrupt\n"); + /* Get the device extension */ + DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); - DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension); + /* Fail if the driver didn't register an ISR */ + if (!DeviceExtension->DriverExtension->InitializationData.HwInterrupt) + { + /* No ISR, no interrupts */ + return ERROR_INVALID_FUNCTION; + } - Status = HalDisableSystemInterrupt( - DeviceExtension->InterruptVector, - 0); - - return Status ? NO_ERROR : ERROR_INVALID_PARAMETER; + /* Disable the interrupt and return */ + HalDisableSystemInterrupt(DeviceExtension->InterruptVector, + 0); + return NO_ERROR; } From 49ce5d1d632f10101ff70f6b30fa545962e043b0 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Wed, 11 Nov 2009 03:09:42 +0000 Subject: [PATCH 015/140] Non-ANSI names need _CRTIMP too svn path=/trunk/; revision=44089 --- reactos/include/crt/conio.h | 18 ++++++------ reactos/include/crt/ctype.h | 12 ++++---- reactos/include/crt/direct.h | 8 +++--- reactos/include/crt/io.h | 54 +++++++++++++++++------------------ reactos/include/crt/memory.h | 4 +-- reactos/include/crt/process.h | 52 ++++++++++++++++----------------- reactos/include/crt/search.h | 4 +-- reactos/include/crt/stdio.h | 20 ++++++------- reactos/include/crt/time.h | 2 +- reactos/include/crt/wchar.h | 22 +++++++------- 10 files changed, 98 insertions(+), 98 deletions(-) diff --git a/reactos/include/crt/conio.h b/reactos/include/crt/conio.h index 74fbbac7524..3fc47269383 100644 --- a/reactos/include/crt/conio.h +++ b/reactos/include/crt/conio.h @@ -84,15 +84,15 @@ extern "C" { #endif #ifndef NO_OLDNAMES - _CRT_NONSTDC_DEPRECATE(_cgets) _CRT_INSECURE_DEPRECATE(_cgets_s) _CRTIMP char *__cdecl cgets(char *_Buffer); - _CRT_NONSTDC_DEPRECATE(_cprintf) _CRTIMP int __cdecl cprintf(const char *_Format,...); - _CRT_NONSTDC_DEPRECATE(_cputs) _CRTIMP int __cdecl cputs(const char *_Str); - _CRT_NONSTDC_DEPRECATE(_cscanf) _CRTIMP int __cdecl cscanf(const char *_Format,...); - _CRT_NONSTDC_DEPRECATE(_getch) _CRTIMP int __cdecl getch(void); - _CRT_NONSTDC_DEPRECATE(_getche) _CRTIMP int __cdecl getche(void); - _CRT_NONSTDC_DEPRECATE(_kbhit) _CRTIMP int __cdecl kbhit(void); - _CRT_NONSTDC_DEPRECATE(_putch) _CRTIMP int __cdecl putch(int _Ch); - _CRT_NONSTDC_DEPRECATE(_ungetch) _CRTIMP int __cdecl ungetch(int _Ch); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_cgets) _CRT_INSECURE_DEPRECATE(_cgets_s) _CRTIMP char *__cdecl cgets(char *_Buffer); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_cprintf) _CRTIMP int __cdecl cprintf(const char *_Format,...); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_cputs) _CRTIMP int __cdecl cputs(const char *_Str); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_cscanf) _CRTIMP int __cdecl cscanf(const char *_Format,...); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_getch) _CRTIMP int __cdecl getch(void); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_getche) _CRTIMP int __cdecl getche(void); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_kbhit) _CRTIMP int __cdecl kbhit(void); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_putch) _CRTIMP int __cdecl putch(int _Ch); + _CRTIMP _CRT_NONSTDC_DEPRECATE(_ungetch) _CRTIMP int __cdecl ungetch(int _Ch); #if (defined(_X86_) && !defined(__x86_64)) _CRT_NONSTDC_DEPRECATE(_inp) _CRTIMP int __cdecl inp(unsigned short); diff --git a/reactos/include/crt/ctype.h b/reactos/include/crt/ctype.h index d881539be31..74f7b1eb170 100644 --- a/reactos/include/crt/ctype.h +++ b/reactos/include/crt/ctype.h @@ -112,7 +112,7 @@ extern "C" { _CRTIMP int __cdecl __iscsymf(int _C); _CRTIMP int __cdecl __iscsym(int _C); #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES) -int __cdecl isblank(int _C); + _CRTIMP int __cdecl isblank(int _C); #endif #endif /* !_CTYPE_DEFINED */ @@ -156,7 +156,7 @@ int __cdecl isblank(int _C); _CRTIMP int __cdecl is_wctype(wint_t _C,wctype_t _Type); #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES) -int __cdecl iswblank(wint_t _C); + _CRTIMP int __cdecl iswblank(wint_t _C); #endif #endif @@ -241,10 +241,10 @@ int __cdecl iswblank(wint_t _C); #ifndef NO_OLDNAMES #ifndef _CTYPE_DEFINED - _CRT_NONSTDC_DEPRECATE(__isascii) _CRTIMP int __cdecl isascii(int _C); - _CRT_NONSTDC_DEPRECATE(__toascii) _CRTIMP int __cdecl toascii(int _C); - _CRT_NONSTDC_DEPRECATE(__iscsymf) _CRTIMP int __cdecl iscsymf(int _C); - _CRT_NONSTDC_DEPRECATE(__iscsym) _CRTIMP int __cdecl iscsym(int _C); + _CRTIMP _CRT_NONSTDC_DEPRECATE(__isascii) _CRTIMP int __cdecl isascii(int _C); + _CRTIMP _CRT_NONSTDC_DEPRECATE(__toascii) _CRTIMP int __cdecl toascii(int _C); + _CRTIMP _CRT_NONSTDC_DEPRECATE(__iscsymf) _CRTIMP int __cdecl iscsymf(int _C); + _CRTIMP _CRT_NONSTDC_DEPRECATE(__iscsym) _CRTIMP int __cdecl iscsym(int _C); #else #define isascii __isascii #define toascii __toascii diff --git a/reactos/include/crt/direct.h b/reactos/include/crt/direct.h index f64ceba4d7a..e9eb50b4072 100644 --- a/reactos/include/crt/direct.h +++ b/reactos/include/crt/direct.h @@ -54,10 +54,10 @@ extern "C" { #define diskfree_t _diskfree_t - char *__cdecl getcwd(char *_DstBuf,int _SizeInBytes); - int __cdecl chdir(const char *_Path); - int __cdecl mkdir(const char *_Path); - int __cdecl rmdir(const char *_Path); + _CRTIMP char *__cdecl getcwd(char *_DstBuf,int _SizeInBytes); + _CRTIMP int __cdecl chdir(const char *_Path); + _CRTIMP int __cdecl mkdir(const char *_Path); + _CRTIMP int __cdecl rmdir(const char *_Path); #endif #ifdef __cplusplus diff --git a/reactos/include/crt/io.h b/reactos/include/crt/io.h index 0accf137df2..2eaae8f4581 100644 --- a/reactos/include/crt/io.h +++ b/reactos/include/crt/io.h @@ -190,7 +190,7 @@ _CRTIMP char* __cdecl _getcwd (char*, int); int __cdecl rename(const char *_OldFilename,const char *_NewFilename); _CRTIMP int __cdecl _unlink(const char *_Filename); #ifndef NO_OLDNAMES - int __cdecl unlink(const char *_Filename); + _CRTIMP int __cdecl unlink(const char *_Filename); #endif #endif @@ -240,12 +240,12 @@ _CRTIMP char* __cdecl _getcwd (char*, int); #ifndef NO_OLDNAMES #ifndef _UWIN - int __cdecl chdir (const char *); - char *__cdecl getcwd (char *, int); - int __cdecl mkdir (const char *); - char *__cdecl mktemp(char *); - int __cdecl rmdir (const char*); - int __cdecl chmod (const char *, int); + _CRTIMP int __cdecl chdir (const char *); + _CRTIMP char *__cdecl getcwd (char *, int); + _CRTIMP int __cdecl mkdir (const char *); + _CRTIMP char *__cdecl mktemp(char *); + _CRTIMP int __cdecl rmdir (const char*); + _CRTIMP int __cdecl chmod (const char *, int); #endif /* _UWIN */ #endif /* Not NO_OLDNAMES */ @@ -297,26 +297,26 @@ _CRTIMP char* __cdecl _getcwd (char*, int); _CRTIMP int __cdecl _open_osfhandle(intptr_t _OSFileHandle,int _Flags); #ifndef NO_OLDNAMES - int __cdecl access(const char *_Filename,int _AccessMode); - int __cdecl chmod(const char *_Filename,int _AccessMode); - int __cdecl chsize(int _FileHandle,long _Size); - int __cdecl close(int _FileHandle); - int __cdecl creat(const char *_Filename,int _PermissionMode); - int __cdecl dup(int _FileHandle); - int __cdecl dup2(int _FileHandleSrc,int _FileHandleDst); - int __cdecl eof(int _FileHandle); - long __cdecl filelength(int _FileHandle); - int __cdecl isatty(int _FileHandle); - int __cdecl locking(int _FileHandle,int _LockMode,long _NumOfBytes); - long __cdecl lseek(int _FileHandle,long _Offset,int _Origin); - char *__cdecl mktemp(char *_TemplateName); - int __cdecl open(const char *_Filename,int _OpenFlag,...); - int __cdecl read(int _FileHandle,void *_DstBuf,unsigned int _MaxCharCount); - int __cdecl setmode(int _FileHandle,int _Mode); - int __cdecl sopen(const char *_Filename,int _OpenFlag,int _ShareFlag,...); - long __cdecl tell(int _FileHandle); - int __cdecl umask(int _Mode); - int __cdecl write(int _Filehandle,const void *_Buf,unsigned int _MaxCharCount); + _CRTIMP int __cdecl access(const char *_Filename,int _AccessMode); + _CRTIMP int __cdecl chmod(const char *_Filename,int _AccessMode); + _CRTIMP int __cdecl chsize(int _FileHandle,long _Size); + _CRTIMP int __cdecl close(int _FileHandle); + _CRTIMP int __cdecl creat(const char *_Filename,int _PermissionMode); + _CRTIMP int __cdecl dup(int _FileHandle); + _CRTIMP int __cdecl dup2(int _FileHandleSrc,int _FileHandleDst); + _CRTIMP int __cdecl eof(int _FileHandle); + _CRTIMP long __cdecl filelength(int _FileHandle); + _CRTIMP int __cdecl isatty(int _FileHandle); + _CRTIMP int __cdecl locking(int _FileHandle,int _LockMode,long _NumOfBytes); + _CRTIMP long __cdecl lseek(int _FileHandle,long _Offset,int _Origin); + _CRTIMP char *__cdecl mktemp(char *_TemplateName); + _CRTIMP int __cdecl open(const char *_Filename,int _OpenFlag,...); + _CRTIMP int __cdecl read(int _FileHandle,void *_DstBuf,unsigned int _MaxCharCount); + _CRTIMP int __cdecl setmode(int _FileHandle,int _Mode); + _CRTIMP int __cdecl sopen(const char *_Filename,int _OpenFlag,int _ShareFlag,...); + _CRTIMP long __cdecl tell(int _FileHandle); + _CRTIMP int __cdecl umask(int _Mode); + _CRTIMP int __cdecl write(int _Filehandle,const void *_Buf,unsigned int _MaxCharCount); #endif #ifdef __cplusplus diff --git a/reactos/include/crt/memory.h b/reactos/include/crt/memory.h index b0732953c4d..78be8083c61 100644 --- a/reactos/include/crt/memory.h +++ b/reactos/include/crt/memory.h @@ -29,8 +29,8 @@ extern "C" { void *__cdecl memset(void *_Dst,int _Val,size_t _Size); #ifndef NO_OLDNAMES - void *__cdecl memccpy(void *_Dst,const void *_Src,int _Val,size_t _Size); - int __cdecl memicmp(const void *_Buf1,const void *_Buf2,size_t _Size); + _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 diff --git a/reactos/include/crt/process.h b/reactos/include/crt/process.h index 35555e59168..591032f4d9d 100644 --- a/reactos/include/crt/process.h +++ b/reactos/include/crt/process.h @@ -135,42 +135,42 @@ extern "C" { #define WAIT_CHILD _WAIT_CHILD #define WAIT_GRANDCHILD _WAIT_GRANDCHILD - intptr_t __cdecl cwait(int *_TermStat,intptr_t _ProcHandle,int _Action); + _CRTIMP intptr_t __cdecl cwait(int *_TermStat,intptr_t _ProcHandle,int _Action); #ifdef __GNUC__ - int __cdecl execl(const char *_Filename,const char *_ArgList,...); - int __cdecl execle(const char *_Filename,const char *_ArgList,...); - int __cdecl execlp(const char *_Filename,const char *_ArgList,...); - int __cdecl execlpe(const char *_Filename,const char *_ArgList,...); + _CRTIMP int __cdecl execl(const char *_Filename,const char *_ArgList,...); + _CRTIMP int __cdecl execle(const char *_Filename,const char *_ArgList,...); + _CRTIMP int __cdecl execlp(const char *_Filename,const char *_ArgList,...); + _CRTIMP int __cdecl execlpe(const char *_Filename,const char *_ArgList,...); #else - intptr_t __cdecl execl(const char *_Filename,const char *_ArgList,...); - intptr_t __cdecl execle(const char *_Filename,const char *_ArgList,...); - intptr_t __cdecl execlp(const char *_Filename,const char *_ArgList,...); - intptr_t __cdecl execlpe(const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl execl(const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl execle(const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl execlp(const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl execlpe(const char *_Filename,const char *_ArgList,...); #endif - intptr_t __cdecl spawnl(int,const char *_Filename,const char *_ArgList,...); - intptr_t __cdecl spawnle(int,const char *_Filename,const char *_ArgList,...); - intptr_t __cdecl spawnlp(int,const char *_Filename,const char *_ArgList,...); - intptr_t __cdecl spawnlpe(int,const char *_Filename,const char *_ArgList,...); - int __cdecl getpid(void); + _CRTIMP intptr_t __cdecl spawnl(int,const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl spawnle(int,const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl spawnlp(int,const char *_Filename,const char *_ArgList,...); + _CRTIMP intptr_t __cdecl spawnlpe(int,const char *_Filename,const char *_ArgList,...); + _CRTIMP int __cdecl getpid(void); #ifdef __GNUC__ /* Those methods are predefined by gcc builtins to return int. So to prevent stupid warnings, define them in POSIX way. This is save, because those methods do not return in success case, so that the return value is not really dependent to its scalar width. */ - int __cdecl execv(const char *_Filename,char *const _ArgList[]); - int __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]); - int __cdecl execvp(const char *_Filename,char *const _ArgList[]); - int __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]); + _CRTIMP int __cdecl execv(const char *_Filename,char *const _ArgList[]); + _CRTIMP int __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]); + _CRTIMP int __cdecl execvp(const char *_Filename,char *const _ArgList[]); + _CRTIMP int __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]); #else - intptr_t __cdecl execv(const char *_Filename,char *const _ArgList[]); - intptr_t __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]); - intptr_t __cdecl execvp(const char *_Filename,char *const _ArgList[]); - intptr_t __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]); + _CRTIMP intptr_t __cdecl execv(const char *_Filename,char *const _ArgList[]); + _CRTIMP intptr_t __cdecl execve(const char *_Filename,char *const _ArgList[],char *const _Env[]); + _CRTIMP intptr_t __cdecl execvp(const char *_Filename,char *const _ArgList[]); + _CRTIMP intptr_t __cdecl execvpe(const char *_Filename,char *const _ArgList[],char *const _Env[]); #endif - intptr_t __cdecl spawnv(int,const char *_Filename,char *const _ArgList[]); - intptr_t __cdecl spawnve(int,const char *_Filename,char *const _ArgList[],char *const _Env[]); - intptr_t __cdecl spawnvp(int,const char *_Filename,char *const _ArgList[]); - intptr_t __cdecl spawnvpe(int,const char *_Filename,char *const _ArgList[],char *const _Env[]); + _CRTIMP intptr_t __cdecl spawnv(int,const char *_Filename,char *const _ArgList[]); + _CRTIMP intptr_t __cdecl spawnve(int,const char *_Filename,char *const _ArgList[],char *const _Env[]); + _CRTIMP intptr_t __cdecl spawnvp(int,const char *_Filename,char *const _ArgList[]); + _CRTIMP intptr_t __cdecl spawnvpe(int,const char *_Filename,char *const _ArgList[],char *const _Env[]); #endif #ifdef __cplusplus diff --git a/reactos/include/crt/search.h b/reactos/include/crt/search.h index a58544893d3..1f487bfd546 100644 --- a/reactos/include/crt/search.h +++ b/reactos/include/crt/search.h @@ -22,8 +22,8 @@ extern "C" { _CRTIMP void *__cdecl _lsearch(const void *_Key,void *_Base,unsigned int *_NumOfElements,unsigned int _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); #ifndef NO_OLDNAMES - void *__cdecl lfind(const void *_Key,const void *_Base,unsigned int *_NumOfElements,unsigned int _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); - void *__cdecl lsearch(const void *_Key,void *_Base,unsigned int *_NumOfElements,unsigned int _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); + _CRTIMP void *__cdecl lfind(const void *_Key,const void *_Base,unsigned int *_NumOfElements,unsigned int _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); + _CRTIMP void *__cdecl lsearch(const void *_Key,void *_Base,unsigned int *_NumOfElements,unsigned int _SizeOfElements,int (__cdecl *_PtFuncCompare)(const void *,const void *)); #endif #ifdef __cplusplus diff --git a/reactos/include/crt/stdio.h b/reactos/include/crt/stdio.h index fa845ac3b78..0125112da93 100644 --- a/reactos/include/crt/stdio.h +++ b/reactos/include/crt/stdio.h @@ -390,16 +390,16 @@ extern "C" { #define P_tmpdir _P_tmpdir #define SYS_OPEN _SYS_OPEN - char *__cdecl tempnam(const char *_Directory,const char *_FilePrefix); - int __cdecl fcloseall(void); - FILE *__cdecl fdopen(int _FileHandle,const char *_Format); - int __cdecl fgetchar(void); - int __cdecl fileno(FILE *_File); - int __cdecl flushall(void); - int __cdecl fputchar(int _Ch); - int __cdecl getw(FILE *_File); - int __cdecl putw(int _Ch,FILE *_File); - int __cdecl rmtmp(void); + _CRTIMP char *__cdecl tempnam(const char *_Directory,const char *_FilePrefix); + _CRTIMP int __cdecl fcloseall(void); + _CRTIMP FILE *__cdecl fdopen(int _FileHandle,const char *_Format); + _CRTIMP int __cdecl fgetchar(void); + _CRTIMP int __cdecl fileno(FILE *_File); + _CRTIMP int __cdecl flushall(void); + _CRTIMP int __cdecl fputchar(int _Ch); + _CRTIMP int __cdecl getw(FILE *_File); + _CRTIMP int __cdecl putw(int _Ch,FILE *_File); + _CRTIMP int __cdecl rmtmp(void); #endif #ifdef __cplusplus diff --git a/reactos/include/crt/time.h b/reactos/include/crt/time.h index d714fa62590..d09a8d9163a 100644 --- a/reactos/include/crt/time.h +++ b/reactos/include/crt/time.h @@ -205,7 +205,7 @@ __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); } _CRTIMP extern int daylight; _CRTIMP extern long timezone; _CRTIMP extern char *tzname[2]; - void __cdecl tzset(void); + _CRTIMP void __cdecl tzset(void); #endif #ifdef __cplusplus diff --git a/reactos/include/crt/wchar.h b/reactos/include/crt/wchar.h index ee794487372..c2f30b5007a 100644 --- a/reactos/include/crt/wchar.h +++ b/reactos/include/crt/wchar.h @@ -220,8 +220,8 @@ extern "C" { _CRTIMP int __cdecl _iswcsym_l(wint_t _C,_locale_t _Locale); _CRTIMP int __cdecl is_wctype(wint_t _C,wctype_t _Type); #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES) -int __cdecl iswblank(wint_t _C); -#endif +_CRTIMP int __cdecl iswblank(wint_t _C); +#endif #endif #ifndef _WDIRECT_DEFINED @@ -714,16 +714,16 @@ int __cdecl iswblank(wint_t _C); _CRTIMP int __cdecl _wcsnicoll_l(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount,_locale_t _Locale); #ifndef NO_OLDNAMES - wchar_t *__cdecl wcsdup(const wchar_t *_Str); + _CRTIMP wchar_t *__cdecl wcsdup(const wchar_t *_Str); #define wcswcs wcsstr - int __cdecl wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2); - int __cdecl wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); - wchar_t *__cdecl wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount); - wchar_t *__cdecl wcsrev(wchar_t *_Str); - wchar_t *__cdecl wcsset(wchar_t *_Str,wchar_t _Val); - wchar_t *__cdecl wcslwr(wchar_t *_Str); - wchar_t *__cdecl wcsupr(wchar_t *_Str); - int __cdecl wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2); + _CRTIMP int __cdecl wcsicmp(const wchar_t *_Str1,const wchar_t *_Str2); + _CRTIMP int __cdecl wcsnicmp(const wchar_t *_Str1,const wchar_t *_Str2,size_t _MaxCount); + _CRTIMP wchar_t *__cdecl wcsnset(wchar_t *_Str,wchar_t _Val,size_t _MaxCount); + _CRTIMP wchar_t *__cdecl wcsrev(wchar_t *_Str); + _CRTIMP wchar_t *__cdecl wcsset(wchar_t *_Str,wchar_t _Val); + _CRTIMP wchar_t *__cdecl wcslwr(wchar_t *_Str); + _CRTIMP wchar_t *__cdecl wcsupr(wchar_t *_Str); + _CRTIMP int __cdecl wcsicoll(const wchar_t *_Str1,const wchar_t *_Str2); #endif #endif From 18d9f647bcea22dd6fb89886ef36ffb883175d04 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Wed, 11 Nov 2009 03:21:16 +0000 Subject: [PATCH 016/140] modified lib/3rdparty/mingw/mingw.rbuild oldnames is not an import library and dlltool --add-underscore is not an appropriate way to build it. Delete it for now modified base/applications/network/ftp/ftp.rbuild modified base/applications/winhlp32/winhlp32.rbuild modified base/services/dhcp/dhcp.rbuild modified dll/win32/crypt32/crypt32.rbuild modified dll/win32/mshtml/mshtml.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/wininet/wininet.rbuild modified lib/3rdparty/libxml2/libxml2.rbuild Workarounds for the removal of oldnames modified dll/directx/d3d8/d3d8.rbuild Use a file that actually exists modified dll/win32/crtdll/crtdll.rbuild modified dll/win32/msvcrt/msvcrt.rbuild "mangledsymbols" never did anything: remove it modified dll/win32/msvcrt/msvcrt.def modified lib/sdk/crt/crt.rbuild We don't actually implement j0/j1/jn/y0/y1/yn: _j0 calls __imp__j0, which is an alias for __imp___j0, which redirects back to _j0 in a perfect loop. Remove them for the time being modified lib/3rdparty/bzip2/bzip2.rbuild This was actually called unbzip2.dll. Who knew svn path=/trunk/; revision=44090 --- reactos/base/applications/network/ftp/ftp.rbuild | 12 ++++++++++++ reactos/base/applications/winhlp32/winhlp32.rbuild | 5 +++++ reactos/base/services/dhcp/dhcp.rbuild | 7 +++++++ reactos/dll/directx/d3d8/d3d8.rbuild | 2 +- reactos/dll/win32/crtdll/crtdll.rbuild | 2 +- reactos/dll/win32/crypt32/crypt32.rbuild | 6 ++++++ reactos/dll/win32/mshtml/mshtml.rbuild | 7 ++++++- reactos/dll/win32/msvcrt/msvcrt.def | 14 ++++++++------ reactos/dll/win32/msvcrt/msvcrt.rbuild | 2 +- reactos/dll/win32/setupapi/setupapi.rbuild | 4 ++++ reactos/dll/win32/wininet/wininet.rbuild | 4 ++++ reactos/lib/3rdparty/bzip2/bzip2.rbuild | 2 +- reactos/lib/3rdparty/libxml2/libxml2.rbuild | 8 ++++++++ reactos/lib/3rdparty/mingw/mingw.rbuild | 3 +-- reactos/lib/sdk/crt/crt.rbuild | 10 ++++++---- 15 files changed, 71 insertions(+), 17 deletions(-) diff --git a/reactos/base/applications/network/ftp/ftp.rbuild b/reactos/base/applications/network/ftp/ftp.rbuild index 854c41b1701..dd43d65f73b 100644 --- a/reactos/base/applications/network/ftp/ftp.rbuild +++ b/reactos/base/applications/network/ftp/ftp.rbuild @@ -3,6 +3,18 @@ . + + + _chdir + _getcwd + _mktemp + _unlink + _close + _fileno + _read + _write + _lseek + kernel32 ws2_32 iphlpapi diff --git a/reactos/base/applications/winhlp32/winhlp32.rbuild b/reactos/base/applications/winhlp32/winhlp32.rbuild index f58dcdb7c3a..3ce9b593d36 100644 --- a/reactos/base/applications/winhlp32/winhlp32.rbuild +++ b/reactos/base/applications/winhlp32/winhlp32.rbuild @@ -5,6 +5,11 @@ include/reactos/wine + + + _fileno + _isatty + wine user32 gdi32 diff --git a/reactos/base/services/dhcp/dhcp.rbuild b/reactos/base/services/dhcp/dhcp.rbuild index 0953ca88e5a..9b3467c06c9 100644 --- a/reactos/base/services/dhcp/dhcp.rbuild +++ b/reactos/base/services/dhcp/dhcp.rbuild @@ -3,6 +3,13 @@ . include + + + _tzset + _close + _read + _write + ntdll kernel32 ws2_32 diff --git a/reactos/dll/directx/d3d8/d3d8.rbuild b/reactos/dll/directx/d3d8/d3d8.rbuild index ee82042391c..3c14ab2b963 100644 --- a/reactos/dll/directx/d3d8/d3d8.rbuild +++ b/reactos/dll/directx/d3d8/d3d8.rbuild @@ -1,7 +1,7 @@ - + d3d8.c d3d8.rc d3d8.spec diff --git a/reactos/dll/win32/crtdll/crtdll.rbuild b/reactos/dll/win32/crtdll/crtdll.rbuild index 1695350d39a..310eaa5851b 100644 --- a/reactos/dll/win32/crtdll/crtdll.rbuild +++ b/reactos/dll/win32/crtdll/crtdll.rbuild @@ -1,4 +1,4 @@ - + . include diff --git a/reactos/dll/win32/crypt32/crypt32.rbuild b/reactos/dll/win32/crypt32/crypt32.rbuild index 6b91352df3d..a8e7c3effbd 100644 --- a/reactos/dll/win32/crypt32/crypt32.rbuild +++ b/reactos/dll/win32/crypt32/crypt32.rbuild @@ -4,6 +4,12 @@ include/reactos/wine 0x600 + + + _fdopen + _open + _close + wine user32 advapi32 diff --git a/reactos/dll/win32/mshtml/mshtml.rbuild b/reactos/dll/win32/mshtml/mshtml.rbuild index f97b9864820..240d54817b3 100644 --- a/reactos/dll/win32/mshtml/mshtml.rbuild +++ b/reactos/dll/win32/mshtml/mshtml.rbuild @@ -1,13 +1,18 @@ - + . include/reactos/wine 0x600 + + + _open + _close + conpoint.c dispex.c editor.c diff --git a/reactos/dll/win32/msvcrt/msvcrt.def b/reactos/dll/win32/msvcrt/msvcrt.def index 4a35b1bfd92..bcf3fe378c8 100644 --- a/reactos/dll/win32/msvcrt/msvcrt.def +++ b/reactos/dll/win32/msvcrt/msvcrt.def @@ -365,9 +365,10 @@ EXPORTS _isnan @359 _itoa @360 _itow @361 - _j0 @362 - _j1 @363 - _jn @364 +; FIXME: these aren't actually implemented in CRT +; _j0 @362 +; _j1 @363 +; _jn @364 _kbhit @365 _lfind @366 _loaddll @367 @@ -648,9 +649,10 @@ EXPORTS _wunlink @642 _wutime @643 ; _wutime64 @644 - _y0 @645 - _y1 @646 - _yn @647 +; FIXME: these aren't actually implemented in CRT +; _y0 @645 +; _y1 @646 +; _yn @647 abort @648 abs @649 acos @650 diff --git a/reactos/dll/win32/msvcrt/msvcrt.rbuild b/reactos/dll/win32/msvcrt/msvcrt.rbuild index 9c3f9ef08cf..6e6677f2492 100644 --- a/reactos/dll/win32/msvcrt/msvcrt.rbuild +++ b/reactos/dll/win32/msvcrt/msvcrt.rbuild @@ -1,4 +1,4 @@ - + . include diff --git a/reactos/dll/win32/setupapi/setupapi.rbuild b/reactos/dll/win32/setupapi/setupapi.rbuild index 170ec09bbf6..e2d901474c6 100644 --- a/reactos/dll/win32/setupapi/setupapi.rbuild +++ b/reactos/dll/win32/setupapi/setupapi.rbuild @@ -5,6 +5,10 @@ . include/reactos/wine . + + + _wcsnicmp + pnp_client uuid diff --git a/reactos/dll/win32/wininet/wininet.rbuild b/reactos/dll/win32/wininet/wininet.rbuild index 21a504564bc..1bb2b3bee40 100644 --- a/reactos/dll/win32/wininet/wininet.rbuild +++ b/reactos/dll/win32/wininet/wininet.rbuild @@ -8,6 +8,10 @@ include/reactos/wine + + + _close + wine mpr shlwapi diff --git a/reactos/lib/3rdparty/bzip2/bzip2.rbuild b/reactos/lib/3rdparty/bzip2/bzip2.rbuild index 3437902a950..f161228aa47 100644 --- a/reactos/lib/3rdparty/bzip2/bzip2.rbuild +++ b/reactos/lib/3rdparty/bzip2/bzip2.rbuild @@ -1,6 +1,6 @@ - + diff --git a/reactos/lib/3rdparty/libxml2/libxml2.rbuild b/reactos/lib/3rdparty/libxml2/libxml2.rbuild index b2631669abc..fab226e9bb4 100644 --- a/reactos/lib/3rdparty/libxml2/libxml2.rbuild +++ b/reactos/lib/3rdparty/libxml2/libxml2.rbuild @@ -11,6 +11,14 @@ include . + + + _getcwd + _close + _write + _read + _open + c14n.c catalog.c chvalid.c diff --git a/reactos/lib/3rdparty/mingw/mingw.rbuild b/reactos/lib/3rdparty/mingw/mingw.rbuild index c41e7a4b325..0e87ee7971b 100644 --- a/reactos/lib/3rdparty/mingw/mingw.rbuild +++ b/reactos/lib/3rdparty/mingw/mingw.rbuild @@ -1,9 +1,8 @@ - + - include/reactos/mingw-w64 kernel32 _newmode.c diff --git a/reactos/lib/sdk/crt/crt.rbuild b/reactos/lib/sdk/crt/crt.rbuild index 319b0ba66a5..73a88a029e4 100644 --- a/reactos/lib/sdk/crt/crt.rbuild +++ b/reactos/lib/sdk/crt/crt.rbuild @@ -155,9 +155,10 @@ fmod.c ldexp.c - j0_y0.c + + @@ -166,9 +167,10 @@ fmod.c ldexp.c - j0_y0.c + + stubs.c From 7f4bf6c49053e7d4d4bb512bec4c10b63e381a39 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Wed, 11 Nov 2009 03:41:14 +0000 Subject: [PATCH 017/140] modified Makefile Give poor pefixup its own echo line modified ReactOS-amd64.rbuild modified ReactOS-arm.rbuild modified ReactOS-i386.rbuild Set global linker flags globally Goodbye NTOSKRNL_SHARED modified tools/rbuild/backend/codeblocks/codeblocks.cpp modified tools/rbuild/backend/msvc/vcprojmaker.cpp Build fixes. I really want to delete these dead backends modified tools/rbuild/backend/mingw/linkers/ld.mak Makefile rule for the linker. Also generates the .lib and .exp for DLLs, and obsoletes a whole lot of shitty rbuild code modified tools/rbuild/backend/mingw/mingw.cpp modified tools/rbuild/backend/mingw/mingw.h Specify module type-specific linker flags... in the specification of flags for module types, instead of wherever Fix generation of project-global linker and NASM flags Give better names to the variables that contain names of BE-provided libraries Don't put quotes around the names of BE-provided libraries, GNU make doesn't support quoting in any way, shape or form and quotes around filenames actually break shit on Windows (see ). Just install the BE in a path without spaces in it Typo: LFLAGS is the flags for lex, flags for linker come from LDFLAGS modified tools/rbuild/backend/mingw/modulehandler.cpp modified tools/rbuild/backend/mingw/modulehandler.h modified tools/rbuild/module.cpp modified tools/rbuild/rbuild.h Moved generation of linker and import library generation rules out of rbuild and into sub-makefiles. A lot of code deleted, nothing of value was lost More LFLAGS -> LDFLAGS Goodbye mangledsymbols and underscoresymbols attributes, they don't do shit other than complicating my life If we have to add an underscore in front of the entry point name for some architectures, how about we do it in a single place? modified tools/rbuild/backend/mingw/rules.mak Minor cosmetic change svn path=/trunk/; revision=44091 --- reactos/Makefile | 1 + reactos/ReactOS-amd64.rbuild | 14 +- reactos/ReactOS-arm.rbuild | 15 +- reactos/ReactOS-i386.rbuild | 3 +- .../rbuild/backend/codeblocks/codeblocks.cpp | 4 +- .../tools/rbuild/backend/mingw/linkers/ld.mak | 96 +++- reactos/tools/rbuild/backend/mingw/mingw.cpp | 91 +-- reactos/tools/rbuild/backend/mingw/mingw.h | 2 +- .../rbuild/backend/mingw/modulehandler.cpp | 539 +++--------------- .../rbuild/backend/mingw/modulehandler.h | 8 +- reactos/tools/rbuild/backend/mingw/rules.mak | 2 +- .../tools/rbuild/backend/msvc/vcprojmaker.cpp | 12 +- reactos/tools/rbuild/module.cpp | 17 +- reactos/tools/rbuild/rbuild.h | 4 +- 14 files changed, 227 insertions(+), 581 deletions(-) diff --git a/reactos/Makefile b/reactos/Makefile index 52c59dd049c..e6a7d58b371 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -242,6 +242,7 @@ ifeq ($(HALFVERBOSEECHO),yes) ECHO_OBJDUMP =@echo $(QUOTE)[OBJDUMP] $@$(QUOTE) ECHO_RBUILD =@echo $(QUOTE)[RBUILD] $@$(QUOTE) ECHO_RSYM =@echo $(QUOTE)[RSYM] $@$(QUOTE) + ECHO_PEFIXUP =@echo $(QUOTE)[PEFIXUP] $@$(QUOTE) ECHO_WMC =@echo $(QUOTE)[WMC] $@$(QUOTE) ECHO_NCI =@echo $(QUOTE)[NCI] $@$(QUOTE) ECHO_CABMAN =@echo $(QUOTE)[CABMAN] $<$(QUOTE) diff --git a/reactos/ReactOS-amd64.rbuild b/reactos/ReactOS-amd64.rbuild index 149506bda87..f33c20f8be7 100644 --- a/reactos/ReactOS-amd64.rbuild +++ b/reactos/ReactOS-amd64.rbuild @@ -20,7 +20,6 @@ - -Os @@ -48,9 +47,14 @@ -Wno-multichar -Wno-format - -disable-stdcall-fixup - -static - --unique=.eh_frame + + + -disable-stdcall-fixup + -static + --unique=.eh_frame + -file-alignment=0x1000 + -section-alignment=0x1000 + @@ -191,7 +195,7 @@ - + diff --git a/reactos/ReactOS-arm.rbuild b/reactos/ReactOS-arm.rbuild index de897e8629c..aac72e02a0c 100644 --- a/reactos/ReactOS-arm.rbuild +++ b/reactos/ReactOS-arm.rbuild @@ -8,17 +8,16 @@ - + - + - - + - + include/reactos/arm @@ -32,12 +31,14 @@ -Wno-attributes - + - + --strip-debug -static + -file-alignment=0x1000 + -section-alignment=0x1000 diff --git a/reactos/ReactOS-i386.rbuild b/reactos/ReactOS-i386.rbuild index 6f295ee8dbf..b6fc035dd91 100644 --- a/reactos/ReactOS-i386.rbuild +++ b/reactos/ReactOS-i386.rbuild @@ -16,7 +16,6 @@ - @@ -30,6 +29,8 @@ -disable-stdcall-fixup + -file-alignment=0x1000 + -section-alignment=0x1000 diff --git a/reactos/tools/rbuild/backend/codeblocks/codeblocks.cpp b/reactos/tools/rbuild/backend/codeblocks/codeblocks.cpp index 74479a857d7..b1fb3f1c406 100644 --- a/reactos/tools/rbuild/backend/codeblocks/codeblocks.cpp +++ b/reactos/tools/rbuild/backend/codeblocks/codeblocks.cpp @@ -598,7 +598,7 @@ CBBackend::_generate_cbproj ( const Module& module ) if ( sys ) { - fprintf ( OUT, "\t\t\t\t\t\r\n", "_", module.GetEntryPoint(false) == "" ? "DriverEntry@8" : module.GetEntryPoint(false).c_str ()); + fprintf ( OUT, "\t\t\t\t\t\r\n", "_", module.GetEntryPoint() == "" ? "DriverEntry@8" : module.GetEntryPoint().c_str ()); fprintf ( OUT, "\t\t\t\t\t\r\n", baseaddr == "" ? "0x10000" : baseaddr.c_str () ); fprintf ( OUT, "\t\t\t\t\t\r\n" ); } @@ -623,7 +623,7 @@ CBBackend::_generate_cbproj ( const Module& module ) } else if ( dll ) { - fprintf ( OUT, "\t\t\t\t\t\r\n", "_", module.GetEntryPoint(false).c_str () ); + fprintf ( OUT, "\t\t\t\t\t\r\n", "_", module.GetEntryPoint().c_str () ); fprintf ( OUT, "\t\t\t\t\t\r\n", baseaddr == "" ? "0x40000" : baseaddr.c_str () ); if ( module.type == Win32DLL) diff --git a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak index a8de2ed235b..812f30ec874 100644 --- a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak +++ b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak @@ -1,32 +1,70 @@ -#~ #(module, objs, deps, ldflags, output, libs, subsys, entry, base, falign, salign) -#~ define RBUILD_LINK +LDFLAG_DLL:=-shared +LDFLAG_DRIVER:=-shared --subsystem=native +LDFLAG_NOSTDLIB:=-nostartfiles -nostdlib +LDFLAG_CONSOLE:=--subsystem=console +LDFLAG_WINDOWS:=--subsystem=windows +LDFLAG_NATIVE:=--subsystem=native -#~ $(5) ${call RBUILD_output_dir,$(5)}$$(SEP)$(basename $(notdir $(5))).map: $(2) $(3) $(6) | ${call RBUILD_dir,$(5)} - #~ $$(ECHO_CC) - #~ $${ld} -subsystem=$(7) -entry=$(8) -base=$(9) -file-alignment=$(10) -section-alignment=$(11) $(2) $(6) ${call RBUILD_ldflags,$(1),$(4)} -o $(5) -#~ ifeq ($(ROS_BUILDMAP),full) - #~ $$(ECHO_OBJDUMP) - #~ $${objdump} -d -S $$@ > ${call RBUILD_output_dir,$(5)}$$(SEP)$(basename $(notdir $(5))).map -#~ else -#~ ifeq ($(ROS_BUILDMAP),yes) - #~ $$(ECHO_NM) - #~ $${nm} --numeric-sort $$@ > ${call RBUILD_output_dir,$(5)}$$(SEP)$(basename $(notdir $(5))).map -#~ endif -#~ endif -#~ ifeq ($(ROS_BUILDNOSTRIP),yes) - #~ $$(ECHO_CP) - #~ $${cp} $(5) $(basename $(5)).nostrip$(suffix $(5)) 1>$(NUL) -#~ endif -#~ ifneq ($(ROS_GENERATE_RSYM),no) - #~ $$(ECHO_RSYM) - #~ $$(Q)$$(rsym_TARGET) $$@ $$@ -#~ endif -#~ ifeq ($(ROS_LEAN_AND_MEAN),yes) - #~ $$(ECHO_STRIP) - #~ $${strip} -s -x -X $$@ -#~ endif +#(module, objs, deps, ldflags, output, def, libs, entry, base) +define RBUILD_LINK -#~ endef +ifneq ($(6),) +${call RBUILD_intermediate_dir,$(5)}$$(SEP)lib${call RBUILD_name,$(5)}.a: $(6) | ${call RBUILD_intermediate_path,$(5)} + $$(ECHO DLLTOOL) + $${dlltool} --def $(6) --kill-at --output-lib=$$@ -#~ #(module, dependencies, ldflags, subsys, entry, base, falign, salign) -#~ RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(1)_OBJS,$(2),$(3),$(1)_TARGET,$(1)_LIBS,$(4),$(5),$(6),$(7),$(8)} +${call RBUILD_intermediate_dir,$(5)}$$(SEP)lib${call RBUILD_name,$(5)}.delayimp.a: $(6) | ${call RBUILD_intermediate_path,$(5)} + $$(ECHO DLLTOOL) + $${dlltool} --def $(6) --kill-at --output-delaylib=$$@ + +${call RBUILD_intermediate_path_noext,$(5)}.exp: $(6) | ${call RBUILD_intermediate_path,$(5)} + $$(ECHO DLLTOOL) + $${dlltool} --def $(6) --kill-at --output-exp=$$@ + +$(1)_CLEANFILES+=\ + ${call RBUILD_intermediate_dir,$(5)}$$(SEP)lib$(notdir $(5)).a \ + ${call RBUILD_intermediate_dir,$(5)}$$(SEP)lib$(notdir $(5)).delayimp.a \ + ${call RBUILD_intermediate_path_noext,$(5)}.exp +endif + +$(5): $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(7) $(3) $$(RSYM_TARGET) $$(PEFIXUP_TARGET) | ${call RBUILD_dir,$(5)} + $$(ECHO_LD) + $${ld} --entry=$(8) --image-base=$(9) $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(7) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ +ifneq ($(or $(6),$$(MODULETYPE$$($(1)_TYPE)_KMODE)),) + $$(ECHO_PEFIXUP) + $$(Q)$$(PEFIXUP_TARGET) $$@ $(if $(6),-exports) $$(if $$(MODULETYPE$($(1)_TYPE)_KMODE),-sections) +endif +ifeq ($(ROS_BUILDMAP),full) + $$(ECHO_OBJDUMP) + $${objdump} -d -S $$@ > ${call RBUILD_output_path_noext,$(5)}.map +else +ifeq ($(ROS_BUILDMAP),yes) + $$(ECHO_NM) + $${nm} --numeric-sort $$@ > ${call RBUILD_output_path_noext,$(5)}.map +endif +endif +ifeq ($(ROS_BUILDNOSTRIP),yes) + $$(ECHO_CP) + $${cp} $(5) $(basename $(5)).nostrip$(suffix $(5)) 1>$(NUL) +endif +ifneq ($(ROS_GENERATE_RSYM),no) + $$(ECHO_RSYM) + $$(Q)$$(RSYM_TARGET) $$@ $$@ +endif +ifeq ($(ROS_LEAN_AND_MEAN),yes) + $$(ECHO_STRIP) + $${strip} -s -x -X $$@ +endif + +ifneq ($(ROS_BUILDMAP),) +$(1)_CLEANFILES+=${call RBUILD_output_path_noext,$(5)}.map +endif + +ifeq ($(ROS_BUILDNOSTRIP),yes) +$(1)_CLEANFILES+=$(basename $(5)).nostrip$(suffix $(5)) +endif + +endef + +#(module, def, deps, ldflags, libs, entry, base) +RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(5) $(value $(1)_LIBS) $(5),$(6),$(7)} diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index 77893a1006d..472e5960dac 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -38,16 +38,16 @@ const struct ModuleHandlerInformations ModuleHandlerInformations[] = { { HostTrue, "", "", "" }, // BuildTool { HostFalse, "", "", "" }, // StaticLibrary { HostFalse, "", "", "" }, // ObjectLibrary - { HostFalse, "", "", "" }, // Kernel - { HostFalse, "", "", "" }, // KernelModeDLL - { HostFalse, "-D__NTDRIVER__", "", "" }, // KernelModeDriver - { HostFalse, "", "", "" }, // NativeDLL - { HostFalse, "-D__NTAPP__", "", "" }, // NativeCUI - { HostFalse, "", "", "" }, // Win32DLL - { HostFalse, "", "", "" }, // Win32OCX - { HostFalse, "", "", "" }, // Win32CUI - { HostFalse, "", "", "" }, // Win32GUI - { HostFalse, "", "", "-nostartfiles -nostdlib" }, // BootLoader + { HostFalse, "", "", "$(LDFLAG_DRIVER)" }, // Kernel + { HostFalse, "", "", "$(LDFLAG_DRIVER)" }, // KernelModeDLL + { HostFalse, "-D__NTDRIVER__", "", "$(LDFLAG_DRIVER)" }, // KernelModeDriver + { HostFalse, "", "", "$(LDFLAG_DLL)" }, // NativeDLL + { HostFalse, "-D__NTAPP__", "", "$(LDFLAG_NATIVE)" }, // NativeCUI + { HostFalse, "", "", "$(LDFLAG_DLL)" }, // Win32DLL + { HostFalse, "", "", "$(LDFLAG_DLL)" }, // Win32OCX + { HostFalse, "", "", "$(LDFLAG_CONSOLE)" }, // Win32CUI + { HostFalse, "", "", "$(LDFLAG_WINDOWS)" }, // Win32GUI + { HostFalse, "", "", "" }, // BootLoader { HostFalse, "", "-f bin", "" }, // BootSector { HostFalse, "", "", "" }, // Iso { HostFalse, "", "", "" }, // LiveIso @@ -55,8 +55,8 @@ const struct ModuleHandlerInformations ModuleHandlerInformations[] = { { HostFalse, "", "", "" }, // RpcServer { HostFalse, "", "", "" }, // RpcClient { HostFalse, "", "", "" }, // Alias - { HostFalse, "", "", "-nostartfiles -nostdlib" }, // BootProgram - { HostFalse, "", "", "" }, // Win32SCR + { HostFalse, "", "", "" }, // BootProgram + { HostFalse, "", "", "$(LDFLAG_WINDOWS)" }, // Win32SCR { HostFalse, "", "", "" }, // IdlHeader { HostFalse, "", "", "" }, // IdlInterface { HostFalse, "", "", "" }, // EmbeddedTypeLib @@ -64,7 +64,7 @@ const struct ModuleHandlerInformations ModuleHandlerInformations[] = { { HostFalse, "", "", "" }, // RpcProxy { HostTrue, "", "", "" }, // HostStaticLibrary { HostFalse, "", "", "" }, // Cabinet - { HostFalse, "", "", "" }, // KeyboardLayout + { HostFalse, "", "", "$(LDFLAG_DLL)" }, // KeyboardLayout { HostFalse, "", "", "" }, // MessageHeader }; @@ -413,17 +413,17 @@ MingwBackend::GenerateGlobalProperties ( } string -MingwBackend::GenerateProjectLFLAGS () const +MingwBackend::GenerateProjectLDFLAGS () const { - string lflags; + string ldflags; for ( size_t i = 0; i < ProjectNode.linkerFlags.size (); i++ ) { LinkerFlag& linkerFlag = *ProjectNode.linkerFlags[i]; - if ( lflags.length () > 0 ) - lflags += " "; - lflags += linkerFlag.flag; + if ( ldflags.length () > 0 ) + ldflags += " "; + ldflags += linkerFlag.flag; } - return lflags; + return ldflags; } void @@ -478,24 +478,21 @@ MingwBackend::GenerateGlobalVariables () const // Would be nice to have our own C++ runtime fputs ( "BUILTIN_CXXINCLUDES+= $(TARGET_CPPFLAGS)\n", fMakefile ); - } - // Because RosBE gcc is built to suck - fputs ( "BUILTIN_HOST_CINCLUDES+= $(HOST_CFLAGS)\n", fMakefile ); - fputs ( "BUILTIN_HOST_CPPINCLUDES+= $(HOST_CFLAGS)\n", fMakefile ); - fputs ( "BUILTIN_HOST_CXXINCLUDES+= $(HOST_CPPFLAGS)\n", fMakefile ); + fprintf ( fMakefile, "PROJECT_CCLIBS := $(shell ${TARGET_CC} -print-libgcc-file-name)\n" ); + fprintf ( fMakefile, "PROJECT_CXXLIBS := $(shell ${TARGET_CPP} -print-file-name=libstdc++.a) $(shell ${TARGET_CPP} -print-file-name=libgcc.a) $(shell ${TARGET_CPP} -print-file-name=libmingw32.a) $(shell ${TARGET_CPP} -print-file-name=libmingwex.a) $(shell ${TARGET_CPP} -print-file-name=libcoldname.a)\n" ); + + /* hack to get libgcc_eh.a, should check mingw version or something */ + if (Environment::GetArch() == "amd64") + { + fprintf ( fMakefile, "PROJECT_LPPFLAGS += $(shell ${TARGET_CPP} -print-file-name=libgcc_eh.a)\n" ); + } + } MingwModuleHandler::GenerateParameters ( "PROJECT", "+=", ProjectNode.non_if_data ); MingwModuleHandler::GenerateParameters ( "PROJECT_HOST", "+=", ProjectNode.host_non_if_data ); - // TODO: linker flags - fprintf ( fMakefile, "PROJECT_LFLAGS := '$(shell ${TARGET_CC} -print-libgcc-file-name)' %s\n", GenerateProjectLFLAGS ().c_str () ); - fprintf ( fMakefile, "PROJECT_LPPFLAGS := '$(shell ${TARGET_CPP} -print-file-name=libstdc++.a)' '$(shell ${TARGET_CPP} -print-file-name=libgcc.a)' '$(shell ${TARGET_CPP} -print-file-name=libmingw32.a)' '$(shell ${TARGET_CPP} -print-file-name=libmingwex.a)' '$(shell ${TARGET_CPP} -print-file-name=libcoldname.a)'\n" ); - /* hack to get libgcc_eh.a, should check mingw version or something */ - if (Environment::GetArch() == "amd64") - { - fprintf ( fMakefile, "PROJECT_LPPFLAGS += '$(shell ${TARGET_CPP} -print-file-name=libgcc_eh.a)'\n" ); - } + fprintf ( fMakefile, "PROJECT_LDFLAGS := %s\n", GenerateProjectLDFLAGS ().c_str () ); // TODO: use symbolic names for module types for ( size_t i = 0; i < sizeof(ModuleHandlerInformations) / sizeof(ModuleHandlerInformations[0]); ++ i ) @@ -509,15 +506,6 @@ MingwBackend::GenerateGlobalVariables () const ModuleHandlerInformations[i].cflags ); } - if ( ModuleHandlerInformations[i].cflags && ModuleHandlerInformations[i].cflags[0] ) - { - fprintf ( fMakefile, - "MODULETYPE%d_%sFLAGS:=%s\n", - (int)i, - "CXX", - ModuleHandlerInformations[i].cflags ); - } - if ( ModuleHandlerInformations[i].nasmflags && ModuleHandlerInformations[i].nasmflags[0] ) { fprintf ( fMakefile, @@ -526,8 +514,29 @@ MingwBackend::GenerateGlobalVariables () const "NASM", ModuleHandlerInformations[i].nasmflags ); } + + if ( ModuleHandlerInformations[i].linkerflags && ModuleHandlerInformations[i].linkerflags[0] ) + { + fprintf ( fMakefile, + "MODULETYPE%d_%sFLAGS:=%s\n", + (int)i, + "LD", + ModuleHandlerInformations[i].linkerflags ); + } } + fprintf ( fMakefile, + "MODULETYPE%d_KMODE:=yes\n", + (int)Kernel ); + + fprintf ( fMakefile, + "MODULETYPE%d_KMODE:=yes\n", + (int)KernelModeDLL ); + + fprintf ( fMakefile, + "MODULETYPE%d_KMODE:=yes\n", + (int)KernelModeDriver ); + fprintf ( fMakefile, "\n" ); } diff --git a/reactos/tools/rbuild/backend/mingw/mingw.h b/reactos/tools/rbuild/backend/mingw/mingw.h index d7bd6fcac78..c4331b9c152 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.h +++ b/reactos/tools/rbuild/backend/mingw/mingw.h @@ -66,7 +66,7 @@ private: void GenerateHeader () const; void GenerateGlobalProperties ( const char* assignmentOperation, const IfableData& data ) const; - std::string GenerateProjectLFLAGS () const; + std::string GenerateProjectLDFLAGS () const; void GenerateDirectories (); void GenerateGlobalVariables () const; bool IncludeInAllTarget ( const Module& module ) const; diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp index 6960c0ae769..1609d63ec9c 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp @@ -290,9 +290,7 @@ MingwModuleHandler::GetModuleArchiveFilename () const { if ( IsStaticLibrary ( module ) ) return GetTargetFilename ( module, NULL ); - return new FileLocation ( IntermediateDirectory, - module.output->relative_path, - ReplaceExtension ( module.name, ".temp.a" ) ); + return NULL; } /*static*/ bool @@ -1359,25 +1357,6 @@ MingwModuleHandler::GenerateBuildMapCode ( const FileLocation *mapTarget ) "endif\n" ); } -void -MingwModuleHandler::GenerateBuildNonSymbolStrippedCode () -{ - fprintf ( fMakefile, "# BUILD NO STRIP CODE\n" ); - - fprintf ( fMakefile, - "ifeq ($(ROS_BUILDNOSTRIP),yes)\n" ); - - FileLocation nostripFilename ( OutputDirectory, - module.output->relative_path, - GetBasename ( module.output->name ) + ".nostrip" + GetExtension ( *module.output ) ); - CLEAN_FILE ( nostripFilename ); - - OutputCopyCommand ( *module.output, nostripFilename ); - - fprintf ( fMakefile, - "endif\n" ); -} - void MergeStringVector ( const Backend* backend, const vector& input, @@ -1438,158 +1417,61 @@ MingwModuleHandler::GenerateCleanObjectsAsYouGoCode () const } void -MingwModuleHandler::GenerateRunRsymCode () const +MingwModuleHandler::GenerateLinkerCommand () const { - fprintf ( fMakefile, "# RUN RSYM CODE\n" ); - fprintf ( fMakefile, - "ifneq ($(ROS_GENERATE_RSYM),no)\n" ); - fprintf ( fMakefile, - "\t$(ECHO_RSYM)\n" ); - fprintf ( fMakefile, - "\t$(Q)$(RSYM_TARGET) $@ $@\n\n" ); - fprintf ( fMakefile, - "endif\n" ); -} + string definitionFilename; + + const FileLocation *DefinitionFilename = GetDefinitionFilename (); -void -MingwModuleHandler::GenerateRunStripCode () const -{ - fprintf ( fMakefile, "# RUN STRIP CODE\n" ); - fprintf ( fMakefile, - "ifeq ($(ROS_LEAN_AND_MEAN),yes)\n" ); - fprintf ( fMakefile, - "\t$(ECHO_STRIP)\n" ); - fprintf ( fMakefile, - "\t${strip} -s -x -X $@\n\n" ); - fprintf ( fMakefile, - "endif\n" ); -} - -void -MingwModuleHandler::GenerateLinkerCommand ( - const string& dependencies, - const string& linkerParameters, - const string& pefixupParameters ) -{ - const FileLocation *target_file = GetTargetFilename ( module, NULL ); - const FileLocation *definitionFilename = GetDefinitionFilename (); - string linker = "${ld}"; - string objectsMacro = GetObjectsMacro ( module ); - string libsMacro = GetLibsMacro (); - - fprintf ( fMakefile, "# LINKER COMMAND\n" ); - - string target_macro ( GetTargetMacro ( module ) ); - string target_folder ( backend->GetFullPath ( *target_file ) ); + if ( DefinitionFilename ) { + definitionFilename = backend->GetFullName (*DefinitionFilename); + delete DefinitionFilename; + } string linkerScriptArgument; - if ( module.linkerScript != NULL ) + if ( module.linkerScript != NULL ) { + if ( module.project.configuration.Linker == GnuLd ) linkerScriptArgument = ssprintf ( " -T %s", backend->GetFullName ( *module.linkerScript->file ).c_str () ); else - linkerScriptArgument = ""; - - /* check if we need to add default C++ libraries, ie if we have - * a C++ user-mode module without the -nostdlib linker flag - */ - bool link_defaultlibs = module.cplusplus && - linkerParameters.find ("-nostdlib") == string::npos && - !(module.type == KernelModeDLL || module.type == KernelModeDriver); - - if ( !module.HasImportLibrary() ) - { - fprintf ( fMakefile, - "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n", - target_macro.c_str (), - definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "", - dependencies.c_str (), - target_folder.c_str () ); - fprintf ( fMakefile, "\t$(ECHO_LD)\n" ); - - fprintf ( fMakefile, - "\t%s %s%s %s %s %s %s -o %s\n", - linker.c_str (), - linkerParameters.c_str (), - linkerScriptArgument.c_str (), - objectsMacro.c_str (), - link_defaultlibs ? "$(PROJECT_LPPFLAGS) " : "", - libsMacro.c_str (), - GetLinkerMacro ().c_str (), - target_macro.c_str () ); - } - else - { - FileLocation temp_exp ( IntermediateDirectory, - module.output->relative_path, - module.name + ".exp" ); - CLEAN_FILE ( temp_exp ); - - fprintf ( fMakefile, - "%s: %s | %s\n", - backend->GetFullName ( temp_exp ).c_str (), - definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "", - backend->GetFullPath ( temp_exp ).c_str () ); - fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" ); - - fprintf ( fMakefile, - "\t${dlltool} --dllname %s --def %s --output-exp $@%s%s\n", - module.GetDllName ().c_str (), - definitionFilename ? backend->GetFullName ( *definitionFilename ).c_str () : "", - module.mangledSymbols ? "" : " --kill-at", - module.underscoreSymbols ? " --add-underscore" : "" ); - - fprintf ( fMakefile, - "%s: %s %s $(RSYM_TARGET) $(PEFIXUP_TARGET) | %s\n", - target_macro.c_str (), - backend->GetFullName ( temp_exp ).c_str (), - dependencies.c_str (), - target_folder.c_str () ); - fprintf ( fMakefile, "\t$(ECHO_LD)\n" ); - - fprintf ( fMakefile, - "\t%s %s%s %s %s %s %s %s -o %s\n", - - linker.c_str (), - linkerParameters.c_str (), - linkerScriptArgument.c_str (), - backend->GetFullName ( temp_exp ).c_str (), - objectsMacro.c_str (), - link_defaultlibs ? "$(PROJECT_LPPFLAGS) " : "", - libsMacro.c_str (), - GetLinkerMacro ().c_str (), - target_macro.c_str () ); - - fprintf ( fMakefile, - "\t$(Q)$(PEFIXUP_TARGET) %s -exports%s\n", - target_macro.c_str (), - pefixupParameters.c_str() ); + fprintf ( stderr, + "Linker doesn't support linker scripts: linker script %s ignored for module %s\n", + backend->GetFullName ( *module.linkerScript->file ).c_str (), + module.name.c_str() ); } - GenerateBuildMapCode (); - GenerateBuildNonSymbolStrippedCode (); - GenerateRunRsymCode (); - GenerateRunStripCode (); - GenerateCleanObjectsAsYouGoCode (); + string extraLibraries; + if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse ) { + if ( module.cplusplus ) { + switch ( module.type ) + { + case Win32DLL: + case Win32OCX: + case Win32CUI: + case Win32GUI: + case Win32SCR: + extraLibraries = "$$(PROJECT_CXXLIBS)"; + break; - if ( definitionFilename ) - delete definitionFilename; - delete target_file; -} + default: + extraLibraries = "$$(PROJECT_CCLIBS)"; + break; + } + } else + extraLibraries = "$$(PROJECT_CCLIBS)"; + } -void -MingwModuleHandler::GeneratePhonyTarget() const -{ - string targetMacro ( GetTargetMacro ( module ) ); - const FileLocation *target_file = GetTargetFilename ( module, NULL ); + delete PassThruCacheDirectory ( new FileLocation ( module.output->directory, module.output->relative_path, "" ) ); + delete PassThruCacheDirectory ( new FileLocation ( IntermediateDirectory, module.output->relative_path, "" ) ); - fprintf ( fMakefile, "# PHONY TARGET\n" ); fprintf ( fMakefile, - ".PHONY: %s\n\n", - targetMacro.c_str ()); - fprintf ( fMakefile, "%s: | %s\n", - targetMacro.c_str (), - backend->GetFullPath ( *target_file ).c_str () ); - - delete target_file; + "$(eval $(call RBUILD_LINK_RULE,%s,%s,%s,%s,%s,%s,%s))\n", + module.name.c_str(), + definitionFilename.c_str(), + module.xmlbuildFile.c_str(), + linkerScriptArgument.c_str(), + extraLibraries.c_str(), + module.GetEntryPoint().c_str(), + module.baseaddress.c_str() ); } void @@ -1598,8 +1480,6 @@ MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data ) size_t i; string moduleDependencies; - fprintf ( fMakefile, "# OBJECT FILE TARGETS\n" ); - const vector& compilationUnits = data.compilationUnits; for ( i = 0; i < compilationUnits.size (); i++ ) { @@ -1642,8 +1522,6 @@ MingwModuleHandler::GenerateObjectFileTargets ( const IfableData& data ) void MingwModuleHandler::GenerateObjectFileTargets () { - fprintf ( fMakefile, "# OBJECT FILE TARGETS\n" ); - if ( module.pch && use_pch ) { @@ -1660,12 +1538,9 @@ MingwModuleHandler::GenerateObjectFileTargets () pchCxxRule.Execute ( fMakefile, backend, module, module.pch->file, clean_files, dependencies ); else pchRule.Execute ( fMakefile, backend, module, module.pch->file, clean_files, dependencies ); - - fprintf ( fMakefile, "\n" ); } GenerateObjectFileTargets ( module.non_if_data ); - fprintf ( fMakefile, "\n" ); } /* caller needs to delete the returned object */ @@ -1673,6 +1548,10 @@ const FileLocation* MingwModuleHandler::GenerateArchiveTarget () { const FileLocation *archiveFilename = GetModuleArchiveFilename (); + + if ( archiveFilename == NULL ) + return NULL; + const FileLocation *definitionFilename = GetDefinitionFilename (); fprintf ( fMakefile, "# ARCHIVE TARGET\n" ); @@ -1687,11 +1566,8 @@ MingwModuleHandler::GenerateArchiveTarget () backend->GetFullName ( *definitionFilename ).c_str () ); fprintf ( fMakefile, - "\t${dlltool} --dllname %s --def %s --output-lib $@%s%s\n", - module.GetDllName ().c_str (), - backend->GetFullName ( *definitionFilename ).c_str (), - module.mangledSymbols ? "" : " --kill-at", - module.underscoreSymbols ? " --add-underscore" : "" ); + "\t${dlltool} --def %s --kill-at --output-lib $@\n", + backend->GetFullName ( *definitionFilename ).c_str () ); } else arRule1.Execute ( fMakefile, backend, module, archiveFilename, clean_files ); @@ -1727,7 +1603,7 @@ MingwModuleHandler::GetLibsMacro () const string MingwModuleHandler::GetLinkerMacro () const { - return ssprintf ( "$(%s_LFLAGS)", + return ssprintf ( "$(%s_LDFLAGS)", module.name.c_str () ); } @@ -1842,7 +1718,7 @@ MingwModuleHandler::GenerateOtherMacros () { set used_defs; - linkerflagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ()); + linkerflagsMacro = ssprintf ("%s_LDFLAGS", module.name.c_str ()); libsMacro = ssprintf("%s_LIBS", module.name.c_str ()); const FileLocation * pchPath = GetPrecompiledHeaderPath (); @@ -1897,28 +1773,6 @@ MingwModuleHandler::GenerateOtherMacros () GenerateParameters ( module.name.c_str(), "+=", module.non_if_data ); - const char *linkerflags = ModuleHandlerInformations[module.type].linkerflags; - if ( strlen( linkerflags ) > 0 ) - { - fprintf ( fMakefile, - "%s += %s\n\n", - linkerflagsMacro.c_str (), - linkerflags ); - } - - // FIXME: make rules for linker, move standard flags there - if ( ModuleHandlerInformations[module.type].DefaultHost == HostFalse ) - { - if ( module.cplusplus ) - fprintf ( fMakefile, - "%s+= $(PROJECT_LPPFLAGS)\n\n", - linkerflagsMacro.c_str () ); - else - fprintf ( fMakefile, - "%s+= $(PROJECT_LFLAGS)\n\n", - linkerflagsMacro.c_str () ); - } - GenerateMacros ( "+=", module.non_if_data, @@ -1957,7 +1811,9 @@ MingwModuleHandler::GenerateRules () if ( !ReferenceObjects ( module ) ) { const FileLocation* ar_target = GenerateArchiveTarget (); - delete ar_target; + + if ( ar_target ) + delete ar_target; } @@ -2158,61 +2014,6 @@ MingwModuleHandler::GetDefinitionFilename () const } } -void -MingwModuleHandler::GenerateImportLibraryTarget ( - const FileLocation *defFilename, - const FileLocation *library_target, - bool delayimp) -{ - string empty = "tools" + sSep + "rbuild" + sSep + "empty.def"; - - fprintf ( fMakefile, "# IMPORT LIBRARY RULE\n" ); - - fprintf ( fMakefile, "%s:", - backend->GetFullName ( *library_target ).c_str () ); - - if ( defFilename ) - { - fprintf ( fMakefile, " %s", - backend->GetFullName ( *defFilename ).c_str () ); - } - - fprintf ( fMakefile, " | %s\n", - backend->GetFullPath ( *library_target ).c_str () ); - - fprintf ( fMakefile, "\t$(ECHO_DLLTOOL)\n" ); - - fprintf ( fMakefile, - "\t${dlltool} --dllname %s --def %s %s %s%s%s\n\n", - module.GetDllName ().c_str (), - defFilename ? backend->GetFullName ( *defFilename ).c_str () - : empty.c_str (), - delayimp ? "--output-delaylib" : "--output-lib", - backend->GetFullName ( *library_target ).c_str (), - module.mangledSymbols ? "" : " --kill-at", - module.underscoreSymbols ? " --add-underscore" : "" ); -} - -void -MingwModuleHandler::GenerateImportLibraryTargetIfNeeded () -{ - if ( module.importLibrary != NULL ) - { - const FileLocation *library_target = GetImportLibraryFilename ( module, &clean_files, false ); - const FileLocation *delayimp_target = GetImportLibraryFilename ( module, &clean_files, true ); - const FileLocation *defFilename = GetDefinitionFilename (); - - GenerateImportLibraryTarget(defFilename, library_target, false); - GenerateImportLibraryTarget(defFilename, delayimp_target, true); - - if ( defFilename ) - delete defFilename; - delete library_target; - delete delayimp_target; - - } -} - void MingwModuleHandler::GetSpecObjectDependencies ( vector& dependencies, @@ -2402,30 +2203,8 @@ MingwKernelModuleHandler::Process () void MingwKernelModuleHandler::GenerateKernelModuleTarget () { - string targetMacro ( GetTargetMacro ( module ) ); - string workingDirectory = GetWorkingDirectory ( ); - string libsMacro = GetLibsMacro (); - - GenerateImportLibraryTargetIfNeeded (); - - if ( module.non_if_data.compilationUnits.size () > 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - - GenerateLinkerCommand ( dependencies, - linkerParameters + " $(NTOSKRNL_SHARED)", - " -sections" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } @@ -2453,29 +2232,8 @@ MingwKernelModeDLLModuleHandler::Process () void MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget () { - string targetMacro ( GetTargetMacro ( module ) ); - string workingDirectory = GetWorkingDirectory (); - string libsMacro = GetLibsMacro (); - - GenerateImportLibraryTargetIfNeeded (); - - if ( module.non_if_data.compilationUnits.size () > 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - GenerateLinkerCommand ( dependencies, - linkerParameters, - " -sections" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } @@ -2502,29 +2260,8 @@ MingwNativeDLLModuleHandler::Process () void MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget () { - string targetMacro ( GetTargetMacro (module) ); - string workingDirectory = GetWorkingDirectory ( ); - string libsMacro = GetLibsMacro (); - - GenerateImportLibraryTargetIfNeeded (); - - if ( module.non_if_data.compilationUnits.size () > 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - GenerateLinkerCommand ( dependencies, - linkerParameters, - "" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } @@ -2551,29 +2288,8 @@ MingwNativeCUIModuleHandler::Process () void MingwNativeCUIModuleHandler::GenerateNativeCUIModuleTarget () { - string targetMacro ( GetTargetMacro (module) ); - string workingDirectory = GetWorkingDirectory ( ); - string libsMacro = GetLibsMacro (); - - GenerateImportLibraryTargetIfNeeded (); - - if ( module.non_if_data.compilationUnits.size () > 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=native -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - GenerateLinkerCommand ( dependencies, - linkerParameters, - "" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } @@ -2641,29 +2357,8 @@ MingwWin32DLLModuleHandler::Process () void MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget () { - string targetMacro ( GetTargetMacro (module) ); - string workingDirectory = GetWorkingDirectory ( ); - string libsMacro = GetLibsMacro (); - - GenerateImportLibraryTargetIfNeeded (); - - if ( module.non_if_data.compilationUnits.size () > 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - GenerateLinkerCommand ( dependencies, - linkerParameters, - "" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } @@ -2682,29 +2377,8 @@ MingwWin32OCXModuleHandler::Process () void MingwWin32OCXModuleHandler::GenerateWin32OCXModuleTarget () { - string targetMacro ( GetTargetMacro (module) ); - string workingDirectory = GetWorkingDirectory ( ); - string libsMacro = GetLibsMacro (); - - GenerateImportLibraryTargetIfNeeded (); - - if ( module.non_if_data.compilationUnits.size () > 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000 -shared", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - GenerateLinkerCommand ( dependencies, - linkerParameters, - "" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } @@ -2730,29 +2404,8 @@ MingwWin32CUIModuleHandler::Process () void MingwWin32CUIModuleHandler::GenerateWin32CUIModuleTarget () { - string targetMacro ( GetTargetMacro (module) ); - string workingDirectory = GetWorkingDirectory ( ); - string libsMacro = GetLibsMacro (); - - GenerateImportLibraryTargetIfNeeded (); - - if ( module.non_if_data.compilationUnits.size () > 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - GenerateLinkerCommand ( dependencies, - linkerParameters, - "" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } @@ -2778,29 +2431,8 @@ MingwWin32GUIModuleHandler::Process () void MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget () { - string targetMacro ( GetTargetMacro (module) ); - string workingDirectory = GetWorkingDirectory ( ); - string libsMacro = GetLibsMacro (); - - GenerateImportLibraryTargetIfNeeded (); - - if ( module.non_if_data.compilationUnits.size () > 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=windows -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - GenerateLinkerCommand ( dependencies, - linkerParameters, - "" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } @@ -2845,7 +2477,7 @@ MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget () if (Environment::GetArch() == "arm") { fprintf ( fMakefile, - "\t${gcc} -Wl,--subsystem,native -o %s %s %s %s\n", + "\t${gcc} -Wl,--subsystem,native -o %s %s %s %s -nostartfiles -nostdlib\n", backend->GetFullName ( junk_tmp ).c_str (), objectsMacro.c_str (), libsMacro.c_str (), @@ -2854,7 +2486,7 @@ MingwBootLoaderModuleHandler::GenerateBootLoaderModuleTarget () else { fprintf ( fMakefile, - "\t${gcc} -Wl,--subsystem,native -Wl,-Ttext,0x8000 -o %s %s %s %s\n", + "\t${gcc} -Wl,--subsystem,native -Wl,-Ttext,0x8000 -o %s %s %s %s -nostartfiles -nostdlib\n", backend->GetFullName ( junk_tmp ).c_str (), objectsMacro.c_str (), libsMacro.c_str (), @@ -3400,29 +3032,8 @@ MingwTestModuleHandler::GetModuleSpecificCompilationUnits ( vector 0 ) - { - GenerateRules (); - - string dependencies = libsMacro + " " + objectsMacro; - - string linkerParameters = ssprintf ( "-subsystem=console -entry=%s -image-base=%s -file-alignment=0x1000 -section-alignment=0x1000", - module.GetEntryPoint(!(Environment::GetArch() == "arm")).c_str (), - module.baseaddress.c_str () ); - GenerateLinkerCommand ( dependencies, - linkerParameters, - "" ); - } - else - { - GeneratePhonyTarget(); - } + GenerateRules (); + GenerateLinkerCommand (); } diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.h b/reactos/tools/rbuild/backend/mingw/modulehandler.h index 57aaad29570..b0687177d9a 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.h +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.h @@ -113,15 +113,9 @@ protected: std::string GetLinkerMacro () const; static std::string GetDebugFormat (); void GenerateCleanObjectsAsYouGoCode () const; - void GenerateRunRsymCode () const; - void GenerateRunStripCode () const; - void GenerateLinkerCommand ( const std::string& dependencies, - const std::string& linkerParameters, - const std::string& pefixupParameters ); - void GeneratePhonyTarget() const; + void GenerateLinkerCommand () const; void GenerateBuildMapCode ( const FileLocation *mapTarget = NULL ); void GenerateRules (); - void GenerateImportLibraryTarget (const FileLocation *defFilename, const FileLocation *library_target, bool delayimp); void GenerateImportLibraryTargetIfNeeded (); void GetDefinitionDependencies ( std::vector& dependencies ) const; std::string GetLinkingDependencies () const; diff --git a/reactos/tools/rbuild/backend/mingw/rules.mak b/reactos/tools/rbuild/backend/mingw/rules.mak index 9b9cc8cc1f4..40e30f7bdcd 100644 --- a/reactos/tools/rbuild/backend/mingw/rules.mak +++ b/reactos/tools/rbuild/backend/mingw/rules.mak @@ -19,7 +19,7 @@ RBUILD_intermediate_dir=${call RBUILD_fullpath,$(value INTERMEDIATE)$(SEP)$(dir RBUILD_output_dir=${call RBUILD_fullpath,$(value OUTPUT)$(SEP)$(dir ${call RBUILD_strip_prefixes,$(1)})} #(source) -RBUILD_source_name=$(basename $(notdir $(1))) +RBUILD_name=$(basename $(notdir $(1))) #(source) RBUILD_dir=${call RBUILD_fullpath,$(dir ${call RBUILD_compress_prefixes,$(1)})} diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index 21595b69a88..812e11c4b0e 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -467,7 +467,7 @@ MSVCBackend::_generate_vcproj ( const Module& module ) { fprintf ( OUT, "\t\t\tvalue == "true"; - else - underscoreSymbols = false; - isStartupLib = GetBooleanAttribute ( moduleNode, "isstartuplib" ); isCRT = GetBooleanAttribute ( moduleNode, "iscrt", GetDefaultModuleIsCRT () ); @@ -1359,12 +1351,13 @@ Module::GetInvocationTarget ( const int index ) const } string -Module::GetEntryPoint(bool leadingUnderscore) const +Module::GetEntryPoint() const { string result = ""; if (entrypoint == "0" || entrypoint == "0x0") return "0"; - if (leadingUnderscore) + + if (Environment::GetArch() != "arm") result = "_"; result += entrypoint; @@ -1874,10 +1867,6 @@ ImportLibrary::ImportLibrary ( const Project& project, if ( dllname ) this->dllname = dllname->value; - else if ( module->type == StaticLibrary || module->type == HostStaticLibrary ) - throw XMLInvalidBuildFileException ( - node.location, - " dllname attribute required." ); size_t index = definition->value.find_last_of ( "/\\" ); if ( index == string::npos ) diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h index 6d70f3afcd5..f8ae933a130 100644 --- a/reactos/tools/rbuild/rbuild.h +++ b/reactos/tools/rbuild/rbuild.h @@ -378,8 +378,6 @@ public: ImportLibrary* delayImportLibrary; Metadata* metadata; Bootsector* bootSector; - bool mangledSymbols; - bool underscoreSymbols; bool isUnicode; bool isDefaultEntryPoint; Bootstrap* bootstrap; @@ -420,7 +418,7 @@ public: bool IsDLL () const; std::string GetPathWithPrefix ( const std::string& prefix ) const; // "path/prefixfoo.exe" std::string GetPathToBaseDir() const; // "../" offset to rootdirectory - std::string GetEntryPoint(bool leadingUnderscore) const; + std::string GetEntryPoint() const; void GetTargets ( string_list& ) const; std::string GetInvocationTarget ( const int index ) const; bool HasFileWithExtension ( const IfableData&, const std::string& extension ) const; From 4574bb5be8076fb0c5b1eca84357af8c57216923 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 11 Nov 2009 07:36:49 +0000 Subject: [PATCH 018/140] sync shell32 winetest to wine 1.1.32 svn path=/trunk/; revision=44098 --- rostests/winetests/shell32/appbar.c | 11 +- rostests/winetests/shell32/shelllink.c | 34 ++- rostests/winetests/shell32/shellpath.c | 5 +- rostests/winetests/shell32/shlexec.c | 370 ++++++++++++++++++------- rostests/winetests/shell32/shlfileop.c | 84 ++++-- 5 files changed, 361 insertions(+), 143 deletions(-) diff --git a/rostests/winetests/shell32/appbar.c b/rostests/winetests/shell32/appbar.c index 73dc0b2d81a..5e5dfafbd22 100644 --- a/rostests/winetests/shell32/appbar.c +++ b/rostests/winetests/shell32/appbar.c @@ -205,6 +205,7 @@ static void test_setpos(void) RECT rc; int screen_width, screen_height; BOOL ret; + int org_bottom1; screen_width = GetSystemMetrics(SM_CXSCREEN); screen_height = GetSystemMetrics(SM_CYSCREEN); @@ -336,6 +337,9 @@ static void test_setpos(void) /* removing windows[0] will cause windows[1] to move down into its space */ expected_bottom = max(windows[0].allocated_rect.bottom, windows[1].allocated_rect.bottom); + org_bottom1 = windows[1].allocated_rect.bottom; + ok(windows[0].allocated_rect.bottom > windows[1].allocated_rect.bottom, + "Expected windows[0] to be lower than windows[1]\n"); abd.hWnd = windows[0].hwnd; windows[0].to_be_deleted = TRUE; @@ -346,7 +350,12 @@ static void test_setpos(void) do_events_until(got_expected_bottom); - ok(windows[1].allocated_rect.bottom == expected_bottom, "windows[1]'s bottom is %i, expected %i\n", windows[1].allocated_rect.bottom, expected_bottom); + if (windows[1].allocated_rect.bottom == org_bottom1) + win_skip("Some broken Vista boxes don't move the higher appbar down\n"); + else + ok(windows[1].allocated_rect.bottom == expected_bottom, + "windows[1]'s bottom is %i, expected %i\n", + windows[1].allocated_rect.bottom, expected_bottom); test_window_rects(1, 2); diff --git a/rostests/winetests/shell32/shelllink.c b/rostests/winetests/shell32/shelllink.c index 15a93db00e4..2f20200c67a 100755 --- a/rostests/winetests/shell32/shelllink.c +++ b/rostests/winetests/shell32/shelllink.c @@ -107,6 +107,7 @@ static void test_get_set(void) { HRESULT r; IShellLinkA *sl; + IShellLinkW *slW = NULL; char mypath[MAX_PATH]; char buffer[INFOTIPSIZE]; LPITEMIDLIST pidl, tmp_pidl; @@ -156,6 +157,19 @@ static void test_get_set(void) ok(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r); ok(*buffer=='\0', "GetPath returned '%s'\n", buffer); + CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + &IID_IShellLinkW, (LPVOID*)&slW); + if (!slW) + skip("SetPath with NULL parameter crashes on Win9x\n"); + else + { + IShellLinkW_Release(slW); + r = IShellLinkA_SetPath(sl, NULL); + ok(r==E_INVALIDARG || + broken(r==S_OK), /* Some Win95 and NT4 */ + "SetPath failed (0x%08x)\n", r); + } + r = IShellLinkA_SetPath(sl, ""); ok(r==S_OK, "SetPath failed (0x%08x)\n", r); @@ -651,16 +665,12 @@ static void test_load_save(void) static void test_datalink(void) { static const WCHAR lnk[] = { - ':',':','{','9','d','b','1','1','8','6','f','-','4','0','d','f','-','1', + ':',':','{','9','d','b','1','1','8','6','e','-','4','0','d','f','-','1', '1','d','1','-','a','a','8','c','-','0','0','c','0','4','f','b','6','7', - '8','6','3','}',':','{','0','0','0','1','0','4','0','9','-','7','8','E', - '1','-','1','1','D','2','-','B','6','0','F','-','0','0','6','0','9','7', - 'C','9','9','8','E','7','}',':',':','{','9','d','b','1','1','8','6','e', - '-','4','0','d','f','-','1','1','d','1','-','a','a','8','c','-','0','0', - 'c','0','4','f','b','6','7','8','6','3','}',':','2','6',',','!','!','g', - 'x','s','f','(','N','g',']','q','F','`','H','{','L','s','A','C','C','E', - 'S','S','F','i','l','e','s','>','p','l','T',']','j','I','{','j','f','(', - '=','1','&','L','[','-','8','1','-',']',':',':',0 }; + '8','6','3','}',':','2','6',',','!','!','g','x','s','f','(','N','g',']', + 'q','F','`','H','{','L','s','A','C','C','E','S','S','F','i','l','e','s', + '>','p','l','T',']','j','I','{','j','f','(','=','1','&','L','[','-','8', + '1','-',']',':',':',0 }; static const WCHAR comp[] = { '2','6',',','!','!','g','x','s','f','(','N','g',']','q','F','`','H','{', 'L','s','A','C','C','E','S','S','F','i','l','e','s','>','p','l','T',']', @@ -704,6 +714,9 @@ static void test_datalink(void) ok( r == E_FAIL, "CopyDataBlock failed\n"); ok( dar == NULL, "should be null\n"); + r = IShellLinkW_SetPath(sl, NULL); + ok(r == E_INVALIDARG, "set path failed\n"); + r = IShellLinkW_SetPath(sl, lnk); ok(r == S_OK, "set path failed\n"); @@ -715,7 +728,8 @@ static void test_datalink(void) flags = 0; r = IShellLinkDataList_GetFlags( dl, &flags ); ok( r == S_OK, "GetFlags failed\n"); - ok( flags == (SLDF_HAS_DARWINID|SLDF_HAS_LOGO3ID), + /* SLDF_HAS_LOGO3ID is no longer supported on Vista+, filter it out */ + ok( (flags & (~ SLDF_HAS_LOGO3ID)) == SLDF_HAS_DARWINID, "GetFlags returned wrong flags\n"); dar = NULL; diff --git a/rostests/winetests/shell32/shellpath.c b/rostests/winetests/shell32/shellpath.c index b5b196747ac..f9f59e16dde 100644 --- a/rostests/winetests/shell32/shellpath.c +++ b/rostests/winetests/shell32/shellpath.c @@ -43,6 +43,9 @@ #endif /* from pidl.h, not included here: */ +#ifndef PT_CPL /* Guess, Win7 uses this for CSIDL_CONTROLS */ +#define PT_CPL 0x01 /* no path */ +#endif #ifndef PT_GUID #define PT_GUID 0x1f /* no path */ #endif @@ -93,7 +96,7 @@ static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR,UINT); static DLLVERSIONINFO shellVersion = { 0 }; static LPMALLOC pMalloc; static const BYTE guidType[] = { PT_GUID }; -static const BYTE controlPanelType[] = { PT_SHELLEXT, PT_GUID }; +static const BYTE controlPanelType[] = { PT_SHELLEXT, PT_GUID, PT_CPL }; static const BYTE folderType[] = { PT_FOLDER, PT_FOLDERW }; static const BYTE favoritesType[] = { PT_FOLDER, PT_FOLDERW, 0, PT_IESPECIAL2 /* Win98 */ }; static const BYTE folderOrSpecialType[] = { PT_FOLDER, PT_IESPECIAL2 }; diff --git a/rostests/winetests/shell32/shlexec.c b/rostests/winetests/shell32/shlexec.c index 7ddeee33da9..5e97f61171a 100755 --- a/rostests/winetests/shell32/shlexec.c +++ b/rostests/winetests/shell32/shlexec.c @@ -56,6 +56,7 @@ static char** myARGV; static char tmpdir[MAX_PATH]; static char child_file[MAX_PATH]; static DLLVERSIONINFO dllver; +static BOOL skip_noassoc_tests = FALSE; /*** @@ -117,7 +118,18 @@ static int shell_execute(LPCSTR operation, LPCSTR file, LPCSTR parameters, LPCST { int wait_rc; wait_rc=WaitForSingleObject(hEvent, 5000); - ok(wait_rc==WAIT_OBJECT_0, "WaitForSingleObject returned %d\n", wait_rc); + if (wait_rc == WAIT_TIMEOUT) + { + HWND wnd = FindWindowA("#32770", "Windows"); + if (wnd != NULL) + { + SendMessage(wnd, WM_CLOSE, 0, 0); + win_skip("Skipping shellexecute of file with unassociated extension\n"); + skip_noassoc_tests = TRUE; + rc = SE_ERR_NOASSOC; + } + } + ok(wait_rc==WAIT_OBJECT_0 || rc <= 32, "WaitForSingleObject returned %d\n", wait_rc); } /* The child process may have changed the result file, so let profile * functions know about it @@ -462,11 +474,67 @@ static void childPrintf(HANDLE h, const char* fmt, ...) WriteFile(h, buffer, strlen(buffer), &w, NULL); } +static DWORD ddeInst; +static HSZ hszTopic; +static char ddeExec[MAX_PATH], ddeApplication[MAX_PATH]; +static BOOL post_quit_on_execute; + +static HDDEDATA CALLBACK ddeCb(UINT uType, UINT uFmt, HCONV hConv, + HSZ hsz1, HSZ hsz2, HDDEDATA hData, + ULONG_PTR dwData1, ULONG_PTR dwData2) +{ + DWORD size = 0; + + if (winetest_debug > 2) + trace("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n", + uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2); + + switch (uType) + { + case XTYP_CONNECT: + if (!DdeCmpStringHandles(hsz1, hszTopic)) + { + size = DdeQueryString(ddeInst, hsz2, ddeApplication, MAX_PATH, CP_WINANSI); + assert(size < MAX_PATH); + return (HDDEDATA)TRUE; + } + return (HDDEDATA)FALSE; + + case XTYP_EXECUTE: + size = DdeGetData(hData, (LPBYTE)ddeExec, MAX_PATH, 0L); + assert(size < MAX_PATH); + DdeFreeDataHandle(hData); + if (post_quit_on_execute) + PostQuitMessage(0); + return (HDDEDATA)DDE_FACK; + + default: + return NULL; + } +} + +/* + * This is just to make sure the child won't run forever stuck in a GetMessage() + * loop when DDE fails for some reason. + */ +static void CALLBACK childTimeout(HWND wnd, UINT msg, UINT_PTR timer, DWORD time) +{ + trace("childTimeout called\n"); + + PostQuitMessage(0); +} + static void doChild(int argc, char** argv) { char* filename; - HANDLE hFile; + HANDLE hFile, map; int i; + int rc; + HSZ hszApplication; + UINT_PTR timer; + HANDLE dde_ready; + MSG msg; + char *shared_block; filename=argv[2]; hFile=CreateFileA(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); @@ -484,6 +552,51 @@ static void doChild(int argc, char** argv) trace("argvA%d=%s\n", i, argv[i]); childPrintf(hFile, "argvA%d=%s\r\n", i, encodeA(argv[i])); } + + map = OpenFileMappingA(FILE_MAP_READ, FALSE, "winetest_shlexec_dde_map"); + if (map != NULL) + { + shared_block = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 4096); + CloseHandle(map); + if (shared_block[0] != '\0' || shared_block[1] != '\0') + { + post_quit_on_execute = TRUE; + ddeInst = 0; + rc = DdeInitializeA(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | + CBF_FAIL_POKES | CBF_FAIL_REQUESTS, 0L); + assert(rc == DMLERR_NO_ERROR); + hszApplication = DdeCreateStringHandleA(ddeInst, shared_block, CP_WINANSI); + hszTopic = DdeCreateStringHandleA(ddeInst, shared_block + strlen(shared_block) + 1, CP_WINANSI); + assert(hszApplication && hszTopic); + assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_REGISTER | DNS_FILTEROFF)); + + timer = SetTimer(NULL, 0, 2500, childTimeout); + + dde_ready = CreateEvent(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready"); + SetEvent(dde_ready); + CloseHandle(dde_ready); + + while (GetMessage(&msg, NULL, 0, 0)) + DispatchMessage(&msg); + + KillTimer(NULL, timer); + assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_UNREGISTER)); + assert(DdeFreeStringHandle(ddeInst, hszTopic)); + assert(DdeFreeStringHandle(ddeInst, hszApplication)); + assert(DdeUninitialize(ddeInst)); + } + else + { + dde_ready = CreateEvent(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready"); + SetEvent(dde_ready); + CloseHandle(dde_ready); + } + + UnmapViewOfFile(shared_block); + + childPrintf(hFile, "ddeExec=%s\r\n", encodeA(ddeExec)); + } + CloseHandle(hFile); init_event(filename); @@ -751,6 +864,13 @@ static void test_filename(void) { BOOL quotedfile = FALSE; + if (skip_noassoc_tests && test->rc == SE_ERR_NOASSOC) + { + win_skip("Skipping shellexecute of file with unassociated extension\n"); + test++; + continue; + } + sprintf(filename, test->basename, tmpdir); if (strchr(filename, '/')) { @@ -1117,7 +1237,7 @@ static void test_lnks(void) { okChildInt("argcA", 5); } - else + else { okChildInt("argcA", 5); } @@ -1159,14 +1279,21 @@ static void test_exes(void) okChildInt("argcA", 4); okChildString("argvA3", "Exec"); - sprintf(filename, "%s\\test file.noassoc", tmpdir); - if (CopyFile(argv0, filename, FALSE)) + if (! skip_noassoc_tests) { - rc=shell_execute(NULL, filename, params, NULL); - todo_wine { - ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); + sprintf(filename, "%s\\test file.noassoc", tmpdir); + if (CopyFile(argv0, filename, FALSE)) + { + rc=shell_execute(NULL, filename, params, NULL); + todo_wine { + ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); + } } } + else + { + win_skip("Skipping shellexecute of file with unassociated extension\n"); + } } static void test_exes_long(void) @@ -1190,14 +1317,21 @@ static void test_exes_long(void) okChildInt("argcA", 4); okChildString("argvA3", longparam); - sprintf(filename, "%s\\test file.noassoc", tmpdir); - if (CopyFile(argv0, filename, FALSE)) + if (! skip_noassoc_tests) { - rc=shell_execute(NULL, filename, params, NULL); - todo_wine { - ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); + sprintf(filename, "%s\\test file.noassoc", tmpdir); + if (CopyFile(argv0, filename, FALSE)) + { + rc=shell_execute(NULL, filename, params, NULL); + todo_wine { + ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); + } } } + else + { + win_skip("Skipping shellexecute of file with unassociated extension\n"); + } } typedef struct @@ -1210,115 +1344,123 @@ typedef struct int expectedArgs; const char* expectedDdeExec; int todo; - int rc; } dde_tests_t; static dde_tests_t dde_tests[] = { /* Test passing and not passing command-line * argument, no DDE */ - {"", NULL, NULL, NULL, NULL, FALSE, "", 0x0, 33}, - {"\"%1\"", NULL, NULL, NULL, NULL, TRUE, "", 0x0, 33}, + {"", NULL, NULL, NULL, NULL, FALSE, "", 0x0}, + {"\"%1\"", NULL, NULL, NULL, NULL, TRUE, "", 0x0}, /* Test passing and not passing command-line * argument, with DDE */ - {"", "[open(\"%1\")]", "shlexec", "dde", NULL, FALSE, "[open(\"%s\")]", 0x0, 33}, - {"\"%1\"", "[open(\"%1\")]", "shlexec", "dde", NULL, TRUE, "[open(\"%s\")]", 0x0, 33}, + {"", "[open(\"%1\")]", "shlexec", "dde", NULL, FALSE, "[open(\"%s\")]", 0x0}, + {"\"%1\"", "[open(\"%1\")]", "shlexec", "dde", NULL, TRUE, "[open(\"%s\")]", 0x0}, /* Test unquoted %1 in command and ddeexec * (test filename has space) */ - {"%1", "[open(%1)]", "shlexec", "dde", NULL, 2, "[open(%s)]", 0x0, 33}, + {"%1", "[open(%1)]", "shlexec", "dde", NULL, 2, "[open(%s)]", 0x0}, /* Test ifexec precedence over ddeexec */ - {"", "[open(\"%1\")]", "shlexec", "dde", "[ifexec(\"%1\")]", FALSE, "[ifexec(\"%s\")]", 0x0, 33}, + {"", "[open(\"%1\")]", "shlexec", "dde", "[ifexec(\"%1\")]", FALSE, "[ifexec(\"%s\")]", 0x0}, /* Test default DDE topic */ - {"", "[open(\"%1\")]", "shlexec", NULL, NULL, FALSE, "[open(\"%s\")]", 0x0, 33}, + {"", "[open(\"%1\")]", "shlexec", NULL, NULL, FALSE, "[open(\"%s\")]", 0x0}, /* Test default DDE application */ - {"", "[open(\"%1\")]", NULL, "dde", NULL, FALSE, "[open(\"%s\")]", 0x0, 33}, + {"", "[open(\"%1\")]", NULL, "dde", NULL, FALSE, "[open(\"%s\")]", 0x0}, - {NULL, NULL, NULL, NULL, NULL, 0, 0x0, 0} + {NULL, NULL, NULL, NULL, NULL, 0, 0x0} }; -static DWORD ddeInst; -static HSZ hszTopic; -static char ddeExec[MAX_PATH], ddeApplication[MAX_PATH]; -static BOOL denyNextConnection; - -static HDDEDATA CALLBACK ddeCb(UINT uType, UINT uFmt, HCONV hConv, - HSZ hsz1, HSZ hsz2, HDDEDATA hData, - ULONG_PTR dwData1, ULONG_PTR dwData2) +static DWORD WINAPI hooked_WaitForInputIdle(HANDLE process, DWORD timeout) { - DWORD size = 0; + HANDLE dde_ready; + DWORD wait_result; - if (winetest_debug > 2) - trace("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n", - uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2); + dde_ready = CreateEventA(NULL, FALSE, FALSE, "winetest_shlexec_dde_ready"); + wait_result = WaitForSingleObject(dde_ready, timeout); + CloseHandle(dde_ready); - switch (uType) + return wait_result; +} + +/* + * WaitForInputIdle() will normally return immediately for console apps. That's + * a problem for us because ShellExecute will assume that an app is ready to + * receive DDE messages after it has called WaitForInputIdle() on that app. + * To work around that we install our own version of WaitForInputIdle() that + * will wait for the child to explicitly tell us that it is ready. We do that + * by changing the entry for WaitForInputIdle() in the shell32 import address + * table. + */ +static void hook_WaitForInputIdle(void *new_func) +{ + char *base; + PIMAGE_NT_HEADERS nt_headers; + DWORD import_directory_rva; + PIMAGE_IMPORT_DESCRIPTOR import_descriptor; + + base = (char *) GetModuleHandleA("shell32.dll"); + nt_headers = (PIMAGE_NT_HEADERS)(base + ((PIMAGE_DOS_HEADER) base)->e_lfanew); + import_directory_rva = nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + + /* Search for the correct imported module by walking the import descriptors */ + import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)(base + import_directory_rva); + while (U(*import_descriptor).OriginalFirstThunk != 0) { - case XTYP_CONNECT: - if (!DdeCmpStringHandles(hsz1, hszTopic)) + char *import_module_name; + + import_module_name = base + import_descriptor->Name; + if (lstrcmpiA(import_module_name, "user32.dll") == 0 || + lstrcmpiA(import_module_name, "user32") == 0) + { + PIMAGE_THUNK_DATA int_entry; + PIMAGE_THUNK_DATA iat_entry; + + /* The import name table and import address table are two parallel + * arrays. We need the import name table to find the imported + * routine and the import address table to patch the address, so + * walk them side by side */ + int_entry = (PIMAGE_THUNK_DATA)(base + U(*import_descriptor).OriginalFirstThunk); + iat_entry = (PIMAGE_THUNK_DATA)(base + import_descriptor->FirstThunk); + while (int_entry->u1.Ordinal != 0) { - if (denyNextConnection) - denyNextConnection = FALSE; - else + if (! IMAGE_SNAP_BY_ORDINAL(int_entry->u1.Ordinal)) { - size = DdeQueryString(ddeInst, hsz2, ddeApplication, MAX_PATH, CP_WINANSI); - assert(size < MAX_PATH); - return (HDDEDATA)TRUE; + PIMAGE_IMPORT_BY_NAME import_by_name; + import_by_name = (PIMAGE_IMPORT_BY_NAME)(base + int_entry->u1.AddressOfData); + if (lstrcmpA((char *) import_by_name->Name, "WaitForInputIdle") == 0) + { + /* Found the correct routine in the correct imported module. Patch it. */ + DWORD old_prot; + VirtualProtect(&iat_entry->u1.Function, sizeof(ULONG_PTR), PAGE_READWRITE, &old_prot); + iat_entry->u1.Function = (ULONG_PTR) new_func; + VirtualProtect(&iat_entry->u1.Function, sizeof(ULONG_PTR), old_prot, &old_prot); + break; + } } + int_entry++; + iat_entry++; } - return (HDDEDATA)FALSE; + break; + } - case XTYP_EXECUTE: - size = DdeGetData(hData, (LPBYTE)ddeExec, MAX_PATH, 0L); - assert(size < MAX_PATH); - DdeFreeDataHandle(hData); - return (HDDEDATA)DDE_FACK; - - default: - return NULL; + import_descriptor++; } } -typedef struct -{ - char *filename; - DWORD threadIdParent; -} dde_thread_info_t; - -static DWORD CALLBACK ddeThread(LPVOID arg) -{ - dde_thread_info_t *info = arg; - assert(info && info->filename); - PostThreadMessage(info->threadIdParent, - WM_QUIT, - shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, info->filename, NULL, NULL), - 0L); - ExitThread(0); -} - -/* ShellExecute won't successfully send DDE commands to console applications after starting them, - * so we run a DDE server in this application, deny the first connection request to make - * ShellExecute start the application, and then process the next DDE connection in this application - * to see the execute command that is sent. */ static void test_dde(void) { char filename[MAX_PATH], defApplication[MAX_PATH]; - HSZ hszApplication; - dde_thread_info_t info = { filename, GetCurrentThreadId() }; const dde_tests_t* test; char params[1024]; - DWORD threadId; - MSG msg; int rc; + HANDLE map; + char *shared_block; - ddeInst = 0; - rc = DdeInitializeA(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | - CBF_FAIL_POKES | CBF_FAIL_REQUESTS, 0L); - assert(rc == DMLERR_NO_ERROR); + hook_WaitForInputIdle((void *) hooked_WaitForInputIdle); sprintf(filename, "%s\\test file.sde", tmpdir); @@ -1326,6 +1468,10 @@ static void test_dde(void) strcpy(defApplication, strrchr(argv0, '\\')+1); *strchr(defApplication, '.') = 0; + map = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, + 4096, "winetest_shlexec_dde_map"); + shared_block = MapViewOfFile(map, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 4096); + test = dde_tests; while (test->command) { @@ -1336,29 +1482,31 @@ static void test_dde(void) } create_test_verb_dde(".sde", "Open", 0, test->command, test->ddeexec, test->application, test->topic, test->ifexec); - hszApplication = DdeCreateStringHandleA(ddeInst, test->application ? - test->application : defApplication, CP_WINANSI); - hszTopic = DdeCreateStringHandleA(ddeInst, test->topic ? test->topic : SZDDESYS_TOPIC, - CP_WINANSI); - assert(hszApplication && hszTopic); - assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_REGISTER)); - denyNextConnection = TRUE; + + if (test->application != NULL || test->topic != NULL) + { + strcpy(shared_block, test->application ? test->application : defApplication); + strcpy(shared_block + strlen(shared_block) + 1, test->topic ? test->topic : SZDDESYS_TOPIC); + } + else + { + shared_block[0] = '\0'; + shared_block[1] = '\0'; + } ddeExec[0] = 0; - assert(CreateThread(NULL, 0, ddeThread, &info, 0, &threadId)); - while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); - rc = msg.wParam > 32 ? 33 : msg.wParam; + rc = shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, filename, NULL, NULL); if ((test->todo & 0x1)==0) { - ok(rc==test->rc, "%s failed: rc=%d err=%d\n", shell_call, + ok(32 < rc, "%s failed: rc=%d err=%d\n", shell_call, rc, GetLastError()); } else todo_wine { - ok(rc==test->rc, "%s failed: rc=%d err=%d\n", shell_call, + ok(32 < rc, "%s failed: rc=%d err=%d\n", shell_call, rc, GetLastError()); } - if (rc == 33) + if (32 < rc) { if ((test->todo & 0x2)==0) { @@ -1382,25 +1530,22 @@ static void test_dde(void) if ((test->todo & 0x8) == 0) { sprintf(params, test->expectedDdeExec, filename); - ok(StrCmpPath(params, ddeExec) == 0, - "ddeexec expected '%s', got '%s'\n", params, ddeExec); + okChildPath("ddeExec", params); } else todo_wine { sprintf(params, test->expectedDdeExec, filename); - ok(StrCmpPath(params, ddeExec) == 0, - "ddeexec expected '%s', got '%s'\n", params, ddeExec); + okChildPath("ddeExec", params); } } - assert(DdeNameService(ddeInst, hszApplication, 0L, DNS_UNREGISTER)); - assert(DdeFreeStringHandle(ddeInst, hszTopic)); - assert(DdeFreeStringHandle(ddeInst, hszApplication)); delete_test_association(".sde"); test++; } - assert(DdeUninitialize(ddeInst)); + UnmapViewOfFile(shared_block); + CloseHandle(map); + hook_WaitForInputIdle((void *) WaitForInputIdle); } #define DDE_DEFAULT_APP_VARIANTS 2 @@ -1454,6 +1599,23 @@ static dde_default_app_tests_t dde_default_app_tests[] = {NULL, {NULL}, 0, {0}} }; +typedef struct +{ + char *filename; + DWORD threadIdParent; +} dde_thread_info_t; + +static DWORD CALLBACK ddeThread(LPVOID arg) +{ + dde_thread_info_t *info = arg; + assert(info && info->filename); + PostThreadMessage(info->threadIdParent, + WM_QUIT, + shell_execute_ex(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI, NULL, info->filename, NULL, NULL), + 0L); + ExitThread(0); +} + static void test_dde_default_app(void) { char filename[MAX_PATH]; @@ -1465,6 +1627,7 @@ static void test_dde_default_app(void) MSG msg; int rc, which = 0; + post_quit_on_execute = FALSE; ddeInst = 0; rc = DdeInitializeA(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | CBF_FAIL_POKES | CBF_FAIL_REQUESTS, 0L); @@ -1491,7 +1654,6 @@ static void test_dde_default_app(void) sprintf(params, test->command, tmpdir); create_test_verb_dde(".sde", "Open", 1, params, "[test]", NULL, "shlexec", NULL); - denyNextConnection = FALSE; ddeApplication[0] = 0; /* No application will be run as we will respond to the first DDE event, diff --git a/rostests/winetests/shell32/shlfileop.c b/rostests/winetests/shell32/shlfileop.c index 3c126ed2f91..33d1a943868 100644 --- a/rostests/winetests/shell32/shlfileop.c +++ b/rostests/winetests/shell32/shlfileop.c @@ -48,8 +48,8 @@ "Expected %d, got %d\n", ret, retval) static CHAR CURR_DIR[MAX_PATH]; -static const WCHAR UNICODE_PATH[] = {'c',':','\\',0x00c4,'\0','\0'}; - /* "c:\Ă„", or "c:\A" with diaeresis */ +static const WCHAR UNICODE_PATH[] = {'c',':','\\',0x00ae,'\0','\0'}; + /* "c:\®" can be used in all codepages */ /* Double-null termination needed for pFrom field of SHFILEOPSTRUCT */ static HMODULE hshell32; @@ -207,11 +207,11 @@ static void test_get_file_info(void) memset(&shfiw, 0xcf, sizeof(shfiw)); memset(&unset_icon, 0xcf, sizeof(unset_icon)); rc=pSHGetFileInfoW(NULL, 0, &shfiw, sizeof(shfiw), 0); - todo_wine ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n"); + ok(!rc, "SHGetFileInfoW(NULL | 0) should fail\n"); ok(shfiw.hIcon == unset_icon, "SHGetFileInfoW(NULL | 0) should not clear hIcon\n"); - todo_wine ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n"); - todo_wine ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n"); - todo_wine ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n"); + ok(shfiw.szDisplayName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szDisplayName[0]\n"); + ok(shfiw.szTypeName[0] == 0xcfcf, "SHGetFileInfoW(NULL | 0) should not clear szTypeName[0]\n"); + ok(shfiw.iIcon == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear iIcon\n"); ok(shfiw.dwAttributes == 0xcfcfcfcf, "SHGetFileInfoW(NULL | 0) should not clear dwAttributes\n"); } else @@ -1042,10 +1042,13 @@ static void test_copy(void) shfo.pTo = "testdir2\\a.txt\0testdir2\\b.txt\0testdir2\\c.txt\0"; shfo.fAnyOperationsAborted = FALSE; retval = SHFileOperation(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n"); ok(DeleteFile("testdir2\\b.txt"), "Expected testdir2\\b.txt to exist\n"); - ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n"); + if (retval == ERROR_SUCCESS) + ok(RemoveDirectory("testdir2\\c.txt"), "Expected testdir2\\c.txt to exist\n"); /* try many dest files without FOF_MULTIDESTFILES flag */ shfo.pFrom = "test1.txt\0test2.txt\0test3.txt\0"; @@ -1073,7 +1076,9 @@ static void test_copy(void) shfo.pTo = "testdir2\0"; shfo.fFlags &= ~FOF_MULTIDESTFILES; retval = SHFileOperation(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); ok(file_exists("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n"); /* try a glob with FOF_FILESONLY */ @@ -1190,18 +1195,28 @@ static void test_copy(void) shfo.fFlags &= ~FOF_MULTIDESTFILES; shfo.fAnyOperationsAborted = FALSE; retval = SHFileOperation(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval); - ok(DeleteFile("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n"); - ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n"); - ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n"); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); + if (retval == ERROR_SUCCESS) + { + ok(DeleteFile("testdir2\\test1.txt"), "Expected testdir2\\test1.txt to exist\n"); + ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n"); + ok(RemoveDirectory("testdir2\\test4.txt"), "Expected testdir2\\test4.txt to exist\n"); + } /* copy one directory and a file in that dir to another dir */ shfo.pFrom = "test4.txt\0test4.txt\\a.txt\0"; shfo.pTo = "testdir2\0"; retval = SHFileOperation(&shfo); - ok(retval == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", retval); - ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n"); - ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n"); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); + if (retval == ERROR_SUCCESS) + { + ok(DeleteFile("testdir2\\test4.txt\\a.txt"), "Expected a.txt to exist\n"); + ok(DeleteFile("testdir2\\a.txt"), "Expected testdir2\\a.txt to exist\n"); + } /* copy a file in a directory first, and then the directory to a nonexistent dir */ shfo.pFrom = "test4.txt\\a.txt\0test4.txt\0"; @@ -1362,13 +1377,21 @@ static void test_copy(void) createTestFile("test4.txt\\test1.txt"); shfo.pFrom = "test4.txt\0"; shfo.pTo = "testdir2\0"; - shfo.fFlags = FOF_NOCONFIRMATION; - ok(!SHFileOperation(&shfo), "First SHFileOperation failed\n"); - createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */ - /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */ + /* WinMe needs FOF_NOERRORUI */ + shfo.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI; retval = SHFileOperation(&shfo); - ok(retval == 0, "Expected 0, got %d\n", retval); - ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n"); + ok(retval == ERROR_SUCCESS || + broken(retval == 0x100a1), /* WinMe */ + "Expected ERROR_SUCCESS, got %d\n", retval); + shfo.fFlags = FOF_NOCONFIRMATION; + if (ERROR_SUCCESS) + { + createTestFile("test4.txt\\.\\test1.txt"); /* modify the content of the file */ + /* without FOF_NOCONFIRMATION the confirmation is "This folder already contains a folder named ..." */ + retval = SHFileOperation(&shfo); + ok(retval == 0, "Expected 0, got %d\n", retval); + ok(file_has_content("testdir2\\test4.txt\\test1.txt", "test4.txt\\.\\test1.txt\n"), "The file was not copied\n"); + } createTestFile("one.txt"); @@ -1955,6 +1978,7 @@ static void test_sh_path_prepare(void) { HRESULT res; CHAR path[MAX_PATH]; + CHAR UNICODE_PATH_A[MAX_PATH]; if(!pSHPathPrepareForWriteA) { @@ -1987,12 +2011,14 @@ static void test_sh_path_prepare(void) set_curr_dir_path(path, "test1.txt\0"); res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE); ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) || + res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */ res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */ "Unexpected result : 0x%08x\n", res); /* file exists, SHPPFW_DIRCREATE */ res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_DIRCREATE); ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) || + res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */ res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */ "Unexpected result : 0x%08x\n", res); @@ -2000,6 +2026,7 @@ static void test_sh_path_prepare(void) set_curr_dir_path(path, "test1.txt\\\0"); res = pSHPathPrepareForWriteA(0, 0, path, SHPPFW_NONE); ok(res == HRESULT_FROM_WIN32(ERROR_DIRECTORY) || + res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* WinMe */ res == HRESULT_FROM_WIN32(ERROR_INVALID_NAME), /* Vista */ "Unexpected result : 0x%08x\n", res); @@ -2040,19 +2067,22 @@ static void test_sh_path_prepare(void) if(!pSHPathPrepareForWriteW) { - skip("Skipping SHPathPrepareForWriteW tests\n"); + win_skip("Skipping SHPathPrepareForWriteW tests\n"); return; } + WideCharToMultiByte(CP_ACP, 0, UNICODE_PATH, -1, UNICODE_PATH_A, sizeof(UNICODE_PATH_A), NULL, NULL); + /* unicode directory doesn't exist, SHPPFW_NONE */ + RemoveDirectoryA(UNICODE_PATH_A); res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE); ok(res == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND), "res == %08x, expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)\n", res); - ok(!file_existsW(UNICODE_PATH), "unicode path was created but shouldn't be\n"); - RemoveDirectoryW(UNICODE_PATH); + ok(!file_exists(UNICODE_PATH_A), "unicode path was created but shouldn't be\n"); + RemoveDirectoryA(UNICODE_PATH_A); /* unicode directory doesn't exist, SHPPFW_DIRCREATE */ res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE); ok(res == S_OK, "res == %08x, expected S_OK\n", res); - ok(file_existsW(UNICODE_PATH), "unicode path should've been created\n"); + ok(file_exists(UNICODE_PATH_A), "unicode path should've been created\n"); /* unicode directory exists, SHPPFW_NONE */ res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_NONE); @@ -2061,7 +2091,7 @@ static void test_sh_path_prepare(void) /* unicode directory exists, SHPPFW_DIRCREATE */ res = pSHPathPrepareForWriteW(0, 0, UNICODE_PATH, SHPPFW_DIRCREATE); ok(res == S_OK, "ret == %08x, expected S_OK\n", res); - RemoveDirectoryW(UNICODE_PATH); + RemoveDirectoryA(UNICODE_PATH_A); } static void test_sh_new_link_info(void) From 008929cd36cd0574ab9c714ef6888a643b6a5f16 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Wed, 11 Nov 2009 08:29:08 +0000 Subject: [PATCH 019/140] return TRUE in ReadFile if there is nothing to read svn path=/trunk/; revision=44099 --- reactos/dll/win32/kernel32/file/rw.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/reactos/dll/win32/kernel32/file/rw.c b/reactos/dll/win32/kernel32/file/rw.c index 93362f9de15..400caf79a1b 100644 --- a/reactos/dll/win32/kernel32/file/rw.c +++ b/reactos/dll/win32/kernel32/file/rw.c @@ -144,6 +144,11 @@ ReadFile(IN HANDLE hFile, *lpNumberOfBytesRead = 0; } + if (!nNumberOfBytesToRead) + { + return TRUE; + } + hFile = TranslateStdHandle(hFile); if (IsConsoleHandle(hFile)) From 7d088d0725e741d1887b3b84f674b73a14c5894e Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 11 Nov 2009 09:04:42 +0000 Subject: [PATCH 020/140] [KS] - Implement KsEnableEvent, KsEnableEventWithAllocator, KsDiscardEvent [PORTCLS] - Fix signalling the event - DirectSound clients can now use IDirectSoundNotify interface to be notified of a position change svn path=/trunk/; revision=44100 --- reactos/drivers/ksfilter/ks/event.c | 347 +++++++++++++++++- .../audio/backpln/portcls/pin_wavecyclic.cpp | 45 ++- 2 files changed, 365 insertions(+), 27 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/event.c b/reactos/drivers/ksfilter/ks/event.c index fedb507a9b9..5ec2e85e8e5 100644 --- a/reactos/drivers/ksfilter/ks/event.c +++ b/reactos/drivers/ksfilter/ks/event.c @@ -71,9 +71,312 @@ KspSynchronizedEventRoutine( return Result; } +BOOLEAN +NTAPI +SyncAddEvent( + PKSEVENT_CTX Context) +{ + InsertTailList(Context->List, &Context->EventEntry->ListEntry); + return TRUE; +} + +NTSTATUS +KspEnableEvent( + IN PIRP Irp, + IN ULONG EventSetsCount, + IN PKSEVENT_SET EventSet, + IN OUT PLIST_ENTRY EventsList OPTIONAL, + IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL, + IN PVOID EventsLock OPTIONAL, + IN PFNKSALLOCATOR Allocator OPTIONAL, + IN ULONG EventItemSize OPTIONAL) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + KSEVENT Event; + PKSEVENT_ITEM EventItem, FoundEventItem; + PKSEVENTDATA EventData; + PKSEVENT_SET FoundEventSet; + PKSEVENT_ENTRY EventEntry; + ULONG Index, SubIndex, Size; + PVOID Object; + KSEVENT_CTX Ctx; + LPGUID Guid; + + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSEVENT)) + { + /* invalid parameter */ + return STATUS_NOT_SUPPORTED; + } + + if (Irp->RequestorMode == UserMode) + { + _SEH2_TRY + { + ProbeForRead(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSEVENT), sizeof(UCHAR)); + ProbeForRead(Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, sizeof(UCHAR)); + RtlMoveMemory(&Event, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSEVENT)); + Status = STATUS_SUCCESS; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Exception, get the error code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* failed to probe parameters */ + return Status; + } + } + else + { + /* copy event struct */ + RtlMoveMemory(&Event, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSEVENT)); + } + + FoundEventItem = NULL; + FoundEventSet = NULL; + + + if (IsEqualGUIDAligned(&Event.Set, &GUID_NULL) && Event.Id == 0 && Event.Flags == KSEVENT_TYPE_SETSUPPORT) + { + // store output size + Irp->IoStatus.Information = sizeof(GUID) * EventSetsCount; + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * EventSetsCount) + { + // buffer too small + return STATUS_MORE_ENTRIES; + } + + // get output buffer + Guid = (LPGUID)Irp->UserBuffer; + + // copy property guids from property sets + for(Index = 0; Index < EventSetsCount; Index++) + { + RtlMoveMemory(&Guid[Index], EventSet[Index].Set, sizeof(GUID)); + } + return STATUS_SUCCESS; + } + + /* now try to find event set */ + for(Index = 0; Index < EventSetsCount; Index++) + { + if (IsEqualGUIDAligned(&Event.Set, EventSet[Index].Set)) + { + EventItem = (PKSEVENT_ITEM)EventSet[Index].EventItem; + + /* sanity check */ + ASSERT(EventSet[Index].EventsCount); + ASSERT(EventItem); + + /* now find matching event id */ + for(SubIndex = 0; SubIndex < EventSet[Index].EventsCount; SubIndex++) + { + if (EventItem[SubIndex].EventId == Event.Id) + { + /* found event item */ + FoundEventItem = &EventItem[SubIndex]; + FoundEventSet = &EventSet[Index]; + break; + } + } + + if (FoundEventSet) + break; + } + } + + if (!FoundEventSet) + { + UNICODE_STRING GuidString; + + RtlStringFromGUID(&Event.Set, &GuidString); + + DPRINT("Guid %S Id %u Flags %x not found\n", GuidString.Buffer, Event.Id, Event.Flags); + RtlFreeUnicodeString(&GuidString); + return STATUS_PROPSET_NOT_FOUND; + + + } + + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < FoundEventItem->DataInput) + { + /* buffer too small */ + DPRINT1("Got %u expected %u\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength, FoundEventItem->DataInput); + return STATUS_SUCCESS; + } + + if (!FoundEventItem->AddHandler && !EventsList) + { + /* no add handler and no list to add the new entry to */ + return STATUS_INVALID_PARAMETER; + } + + /* get event data */ + EventData = Irp->UserBuffer; + + /* sanity check */ + ASSERT(EventData); + + if (Irp->RequestorMode == UserMode) + { + if (EventData->NotificationType == KSEVENTF_SEMAPHORE_HANDLE) + { + /* get semaphore object handle */ + Status = ObReferenceObjectByHandle(EventData->SemaphoreHandle.Semaphore, SEMAPHORE_MODIFY_STATE, ExSemaphoreObjectType, Irp->RequestorMode, &Object, NULL); + + if (!NT_SUCCESS(Status)) + { + /* invalid semaphore handle */ + return STATUS_INVALID_PARAMETER; + } + } + else if (EventData->NotificationType == KSEVENTF_EVENT_HANDLE) + { + /* get event object handle */ + Status = ObReferenceObjectByHandle(EventData->EventHandle.Event, EVENT_MODIFY_STATE, ExEventObjectType, Irp->RequestorMode, &Object, NULL); + + if (!NT_SUCCESS(Status)) + { + /* invalid event handle */ + return STATUS_INVALID_PARAMETER; + } + } + else + { + /* user mode client can only pass an event or semaphore handle */ + return STATUS_INVALID_PARAMETER; + } + } + else + { + if (EventData->NotificationType != KSEVENTF_EVENT_OBJECT && + EventData->NotificationType != KSEVENTF_SEMAPHORE_OBJECT && + EventData->NotificationType != KSEVENTF_DPC && + EventData->NotificationType != KSEVENTF_WORKITEM && + EventData->NotificationType != KSEVENTF_KSWORKITEM) + { + /* invalid type requested */ + return STATUS_INVALID_PARAMETER; + } + } + + + /* calculate request size */ + Size = sizeof(KSEVENT_ENTRY) + FoundEventItem->ExtraEntryData; + + /* do we have an allocator */ + if (Allocator) + { + /* allocate event entry */ + Status = Allocator(Irp, Size, FALSE); + + if (!NT_SUCCESS(Status)) + { + /* failed */ + return Status; + } + + /* assume the caller put it there */ + EventEntry = KSEVENT_ENTRY_IRP_STORAGE(Irp); + + } + else + { + /* allocate it from nonpaged pool */ + EventEntry = ExAllocatePool(NonPagedPool, Size); + } + + if (!EventEntry) + { + /* not enough memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* zero event entry */ + RtlZeroMemory(EventEntry, Size); + + /* initialize event entry */ + EventEntry->EventData = EventData; + EventEntry->NotificationType = EventData->NotificationType; + EventEntry->EventItem = FoundEventItem; + EventEntry->EventSet = FoundEventSet; + EventEntry->FileObject = IoStack->FileObject; + + switch(EventEntry->NotificationType) + { + case KSEVENTF_EVENT_HANDLE: + EventEntry->Object = Object; + EventEntry->Reserved = 0; + break; + case KSEVENTF_SEMAPHORE_HANDLE: + EventEntry->Object = Object; + EventEntry->SemaphoreAdjustment = EventData->SemaphoreHandle.Adjustment; + EventEntry->Reserved = 0; + break; + case KSEVENTF_EVENT_OBJECT: + EventEntry->Object = EventData->EventObject.Event; + EventEntry->Reserved = EventData->EventObject.Increment; + break; + case KSEVENTF_SEMAPHORE_OBJECT: + EventEntry->Object = EventData->SemaphoreObject.Semaphore; + EventEntry->SemaphoreAdjustment = EventData->SemaphoreObject.Adjustment; + EventEntry->Reserved = EventData->SemaphoreObject.Increment; + break; + case KSEVENTF_DPC: + EventEntry->Object = EventData->Dpc.Dpc; + EventData->Dpc.ReferenceCount = 0; + break; + case KSEVENTF_WORKITEM: + EventEntry->Object = EventData->WorkItem.WorkQueueItem; + EventEntry->BufferItem = (PKSBUFFER_ITEM)UlongToPtr(EventData->WorkItem.WorkQueueType); + break; + case KSEVENTF_KSWORKITEM: + EventEntry->Object = EventData->KsWorkItem.KsWorkerObject; + EventEntry->DpcItem = (PKSDPC_ITEM)EventData->KsWorkItem.WorkQueueItem; + break; + default: + /* should not happen */ + ASSERT(0); + } + + if (FoundEventItem->AddHandler) + { + /* now add the event */ + Status = FoundEventItem->AddHandler(Irp, EventData, EventEntry); + + if (!NT_SUCCESS(Status)) + { + /* discard event entry */ + KsDiscardEvent(EventEntry); + } + } + else + { + /* setup context */ + Ctx.List = EventsList; + Ctx.EventEntry = EventEntry; + + /* add the event */ + (void)KspSynchronizedEventRoutine(EventsFlags, EventsLock, SyncAddEvent, &Ctx); + + Status = STATUS_SUCCESS; + } + + /* done */ + return Status; +} /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -86,12 +389,11 @@ KsEnableEvent( IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL, IN PVOID EventsLock OPTIONAL) { - UNIMPLEMENTED; - return STATUS_SUCCESS; + return KspEnableEvent(Irp, EventSetsCount, EventSet, EventsList, EventsFlags, EventsLock, NULL, 0); } /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -106,8 +408,7 @@ KsEnableEventWithAllocator( IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG EventItemSize OPTIONAL) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + return KspEnableEvent(Irp, EventSetsCount, EventSet, EventsList, EventsFlags, EventsLock, Allocator, EventItemSize); } BOOLEAN @@ -210,7 +511,7 @@ KsDisableEvent( } /* - @unimplemented + @implemented */ KSDDKAPI VOID @@ -218,7 +519,17 @@ NTAPI KsDiscardEvent( IN PKSEVENT_ENTRY EventEntry) { - //UNIMPLEMENTED; + /* sanity check */ + ASSERT(EventEntry->Object); + + if (EventEntry->NotificationType == KSEVENTF_SEMAPHORE_HANDLE || EventEntry->NotificationType == KSEVENTF_EVENT_HANDLE) + { + /* release object */ + ObDereferenceObject(EventEntry->Object); + } + + /* free event entry */ + ExFreePool(EventEntry); } @@ -295,33 +606,35 @@ KsGenerateEvent( { if (EntryEvent->NotificationType == KSEVENTF_EVENT_HANDLE || EntryEvent->NotificationType == KSEVENTF_EVENT_OBJECT) { - // signal event - KeSetEvent(EntryEvent->Object, 0, FALSE); + /* signal event */ + KeSetEvent(EntryEvent->Object, EntryEvent->Reserved, FALSE); } else if (EntryEvent->NotificationType == KSEVENTF_SEMAPHORE_HANDLE || EntryEvent->NotificationType == KSEVENTF_SEMAPHORE_OBJECT) { - // release semaphore - KeReleaseSemaphore(EntryEvent->Object, 0, EntryEvent->SemaphoreAdjustment, FALSE); + /* release semaphore */ + KeReleaseSemaphore(EntryEvent->Object, EntryEvent->Reserved, EntryEvent->SemaphoreAdjustment, FALSE); } else if (EntryEvent->NotificationType == KSEVENTF_DPC) { - // queue dpc + /* increment reference count to indicate dpc is pending */ + InterlockedIncrement((PLONG)&EntryEvent->EventData->Dpc.ReferenceCount); + /* queue dpc */ KeInsertQueueDpc((PRKDPC)EntryEvent->Object, NULL, NULL); } else if (EntryEvent->NotificationType == KSEVENTF_WORKITEM) { - // queue work item + /* queue work item */ ExQueueWorkItem((PWORK_QUEUE_ITEM)EntryEvent->Object, PtrToUlong(EntryEvent->BufferItem)); } else if (EntryEvent->NotificationType == KSEVENTF_KSWORKITEM) { - // queue work item of ks worker + /* queue work item of ks worker */ return KsQueueWorkItem((PKSWORKER)EntryEvent->Object, (PWORK_QUEUE_ITEM)EntryEvent->DpcItem); } else { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + /* unsupported type requested */ + return STATUS_INVALID_PARAMETER; } return STATUS_SUCCESS; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index 62a2094bba8..f7a7c7f44a8 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -41,7 +41,7 @@ protected: VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount); VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount); - VOID GeneratePositionEvents(IN ULONG OldCommonBufferOffset, IN ULONG NewCommonBufferOffset); + VOID GeneratePositionEvents(IN ULONGLONG OldOffset, IN ULONGLONG NewOffset); NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); @@ -261,6 +261,8 @@ PinWaveCyclicAddLoopedStreamEvent( Entry->bLoopedStreaming = TRUE; Entry->Position = Data->Position; + DPRINT1("Added event\n"); + // insert item (void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock); @@ -342,7 +344,7 @@ PinWaveCyclicAudioPosition( } else if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) { - Position->PlayOffset = Pin->m_Position.PlayOffset % Pin->m_Position.WriteOffset; + Position->PlayOffset = Pin->m_Position.PlayOffset; Position->WriteOffset = (ULONGLONG)Pin->m_IrpQueue->GetCurrentIrpOffset(); DPRINT("Play %lu Write %lu\n", Position->PlayOffset, Position->WriteOffset); } @@ -540,8 +542,8 @@ PinWaveCyclicDataFormat( VOID CPortPinWaveCyclic::GeneratePositionEvents( - IN ULONG OldCommonBufferOffset, - IN ULONG NewCommonBufferOffset) + IN ULONGLONG OldOffset, + IN ULONGLONG NewOffset) { PLIST_ENTRY Entry; PKSEVENT_ENTRY EventEntry; @@ -563,11 +565,15 @@ CPortPinWaveCyclic::GeneratePositionEvents( if (Context->bLoopedStreaming == TRUE) { - if (NewCommonBufferOffset > OldCommonBufferOffset) + if (NewOffset > OldOffset) { /* buffer progress no overlap */ - if (OldCommonBufferOffset < Context->Position && Context->Position <= NewCommonBufferOffset) + if (OldOffset < Context->Position && Context->Position <= NewOffset) { + /* when someone eventually fixes sprintf... */ + DPRINT("Generating event at OldOffset %I64u\n", OldOffset); + DPRINT("Context->Position %I64u\n", Context->Position); + DPRINT("NewOffset %I64u\n", NewOffset); /* generate event */ KsGenerateEvent(EventEntry); } @@ -575,8 +581,12 @@ CPortPinWaveCyclic::GeneratePositionEvents( else { /* buffer wrap-arround */ - if (OldCommonBufferOffset < Context->Position || NewCommonBufferOffset > Context->Position) + if (OldOffset < Context->Position || NewOffset > Context->Position) { + /* when someone eventually fixes sprintf... */ + DPRINT("Generating event at OldOffset %I64u\n", OldOffset); + DPRINT("Context->Position %I64u\n", Context->Position); + DPRINT("NewOffset %I64u\n", NewOffset); /* generate event */ KsGenerateEvent(EventEntry); } @@ -627,6 +637,12 @@ CPortPinWaveCyclic::UpdateCommonBuffer( BufferLength = Position - m_CommonBufferOffset; m_Position.PlayOffset += BytesToCopy; + + if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) + { + // normalize position + m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset; + } } } @@ -670,6 +686,13 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap( m_Position.PlayOffset += BytesToCopy; BufferLength = m_CommonBufferSize - m_CommonBufferOffset; + + if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) + { + // normalize position + m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset; + } + } if (Gap == Length) @@ -693,7 +716,7 @@ CPortPinWaveCyclic::RequestService() NTSTATUS Status; PUCHAR Buffer; ULONG BufferSize; - ULONG OldCommonBufferOffset; + ULONGLONG OldOffset, NewOffset; PC_ASSERT_IRQL(DISPATCH_LEVEL); @@ -706,7 +729,7 @@ CPortPinWaveCyclic::RequestService() Status = m_Stream->GetPosition(&Position); DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture); - OldCommonBufferOffset = m_CommonBufferOffset; + OldOffset = m_Position.PlayOffset; if (Position < m_CommonBufferOffset) { @@ -717,7 +740,9 @@ CPortPinWaveCyclic::RequestService() UpdateCommonBuffer(Position, m_FrameSize); } - GeneratePositionEvents(OldCommonBufferOffset, m_CommonBufferOffset); + NewOffset = m_Position.PlayOffset; + + GeneratePositionEvents(OldOffset, NewOffset); } NTSTATUS From 844a59129874b436522456bce079eba64494bb97 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 11 Nov 2009 10:53:52 +0000 Subject: [PATCH 021/140] - Fix problem with ASSERT & ASSERTMSG when compiled with g++ svn path=/trunk/; revision=44101 --- reactos/include/ddk/winddk.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/include/ddk/winddk.h b/reactos/include/ddk/winddk.h index 6ea3a23ead7..620a8a17eba 100644 --- a/reactos/include/ddk/winddk.h +++ b/reactos/include/ddk/winddk.h @@ -5832,11 +5832,11 @@ KeAcquireSpinLockRaiseToDpc( #define ASSERT(exp) \ (VOID)((!(exp)) ? \ - RtlAssert( #exp, __FILE__, __LINE__, NULL ), FALSE : TRUE) + RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, NULL ), FALSE : TRUE) #define ASSERTMSG(msg, exp) \ (VOID)((!(exp)) ? \ - RtlAssert( #exp, __FILE__, __LINE__, msg ), FALSE : TRUE) + RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, msg ), FALSE : TRUE) #define RTL_SOFT_ASSERT(exp) \ (VOID)((!(exp)) ? \ From 42f5d69bb490ae89225788a3b32f22d3d0423b69 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Wed, 11 Nov 2009 11:11:58 +0000 Subject: [PATCH 022/140] More _CRTIMP love for non-ANSI symbols svn path=/trunk/; revision=44102 --- reactos/include/crt/stdlib.h | 18 +++++++++--------- reactos/include/crt/wctype.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/reactos/include/crt/stdlib.h b/reactos/include/crt/stdlib.h index d6e92676c91..f931a4c7b54 100644 --- a/reactos/include/crt/stdlib.h +++ b/reactos/include/crt/stdlib.h @@ -526,15 +526,15 @@ extern "C" { #define sys_errlist _sys_errlist #define sys_nerr _sys_nerr #define environ _environ - char *__cdecl ecvt(double _Val,int _NumOfDigits,int *_PtDec,int *_PtSign); - char *__cdecl fcvt(double _Val,int _NumOfDec,int *_PtDec,int *_PtSign); - char *__cdecl gcvt(double _Val,int _NumOfDigits,char *_DstBuf); - char *__cdecl itoa(int _Val,char *_DstBuf,int _Radix); - char *__cdecl ltoa(long _Val,char *_DstBuf,int _Radix); - int __cdecl putenv(const char *_EnvString); - void __cdecl swab(char *_Buf1,char *_Buf2,int _SizeInBytes); - char *__cdecl ultoa(unsigned long _Val,char *_Dstbuf,int _Radix); - onexit_t __cdecl onexit(onexit_t _Func); + _CRTIMP char *__cdecl ecvt(double _Val,int _NumOfDigits,int *_PtDec,int *_PtSign); + _CRTIMP char *__cdecl fcvt(double _Val,int _NumOfDec,int *_PtDec,int *_PtSign); + _CRTIMP char *__cdecl gcvt(double _Val,int _NumOfDigits,char *_DstBuf); + _CRTIMP char *__cdecl itoa(int _Val,char *_DstBuf,int _Radix); + _CRTIMP char *__cdecl ltoa(long _Val,char *_DstBuf,int _Radix); + _CRTIMP int __cdecl putenv(const char *_EnvString); + _CRTIMP void __cdecl swab(char *_Buf1,char *_Buf2,int _SizeInBytes); + _CRTIMP char *__cdecl ultoa(unsigned long _Val,char *_Dstbuf,int _Radix); + _CRTIMP onexit_t __cdecl onexit(onexit_t _Func); #endif #endif diff --git a/reactos/include/crt/wctype.h b/reactos/include/crt/wctype.h index dc903b3236f..f50582093e6 100644 --- a/reactos/include/crt/wctype.h +++ b/reactos/include/crt/wctype.h @@ -122,7 +122,7 @@ extern "C" { _CRTIMP int __cdecl __iswcsym(wint_t); int __cdecl is_wctype(wint_t,wctype_t); #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || !defined (NO_OLDNAMES) -int __cdecl iswblank(wint_t _C); + _CRTIMP int __cdecl iswblank(wint_t _C); #endif #endif From 8667b162b13b4fb6f68e1a43e5fa43cb06dacf44 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Wed, 11 Nov 2009 11:12:55 +0000 Subject: [PATCH 023/140] modified regtests/crt/crt_regtest.rbuild Don't link msvcrt twice, bad things happen modified tests/dirdlg/dirdlg.rbuild modified winetests/msvcrt/msvcrt.rbuild More oldnames hacks modified tests/tcpsvr/tcpsvr.c Don't use close on sockets, use closesocket svn path=/trunk/; revision=44103 --- rostests/regtests/crt/crt_regtest.rbuild | 1 - rostests/tests/dirdlg/dirdlg.rbuild | 4 ++++ rostests/tests/tcpsvr/tcpsvr.c | 2 +- rostests/winetests/msvcrt/msvcrt.rbuild | 15 ++++++++++++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/rostests/regtests/crt/crt_regtest.rbuild b/rostests/regtests/crt/crt_regtest.rbuild index d4956a26398..4b297d5b1b8 100644 --- a/rostests/regtests/crt/crt_regtest.rbuild +++ b/rostests/regtests/crt/crt_regtest.rbuild @@ -4,7 +4,6 @@ . wine - msvcrt iofuncs.c testlist.c time.c diff --git a/rostests/tests/dirdlg/dirdlg.rbuild b/rostests/tests/dirdlg/dirdlg.rbuild index fd90b46d498..4b53898af3a 100644 --- a/rostests/tests/dirdlg/dirdlg.rbuild +++ b/rostests/tests/dirdlg/dirdlg.rbuild @@ -1,5 +1,9 @@ . + + + _chdir + kernel32 user32 gdi32 diff --git a/rostests/tests/tcpsvr/tcpsvr.c b/rostests/tests/tcpsvr/tcpsvr.c index 8f1d6b8c13b..5915cf31126 100644 --- a/rostests/tests/tcpsvr/tcpsvr.c +++ b/rostests/tests/tcpsvr/tcpsvr.c @@ -130,7 +130,7 @@ int read_line(int newSd, char *line_to_return) { return ERROR; } else if (n==0) { printf(" connection closed by client\n"); - close(newSd); + closesocket(newSd); WSACleanup(); return ERROR; } diff --git a/rostests/winetests/msvcrt/msvcrt.rbuild b/rostests/winetests/msvcrt/msvcrt.rbuild index 85befd9335e..fd9918c6224 100644 --- a/rostests/winetests/msvcrt/msvcrt.rbuild +++ b/rostests/winetests/msvcrt/msvcrt.rbuild @@ -6,8 +6,21 @@ include/reactos/wine/msvcrt + + + _open + _close + _tell + _unlink + _fdopen + _lseek + _read + _write + _mkdir + _rmdir + _putenv + kernel32 - msvcrt cpp.c data.c dir.c From aafb387b32d009713422d206a9365518d8f3a8da Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Wed, 11 Nov 2009 12:51:03 +0000 Subject: [PATCH 024/140] [12:14] kjk_hyperion: i dont understand where msvcrt is linked twice in crt_regtest ? [12:14] Usurp: that's right, you don't understand svn path=/trunk/; revision=44104 --- .../applications/sysutils/utils/nts2w32err/nts2w32err.rbuild | 3 +-- rosapps/applications/sysutils/utils/objdir/objdir.rbuild | 2 +- rosapps/applications/sysutils/utils/partinfo/partinfo.rbuild | 3 +-- rosapps/applications/sysutils/utils/stats/stats.rbuild | 2 +- rosapps/applications/sysutils/utils/tickcount/tickcount.rbuild | 2 +- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/rosapps/applications/sysutils/utils/nts2w32err/nts2w32err.rbuild b/rosapps/applications/sysutils/utils/nts2w32err/nts2w32err.rbuild index 00887d9a697..c7dd94c0c00 100644 --- a/rosapps/applications/sysutils/utils/nts2w32err/nts2w32err.rbuild +++ b/rosapps/applications/sysutils/utils/nts2w32err/nts2w32err.rbuild @@ -1,6 +1,5 @@ - msvcrt kernel32 ntdll nts2w32err.c - \ No newline at end of file + diff --git a/rosapps/applications/sysutils/utils/objdir/objdir.rbuild b/rosapps/applications/sysutils/utils/objdir/objdir.rbuild index b4c78b78f32..027e53803fd 100644 --- a/rosapps/applications/sysutils/utils/objdir/objdir.rbuild +++ b/rosapps/applications/sysutils/utils/objdir/objdir.rbuild @@ -3,4 +3,4 @@ kernel32 ntdll objdir.c - \ No newline at end of file + diff --git a/rosapps/applications/sysutils/utils/partinfo/partinfo.rbuild b/rosapps/applications/sysutils/utils/partinfo/partinfo.rbuild index d4149e8abb3..5ad98287b91 100644 --- a/rosapps/applications/sysutils/utils/partinfo/partinfo.rbuild +++ b/rosapps/applications/sysutils/utils/partinfo/partinfo.rbuild @@ -1,6 +1,5 @@ - msvcrt kernel32 ntdll partinfo.c - \ No newline at end of file + diff --git a/rosapps/applications/sysutils/utils/stats/stats.rbuild b/rosapps/applications/sysutils/utils/stats/stats.rbuild index f18059d921b..5e6400f911a 100644 --- a/rosapps/applications/sysutils/utils/stats/stats.rbuild +++ b/rosapps/applications/sysutils/utils/stats/stats.rbuild @@ -2,4 +2,4 @@ kernel32 ntdll stats.c - \ No newline at end of file + diff --git a/rosapps/applications/sysutils/utils/tickcount/tickcount.rbuild b/rosapps/applications/sysutils/utils/tickcount/tickcount.rbuild index 9d35ae0d6fc..49ce73b11d0 100644 --- a/rosapps/applications/sysutils/utils/tickcount/tickcount.rbuild +++ b/rosapps/applications/sysutils/utils/tickcount/tickcount.rbuild @@ -2,4 +2,4 @@ kernel32 ntdll tickcount.c - \ No newline at end of file + From 94d60cdacc708df2af097e5e8d32dcc632ccf34b Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Wed, 11 Nov 2009 13:02:13 +0000 Subject: [PATCH 025/140] forgot that one svn path=/trunk/; revision=44105 --- rosapps/applications/sysutils/utils/objdir/objdir.rbuild | 1 - 1 file changed, 1 deletion(-) diff --git a/rosapps/applications/sysutils/utils/objdir/objdir.rbuild b/rosapps/applications/sysutils/utils/objdir/objdir.rbuild index 027e53803fd..b292bdbe943 100644 --- a/rosapps/applications/sysutils/utils/objdir/objdir.rbuild +++ b/rosapps/applications/sysutils/utils/objdir/objdir.rbuild @@ -1,5 +1,4 @@ - msvcrt kernel32 ntdll objdir.c From effa38586cebf2b4c9348767bb77baa2fda99afa Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 11 Nov 2009 18:19:42 +0000 Subject: [PATCH 026/140] [rosapps] - Avoid old crt names usage, by Caemyr/kjk_hyperion. svn path=/trunk/; revision=44107 --- rosapps/applications/cmdutils/touch/touch.c | 24 +++++++++---------- .../applications/net/ncftp/libncftp/open.c | 4 ++-- .../applications/net/ncftp/ncftp/bookmark.c | 4 ++-- rosapps/applications/net/ncftp/ncftp/cmds.c | 2 +- .../applications/net/ncftp/ncftp/getline.c | 4 ++-- rosapps/applications/net/ncftp/ncftp/preffw.c | 2 +- rosapps/applications/net/ncftp/ncftp/readln.c | 2 +- rosapps/applications/net/ncftp/ncftp/spool.c | 2 +- rosapps/applications/net/ncftp/ncftp/trace.c | 2 +- .../sysutils/utils/binpatch/patch.c | 4 ++-- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/rosapps/applications/cmdutils/touch/touch.c b/rosapps/applications/cmdutils/touch/touch.c index 80a99c4a29c..257eaeac176 100644 --- a/rosapps/applications/cmdutils/touch/touch.c +++ b/rosapps/applications/cmdutils/touch/touch.c @@ -146,9 +146,9 @@ main(int argc, char *argv[]) if (stat(*argv, &sb)) { if (!cflag) { /* Create the file. */ - fd = open(*argv, + fd = _open(*argv, O_WRONLY | O_CREAT, DEFFILEMODE); - if (fd == -1 || fstat(fd, &sb) || close(fd)) { + if (fd == -1 || fstat(fd, &sb) || _close(fd)) { rval = 1; warn("%s", *argv); continue; @@ -300,37 +300,37 @@ rw(char *fname, struct stat *sbp, int force) } needed_chmod = rval = 0; - if ((fd = open(fname, O_RDWR, 0)) == -1) { - if (!force || chmod(fname, DEFFILEMODE)) + if ((fd = _open(fname, O_RDWR, 0)) == -1) { + if (!force || _chmod(fname, DEFFILEMODE)) goto err; - if ((fd = open(fname, O_RDWR, 0)) == -1) + if ((fd = _open(fname, O_RDWR, 0)) == -1) goto err; needed_chmod = 1; } if (sbp->st_size != 0) { - if (read(fd, &byte, sizeof(byte)) != sizeof(byte)) + if (_read(fd, &byte, sizeof(byte)) != sizeof(byte)) goto err; - if (lseek(fd, (off_t)0, SEEK_SET) == -1) + if (_lseek(fd, (off_t)0, SEEK_SET) == -1) goto err; - if (write(fd, &byte, sizeof(byte)) != sizeof(byte)) + if (_write(fd, &byte, sizeof(byte)) != sizeof(byte)) goto err; } else { - if (write(fd, &byte, sizeof(byte)) != sizeof(byte)) { + if (_write(fd, &byte, sizeof(byte)) != sizeof(byte)) { err: rval = 1; warn("%s", fname); /* } else if (ftruncate(fd, (off_t)0)) {*/ - } else if (chsize(fd, (off_t)0)) { + } else if (_chsize(fd, (off_t)0)) { rval = 1; warn("%s: file modified", fname); } } - if (close(fd) && rval != 1) { + if (_close(fd) && rval != 1) { rval = 1; warn("%s", fname); } - if (needed_chmod && chmod(fname, sbp->st_mode) && rval != 1) { + if (needed_chmod && _chmod(fname, sbp->st_mode) && rval != 1) { rval = 1; warn("%s: permissions modified", fname); } diff --git a/rosapps/applications/net/ncftp/libncftp/open.c b/rosapps/applications/net/ncftp/libncftp/open.c index 7c247633fdb..f3854edd5fc 100644 --- a/rosapps/applications/net/ncftp/libncftp/open.c +++ b/rosapps/applications/net/ncftp/libncftp/open.c @@ -1075,14 +1075,14 @@ FTPRebuildConnectionInfo(const FTPLIPtr lip, const FTPCIPtr cip) /* Reattach the FILE pointers for use with the Std I/O library * routines. */ - if ((cip->cin = fdopen(cip->ctrlSocketR, "r")) == NULL) { + if ((cip->cin = _fdopen(cip->ctrlSocketR, "r")) == NULL) { cip->errNo = kErrFdopenR; cip->ctrlSocketR = kClosedFileDescriptor; cip->ctrlSocketW = kClosedFileDescriptor; return (kErrFdopenR); } - if ((cip->cout = fdopen(cip->ctrlSocketW, "w")) == NULL) { + if ((cip->cout = _fdopen(cip->ctrlSocketW, "w")) == NULL) { CloseFile(&cip->cin); cip->errNo = kErrFdopenW; cip->ctrlSocketR = kClosedFileDescriptor; diff --git a/rosapps/applications/net/ncftp/ncftp/bookmark.c b/rosapps/applications/net/ncftp/ncftp/bookmark.c index d616db0a771..e42eaee52e2 100644 --- a/rosapps/applications/net/ncftp/ncftp/bookmark.c +++ b/rosapps/applications/net/ncftp/ncftp/bookmark.c @@ -297,7 +297,7 @@ OpenBookmarkFile(int *numBookmarks0) return NULL; /* Okay to not have one yet. */ } - (void) chmod(pathName, 00600); + (void) _chmod(pathName, 00600); if (FGets(line, sizeof(line), fp) == NULL) { (void) fprintf(stderr, "%s: invalid format.\n", pathName); (void) fclose(fp); @@ -683,7 +683,7 @@ OpenTmpBookmarkFile(int nb) perror(pathName); return (NULL); } - (void) chmod(pathName, 00600); + (void) _chmod(pathName, 00600); if (nb > 0) { if (fprintf(outfp, "NcFTP bookmark-file version: %d\nNumber of bookmarks: %d\n", kBookmarkVersion, nb) < 0) { (void) fprintf(stderr, "Could not save bookmark.\n"); diff --git a/rosapps/applications/net/ncftp/ncftp/cmds.c b/rosapps/applications/net/ncftp/ncftp/cmds.c index 574c84bedcc..b8b8d300933 100644 --- a/rosapps/applications/net/ncftp/ncftp/cmds.c +++ b/rosapps/applications/net/ncftp/ncftp/cmds.c @@ -2540,7 +2540,7 @@ PageCmd(const int argc, const char **const argv, const CommandPtr cmdp, const Ar #endif for (i=1; i= 0) /* file exists */ + if (_access(buffer, 0) >= 0) /* file exists */ { printf("File %s already exists, overwrite? (Y)es, (N)o, (A)bort", buffer); do From 8e510a0ea280354309f845ee902c60bafdbf504e Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Wed, 11 Nov 2009 20:43:58 +0000 Subject: [PATCH 027/140] - Fix building of cmidriver - Required a few hacks, which were documented as //HACK svn path=/trunk/; revision=44113 --- .../wdm/audio/drivers/CMIDriver/adapter.cpp | 96 ++++++++++++++++++- .../wdm/audio/drivers/CMIDriver/adapter.hpp | 4 +- .../audio/drivers/CMIDriver/cmidriver.rbuild | 10 ++ .../wdm/audio/drivers/CMIDriver/common.cpp | 8 +- .../wdm/audio/drivers/CMIDriver/common.hpp | 29 +++++- .../wdm/audio/drivers/CMIDriver/mintopo.cpp | 4 +- .../wdm/audio/drivers/CMIDriver/mintopo.hpp | 25 ++++- .../audio/drivers/CMIDriver/mintopotables.hpp | 6 +- .../wdm/audio/drivers/CMIDriver/minwave.cpp | 8 +- .../wdm/audio/drivers/CMIDriver/minwave.hpp | 49 ++++++++-- .../audio/drivers/CMIDriver/minwavetables.hpp | 2 +- .../wdm/audio/drivers/CMIDriver/property.h | 6 +- 12 files changed, 211 insertions(+), 36 deletions(-) diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp index 7edf3a4602b..edf88bf746e 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.cpp @@ -31,6 +31,84 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //#pragma code_seg("PAGE") +const GUID KSNODETYPE_DAC = {0x507AE360L, 0xC554, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_ADC = {0x4D837FE0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_AGC = {0xE88C9BA0L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_LOUDNESS = {0x41887440L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_MUTE = {0x02B223C0L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_TONE = {0x7607E580L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_VOLUME = {0x3A5ACC00L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_PEAKMETER = {0xa085651e, 0x5f0d, 0x4b36, {0xa8, 0x69, 0xd1, 0x95, 0xd6, 0xab, 0x4b, 0x9e}}; +const GUID KSNODETYPE_MUX = {0x2CEAF780, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_STEREO_WIDE = {0xA9E69800L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_CHORUS = {0x20173F20L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_REVERB = {0xEF0328E0L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_SUPERMIX = {0xE573ADC0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_SUM = {0xDA441A60L, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_SRC = {0x9DB7B9E0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_3D_EFFECTS = {0x55515860L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; +const GUID KSNODETYPE_SPDIF_INTERFACE = {0x0605+0xDFF219E0, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KSNODETYPE_MICROPHONE = {0x0201+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KSNODETYPE_CD_PLAYER = {0x0703+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KSNODETYPE_LINE_CONNECTOR = {0x0603+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KSNODETYPE_ANALOG_CONNECTOR = {0x601+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KSNODETYPE_SPEAKER = {0x0301+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; + +const GUID KSPROPTYPESETID_General = {0x97E99BA0L, 0xBDEA, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; +const GUID GUID_NULL ={0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +const GUID KSCATEGORY_AUDIO = {0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; + + +const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; +const GUID KSDATAFORMAT_SPECIFIER_DSOUND = {0x518590a2L, 0xa184, 0x11d0, {0x85, 0x22, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3}}; +const GUID KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = {0x00000000L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +const GUID KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF = {0x00000092L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; + + +const GUID KSAUDFNAME_WAVE_VOLUME = {0x185FEDE5L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_WAVE_MUTE = {0x185FEDE6L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_MIC_VOLUME = {0x185FEDEDL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_MASTER_VOLUME = {0x185FEDE3L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_RECORDING_SOURCE = {0x185FEDEFL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_CD_VOLUME = {0x185FEDE9L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_CD_IN_VOLUME = {0x185FEDF3L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_MIC_IN_VOLUME = {0x185FEDF5L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_MICROPHONE_BOOST = {0x2bc31d6aL, 0x96e3, 0x11d2, {0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68}}; +const GUID KSAUDFNAME_CD_MUTE = {0x185FEDEAL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_LINE_MUTE = {0x185FEDECL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_MIC_MUTE = {0x185FEDEEL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_AUX_MUTE = {0x185FEDFDL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_MASTER_MUTE = {0x185FEDE4L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_RECORDING_CONTROL = {0x185FEDFAL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_VOLUME_CONTROL = {0x185FEDF7L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_LINE_IN_VOLUME = {0x185FEDF4L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; +const GUID KSAUDFNAME_AUX_VOLUME = {0x185FEDFCL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; + +const GUID KSPROPSETID_CMI = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFF}}; + + +const GUID CMINAME_IEC_5V = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF0}}; +const GUID CMINAME_IEC_OUT = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF1}}; +const GUID CMINAME_IEC_INVERSE = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF2}}; +const GUID CMINAME_IEC_MONITOR = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF3}}; +const GUID CMINAME_IEC_SELECT = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF5}}; +const GUID CMINAME_XCHG_FB = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF6}}; +const GUID CMINAME_BASS2LINE = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF7}}; +const GUID CMINAME_CENTER2LINE = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF8}}; +const GUID CMINAME_IEC_COPYRIGHT = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF9}}; +const GUID CMINAME_IEC_POLVALID = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFA}}; +const GUID CMINAME_IEC_LOOP = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFB}}; +const GUID CMINAME_REAR2LINE = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFC}}; +const GUID CMINAME_CENTER2MIC = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFD}}; +const GUID CMINAME_DAC = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF4}}; +const GUID PRODUCT_CM8738 = {0x9db14e9a, 0x7be7, 0x480d, {0xa2, 0xfa, 0x32, 0x93, 0x24, 0x89, 0xde, 0x9c}}; +const GUID COMPONENT_CM8738 = {0x9db14e9a, 0x7be7, 0x480d, {0xa2, 0xfa, 0x32, 0x93, 0x24, 0x89, 0xde, 0x9d}}; +const GUID MANUFACTURER_CM8738 = {0x9db14e9a, 0x7be7, 0x480d, {0xa2, 0xfa, 0x32, 0x93, 0x24, 0x89, 0xde, 0x9e}}; + NTSTATUS InstallSubdevice( PDEVICE_OBJECT DeviceObject, @@ -451,8 +529,24 @@ DriverEntry( return ntStatus; } + +#ifdef _MSC_VER + #pragma code_seg() int __cdecl _purecall (void) { - return 0; + return 0; } + +#else + +extern "C" { +void __cxa_pure_virtual() + { + // put error handling here + + DbgBreakPoint(); + + } +} +#endif diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp index c457dc79a14..4f86166eb59 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp @@ -38,7 +38,7 @@ const ULONG MAX_MINIPORTS = 3; const ULONG MAX_MINIPORTS = 2; #endif -extern NTSTATUS CreateMiniportWaveCMI +extern HRESULT NTAPI CreateMiniportWaveCMI ( OUT PUNKNOWN * Unknown, IN REFCLSID, @@ -46,7 +46,7 @@ extern NTSTATUS CreateMiniportWaveCMI IN POOL_TYPE PoolType ); -extern NTSTATUS CreateMiniportTopologyCMI +extern HRESULT NTAPI CreateMiniportTopologyCMI ( OUT PUNKNOWN * Unknown, IN REFCLSID, diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/cmidriver.rbuild b/reactos/drivers/wdm/audio/drivers/CMIDriver/cmidriver.rbuild index 82b9dc34dd3..7e00b457a13 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/cmidriver.rbuild +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/cmidriver.rbuild @@ -1,6 +1,16 @@ + + + -fno-exceptions + -fno-rtti + + + + /GR- + + . ntoskrnl portcls diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/common.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/common.cpp index 27bbfc0e369..260f51d62e2 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/common.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/common.cpp @@ -36,10 +36,10 @@ NewCMIAdapter( PUNKNOWN UnknownOuter, POOL_TYPE PoolType) { -#if 0 +#if 1 //PAGED_CODE(); DBGPRINT(("NewCMIAdapter()")); - //ASSERT (Unknown); + ASSERT (Unknown); #endif STD_CREATE_BODY_(CCMIAdapter, Unknown, UnknownOuter, PoolType, PCMIADAPTER); } @@ -129,7 +129,7 @@ CCMIAdapter::~CCMIAdapter() } } -STDMETHODIMP_(NTSTATUS) CCMIAdapter::NonDelegatingQueryInterface(REFIID Interface, PVOID* Object) +STDMETHODIMP_(NTSTATUS) CCMIAdapter::QueryInterface(REFIID Interface, PVOID* Object) { //PAGED_CODE(); @@ -449,7 +449,7 @@ STDMETHODIMP_(void) CCMIAdapter::clearMixerBit(UInt8 index, UInt8 flag) writeMixer(index, readMixer(index) & ~flag); } -NTSTATUS CCMIAdapter::InterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID DynamicContext) +NTSTATUS NTAPI CCMIAdapter::InterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID DynamicContext) { UInt32 status, mask = 0; diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/common.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/common.hpp index 3502662176e..594838151ab 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/common.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/common.hpp @@ -41,8 +41,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "cmireg.hpp" class CCMIAdapter : public ICMIAdapter, - public IAdapterPowerManagement, - public CUnknown + public IAdapterPowerManagement { private: PDEVICE_OBJECT DeviceObject; @@ -56,8 +55,25 @@ private: void resetController(); public: - DECLARE_STD_UNKNOWN(); - DEFINE_STD_CONSTRUCTOR(CCMIAdapter); + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + + CCMIAdapter(IUnknown *OuterUnknown){} ~CCMIAdapter(); IMP_IAdapterPowerManagement; @@ -88,7 +104,7 @@ public: STDMETHODIMP_(void) resetMixer(); - static NTSTATUS InterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID StaticContext); + static NTSTATUS NTAPI InterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID StaticContext); STDMETHODIMP_(PCMI8738Info) getCMI8738Info(void) { @@ -105,6 +121,9 @@ public: }; friend NTSTATUS NewCCMIAdapter(PCMIADAPTER* OutCMIAdapter, PRESOURCELIST ResourceList); + + LONG m_Ref; + }; NTSTATUS NewCMIAdapter(PUNKNOWN* Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType); diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp index 364e508cf2c..7ced5096ce1 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp @@ -33,14 +33,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma code_seg("PAGE") -NTSTATUS CreateMiniportTopologyCMI(PUNKNOWN* Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType) +HRESULT NTAPI CreateMiniportTopologyCMI(PUNKNOWN* Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType) { //PAGED_CODE(); //ASSERT(Unknown); STD_CREATE_BODY_(CCMITopology,Unknown,UnknownOuter,PoolType,PMINIPORTTOPOLOGY); } -STDMETHODIMP CCMITopology::NonDelegatingQueryInterface(REFIID Interface, PVOID* Object) +STDMETHODIMP CCMITopology::QueryInterface(REFIID Interface, PVOID* Object) { //PAGED_CODE(); //ASSERT(Object); diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.hpp index 3ce6f1b2eb7..5a4628ffc54 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.hpp @@ -31,8 +31,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "common.hpp" #include "property.h" -class CCMITopology : public ICMITopology, - public CUnknown +class CCMITopology : public ICMITopology { private: PCMIADAPTER CMIAdapter; // Adapter common object. @@ -45,8 +44,24 @@ private: NTSTATUS ProcessResources(PRESOURCELIST ResourceList); public: - DECLARE_STD_UNKNOWN(); - DEFINE_STD_CONSTRUCTOR(CCMITopology); + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + CCMITopology(IUnknown * OuterUnknown){} ~CCMITopology(); STDMETHODIMP_(NTSTATUS) loadMixerSettingsFromRegistry(); STDMETHODIMP_(NTSTATUS) storeMixerSettingsToRegistry(); @@ -88,6 +103,8 @@ public: friend NTSTATUS NTAPI PropertyHandler_Mux(PPCPROPERTY_REQUEST PropertyRequest); static NTSTATUS NTAPI EventHandler(PPCEVENT_REQUEST EventRequest); + + LONG m_Ref; }; #endif //_MINTOPO_HPP_ diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp index 922643ad334..96656d682f4 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp @@ -30,12 +30,14 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "mintopo.hpp" +#if 0 #ifndef STATIC_KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF #define STATIC_KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF\ DEFINE_WAVEFORMATEX_GUID(WAVE_FORMAT_DOLBY_AC3_SPDIF) DEFINE_GUIDSTRUCT("00000092-0000-0010-8000-00aa00389b71", KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF); #define KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF DEFINE_GUIDNAMED(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) #endif +#endif NTSTATUS NTAPI PropertyHandler_Level(PPCPROPERTY_REQUEST PropertyRequest); NTSTATUS NTAPI PropertyHandler_CpuResources(PPCPROPERTY_REQUEST PropertyRequest); @@ -352,13 +354,13 @@ static PCPROPERTY_ITEM PropertiesFilter[] = (PCPFNPROPERTY_HANDLER)PropertyHandler_ComponentId }, { - &KSPROPSETID_CMI, + &GUID_NULL,//&KSPROPSETID_CMI, //HACK KSPROPERTY_CMI_GET, KSPROPERTY_TYPE_GET, (PCPFNPROPERTY_HANDLER)PropertyHandler_Private }, { - &KSPROPSETID_CMI, + &GUID_NULL,//&KSPROPSETID_CMI, //HACK KSPROPERTY_CMI_SET, KSPROPERTY_TYPE_SET, (PCPFNPROPERTY_HANDLER)PropertyHandler_Private diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp index 36bdef570e2..ddc9b588d19 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp @@ -31,7 +31,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma code_seg("PAGE") -NTSTATUS CreateMiniportWaveCMI(PUNKNOWN *Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType) +HRESULT NTAPI CreateMiniportWaveCMI(PUNKNOWN *Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType) { //PAGED_CODE(); //ASSERT(Unknown); @@ -77,7 +77,7 @@ NTSTATUS CMiniportWaveCMI::newDMAChannel(PDMACHANNEL *dmaChannel, UInt32 bufferL #endif //generic crap -STDMETHODIMP CMiniportWaveCMI::NonDelegatingQueryInterface(REFIID Interface, PVOID *Object) +STDMETHODIMP CMiniportWaveCMI::QueryInterface(REFIID Interface, PVOID *Object) { //PAGED_CODE(); //ASSERT(Object); @@ -482,7 +482,7 @@ STDMETHODIMP CMiniportWaveCMI::DataRangeIntersection(ULONG PinId, PKSDATARANGE C } - if (!IsEqualGUIDAligned(ClientDataRange->SubFormat, KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) + if (!IsEqualGUIDAligned(ClientDataRange->SubFormat, GUID_NULL)//KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) //HACK && !IsEqualGUIDAligned(ClientDataRange->SubFormat, KSDATAFORMAT_SUBTYPE_WILDCARD)) { // check for Vista isAC3Pin = false; @@ -1215,7 +1215,7 @@ CMiniportWaveStreamCMI::~CMiniportWaveStreamCMI(void) } } -STDMETHODIMP CMiniportWaveStreamCMI::NonDelegatingQueryInterface(REFIID Interface, PVOID *Object) +STDMETHODIMP CMiniportWaveStreamCMI::QueryInterface(REFIID Interface, PVOID *Object) { //PAGED_CODE(); //ASSERT(Object); diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.hpp index 3b5f1d165df..7686c53390d 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.hpp @@ -41,8 +41,7 @@ class CMiniportWaveCMI: #else public IMiniportWaveCyclic, #endif - public IMiniportWaveCMI, - public CUnknown + public IMiniportWaveCMI { private: PCMIADAPTER CMIAdapter; // Adapter common object. @@ -56,7 +55,7 @@ private: CMI8738Info *cm; UInt32 requestedChannelCount; UInt32 requestedChannelMask; - + LONG m_Ref; CMiniportWaveStreamCMI *stream[3]; bool isStreamRunning[3]; @@ -72,8 +71,24 @@ private: NTSTATUS loadChannelConfigFromRegistry(); NTSTATUS storeChannelConfigToRegistry(); public: - DECLARE_STD_UNKNOWN(); - DEFINE_STD_CONSTRUCTOR(CMiniportWaveCMI); + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + CMiniportWaveCMI(IUnknown * OuterUnknown){} ~CMiniportWaveCMI(); #ifdef WAVERT IMP_IMiniportWaveRT; @@ -96,8 +111,7 @@ class CMiniportWaveStreamCMI: #else public IMiniportWaveCyclicStream, #endif - public IDrmAudioStream, - public CUnknown + public IDrmAudioStream { private: CMiniportWaveCMI *Miniport; @@ -119,6 +133,7 @@ private: UInt32 dmaSize; // size of the DMA buffer in frames, NOT in bytes UInt32 currentChannelCount, currentSampleRate, currentResolution; bool enableAC3Passthru, enableSPDIF; + LONG m_Ref; NTSTATUS prepareStream(); NTSTATUS setDACChannels(); @@ -126,8 +141,24 @@ private: NTSTATUS setupAC3Passthru(); public: - DECLARE_STD_UNKNOWN(); - DEFINE_STD_CONSTRUCTOR(CMiniportWaveStreamCMI); + STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); + STDMETHODIMP_(ULONG) AddRef() + { + InterlockedIncrement(&m_Ref); + return m_Ref; + } + STDMETHODIMP_(ULONG) Release() + { + InterlockedDecrement(&m_Ref); + + if (!m_Ref) + { + delete this; + return 0; + } + return m_Ref; + } + CMiniportWaveStreamCMI(IUnknown * OuterUnknown){} ~CMiniportWaveStreamCMI(); #ifdef WAVERT IMP_IMiniportWaveRTStream; diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp index 0c0326ca21c..e380a1ce2fc 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp @@ -65,7 +65,7 @@ static KSDATARANGE_AUDIO WavePinDataRangesAC3Stream[] = 0, 0, STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF), + STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),//STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF), //HACK STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) }, MAX_CHANNELS_AC3, diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/property.h b/reactos/drivers/wdm/audio/drivers/CMIDriver/property.h index 88e09691550..7e6593dfed2 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/property.h +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/property.h @@ -30,10 +30,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //GUID for the private property // {2B81CDBB-EE6C-4ECC-8AA5-9A188B023DFF} + #define STATIC_KSPROPSETID_CMI \ 0x2B81CDBB, 0xEE6C, 0x4ECC, 0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFF -DEFINE_GUIDSTRUCT("2B81CDBB-EE6C-4ECC-8AA5-9A188B023DFF", _STATIC_KSPROPSETID_CMI); -#define KSPROPSETID_CMI DEFINE_GUIDNAMED(_STATIC_KSPROPSETID_CMI) +DEFINE_GUIDSTRUCT("2B81CDBB-EE6C-4ECC-8AA5-9A188B023DFF", KSPROPSETID_CMI); +#define KSPROPSETID_CMI DEFINE_GUIDNAMED(KSPROPSETID_CMI) + //methods #define KSPROPERTY_CMI_GET 1 From c02b96254ead7a23309d7592aa9574815c3f7e07 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Wed, 11 Nov 2009 22:29:16 +0000 Subject: [PATCH 028/140] - Add inital support for PCI and ISA interrupts. - Use different register allocation to be more efficient on certain systems. - Add tables and initial code for Lazy IRQL support. svn path=/trunk/; revision=44115 --- reactos/hal/halx86/generic/irq.S | 388 ++++++++++++++---- .../ntoskrnl/include/internal/i386/asmmacro.S | 34 ++ 2 files changed, 333 insertions(+), 89 deletions(-) diff --git a/reactos/hal/halx86/generic/irq.S b/reactos/hal/halx86/generic/irq.S index 72204991d18..ae78a4b86e7 100644 --- a/reactos/hal/halx86/generic/irq.S +++ b/reactos/hal/halx86/generic/irq.S @@ -69,25 +69,73 @@ KiI8259MaskTable: .long 0xFFFFFFFB /* IRQL 30 */ .long 0xFFFFFFFB /* IRQL 31 */ -HalpSysIntHandler: -.rept 7 +FindHigherIrqlMask: + .long 0xFFFFFFFE /* IRQL 0 */ + .long 0xFFFFFFFC /* IRQL 1 */ + .long 0xFFFFFFF8 /* IRQL 2 */ + .long 0xFFFFFFF0 /* IRQL 3 */ + .long 0x7FFFFF0 /* IRQL 4 */ + .long 0x3FFFFF0 /* IRQL 5 */ + .long 0x1FFFFF0 /* IRQL 6 */ + .long 0x0FFFFF0 /* IRQL 7 */ + .long 0x7FFFF0 /* IRQL 8 */ + .long 0x3FFFF0 /* IRQL 9 */ + .long 0x1FFFF0 /* IRQL 10 */ + .long 0x0FFFF0 /* IRQL 11 */ + .long 0x7FFF0 /* IRQL 12 */ + .long 0x3FFF0 /* IRQL 13 */ + .long 0x1FFF0 /* IRQL 14 */ + .long 0x0FFF0 /* IRQL 15 */ + .long 0x7FF0 /* IRQL 16 */ + .long 0x3FF0 /* IRQL 17 */ + .long 0x1FF0 /* IRQL 18 */ + .long 0x1FF0 /* IRQL 19 */ + .long 0x17F0 /* IRQL 20 */ + .long 0x13F0 /* IRQL 21 */ + .long 0x11F0 /* IRQL 22 */ + .long 0x10F0 /* IRQL 23 */ + .long 0x1070 /* IRQL 24 */ + .long 0x1030 /* IRQL 25 */ + .long 0x1010 /* IRQL 26 */ + .long 0x10 /* IRQL 27 */ + .long 0 /* IRQL 28 */ + .long 0 /* IRQL 29 */ + .long 0 /* IRQL 30 */ + .long 0 /* IRQL 31 */ + +HalpSpecialDismissTable: + .rept 7 .long GenericIRQ /* IRQ 0-7 */ -.endr + .endr .long IRQ7 /* IRQ 7 */ -.rept 7 - .long GenericIRQ /* IRQ 8-15 */ -.endr + .rept 5 + .long GenericIRQ /* IRQ 8-12 */ + .endr + .long IRQ13 /* IRQ 13 */ + .long GenericIRQ /* IRQ 14 */ .long IRQ15 /* IRQ 15 */ -.rept 20 + .rept 20 .long GenericIRQ /* IRQ 16-35 */ -.endr + .endr #if DBG .rept 172 .long InvalidIRQ /* IRQ 36-207 */ .endr #endif -SoftIntByteTable: +HalpSpecialDismissLevelTable: + .rept 7 + .long GenericIRQLevel /* IRQ 0-7 */ + .endr + .long IRQ7Level /* IRQ 7 */ + .rept 5 + .long GenericIRQLevel /* IRQ 8-12 */ + .endr + .long IRQ13Level /* IRQ 13 */ + .long GenericIRQLevel /* IRQ 14 */ + .long IRQ15Level /* IRQ 15 */ + +SWInterruptLookUpTable: .byte PASSIVE_LEVEL /* IRR 0 */ .byte PASSIVE_LEVEL /* IRR 1 */ .byte APC_LEVEL /* IRR 2 */ @@ -97,12 +145,12 @@ SoftIntByteTable: .byte DISPATCH_LEVEL /* IRR 6 */ .byte DISPATCH_LEVEL /* IRR 7 */ -SoftIntHandlerTable: +SWInterruptHandlerTable: .long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */ .long _HalpApcInterrupt /* APC_LEVEL */ .long _HalpDispatchInterrupt /* DISPATCH_LEVEL */ -SoftIntHandlerTable2: +SWInterruptHandlerTable2: .long _KiUnexpectedInterrupt /* PASSIVE_LEVEL */ .long _HalpApcInterrupt2ndEntry /* APC_LEVEL */ .long _HalpDispatchInterrupt2ndEntry /* DISPATCH_LEVEL */ @@ -112,6 +160,39 @@ _UnhandledMsg: /* FUNCTIONS *****************************************************************/ +/* HAL interrupt handlers */ +GENERATE_HAL_INT_HANDLERS + +.globl _HalpHardwareInterruptLevel +.func HalpHardwareInterruptLevel +_HalpHardwareInterruptLevel: + + /* Get IRQL and check for pending interrupts */ + mov eax, PCR[KPCR_IRQL] + mov ecx, PCR[KPCR_IRR] + and ecx, FindHigherIrqlMask[eax*4] + jz NothingHardware + + /* Check the active IRR */ + test dword ptr PCR[KPCR_IRR_ACTIVE], 0xFFFFFFF0 + jnz NothingHardware + + /* Check for pending software interrupts */ + mov eax, ecx + bsr ecx, eax + mov eax, 1 + shl eax, cl + + /* Clear IRR */ + xor PCR[KPCR_IRR], eax + + /* Now dispatch the interrupt */ + call SWInterruptHandlerTable[ecx*4] + +NothingHardware: + ret +.endfunc + .globl _HalpInitPICs@0 .func HalpInitPICs@0 _HalpInitPICs@0: @@ -150,7 +231,23 @@ InitLoop: cmp ax, 0 jnz InitLoop - /* Restore interrupts and return */ + /* Read EISA Edge/Level Register */ + mov edx, 0x4D1 + in al, dx + mov ah, al + dec edx + in al, dx + + /* Clear reserved bits and see if there's anything there */ + and eax, 0xDEF8 + cmp eax, 0xDEF8 + jz NoEisa + + /* FIXME */ + //UNHANDLED_PATH + +/* Restore interrupts and return */ +NoEisa: popf pop esi ret @@ -192,12 +289,12 @@ InitLoop: /* Get highest pending software interrupt and check if it's higher */ xor edx, edx - mov dl, SoftIntByteTable[eax] + mov dl, SWInterruptLookUpTable[eax] cmp dl, cl jbe AfterCall /* Call the pending interrupt */ - call SoftIntHandlerTable[edx*4] + call SWInterruptHandlerTable[edx*4] AfterCall: @@ -249,38 +346,53 @@ _HalEnableSystemInterrupt@12: cmp ecx, CLOCK2_LEVEL jnb Invalid - /* Get the current PCI Edge/Level control registers */ - mov edx, 0x4D1 - in al, dx - shl ax, 8 - mov edx, 0x4D0 - in al, dx - mov dx, 1 - shl dx, cl - and dx, 0xDEF8 +#if 0 + /* Is PCI IRQ Routing enabled? */ + cmp byte ptr _HalpIrqMiniportInitialized, 0 + jz NoMiniport - /* Check if this is a latched interrupt */ - cmp dword ptr [esp+12], 0 + /* UNHANDLED */ + UNHANDLED_PATH + +NoMiniport: + /* Check if this is an EISA IRQ */ + bt _HalpEisaIrqIgnore, ecx + jb IgnoredIrq + + /* Clear the EISA Edge/Level Control Register */ + btr _HalpEisaELCR, ecx + + /* Get the interrupt type */ + mov al, [esp+12] + cmp al, 0 jnz Latched - /* Use OR for edge interrupt */ - or ax, dx - jmp AfterMask + /* Check the register again */ + bt _HalpEisaELCR, ecx + jb Dismiss + + /* Check if the miniport is active */ + cmp byte ptr _HalpIrqMiniportInitialized, 0 + jz Dismiss + + /* Update the EISA Edge/Level Control Register */ + bts _HalpEisaELCR, ecx + +Dismiss: + /* Use the level hardware interrupt handler */ + mov dword ptr SWInterruptHandlerTableHardware[ecx*4], offset _HalpHardwareInterruptLevel + mov edx, HalpSpecialDismissLevelTable[ecx*4] + mov HalpSpecialDismissTable[ecx*4], edx + Latched: + /* Is PCI IRQ Routing enabled? */ + cmp byte ptr _HalpIrqMiniportInitialized, 0 + jz IgnoredIrq - /* Mask it out for level interrupt */ - not dx - and ax, dx - -AfterMask: - - /* Set the PCI Edge/Level control registers */ - mov edx, 0x4D0 - out dx, al - shr ax, 8 - mov edx, 0x4D1 - out dx, al - + /* UNHANDLED */ + UNHANDLED_PATH +#endif +IgnoredIrq: /* Calculate the new IDR */ mov eax, 1 shl eax, cl @@ -316,9 +428,10 @@ Invalid: _HalBeginSystemInterrupt@12: /* Convert to IRQ and call the handler */ - movzx ebx, byte ptr [esp+8] - sub ebx, PRIMARY_VECTOR_BASE - jmp HalpSysIntHandler[ebx*4] + xor ecx, ecx + mov cl, byte ptr [esp+8] + sub ecx, PRIMARY_VECTOR_BASE + jmp HalpSpecialDismissTable[ecx*4] IRQ15: /* This is IRQ 15, check if it's spurious */ @@ -330,6 +443,7 @@ IRQ15: jnz GenericIRQ /* Cascaded interrupt... dismiss it and return FALSE */ +CascadedInterrupt: mov al, 0x62 out 0x20, al mov eax, 0 @@ -348,15 +462,21 @@ IRQ7: mov eax, 0 ret 12 -GenericIRQ: - /* Return the current IRQL */ - mov eax, [esp+12] - mov ecx, PCR[KPCR_IRQL] - mov [eax], cl +IRQ13: + /* AT 80287 latch clear */ + xor al, al + out 0xF0, al - /* Set the new IRQL */ - movzx eax, byte ptr [esp+4] +GenericIRQ: + /* Get current and new IRQL */ + xor eax, eax + mov al, byte ptr [esp+4] + mov ebx, PCR[KPCR_IRQL] + + /* Set and save old */ mov PCR[KPCR_IRQL], eax + mov edx, [esp+12] + mov [edx], bl /* Set IRQ mask in the PIC */ mov eax, KiI8259MaskTable[eax*4] @@ -366,14 +486,18 @@ GenericIRQ: out 0xA1, al /* Check to which PIC the EOI was sent */ - mov eax, ebx + mov eax, ecx cmp eax, 8 jnb Pic1 /* Write mask to master PIC */ or al, 0x60 out 0x20, al - jmp DoneBegin + + /* Enable interrupts and return TRUE */ + sti + mov eax, 1 + ret 12 Pic1: /* Write mask to slave PIC */ @@ -382,9 +506,7 @@ Pic1: mov al, 0x62 out 0x20, al -DoneBegin: /* Enable interrupts and return TRUE */ - in al, 0x21 sti mov eax, 1 ret 12 @@ -397,12 +519,111 @@ InvalidIRQ: #endif .endfunc +IRQ15Level: + /* This is IRQ 15, check if it's spurious */ + mov al, 0xB + out 0xA0, al + jmp $+2 + in al, 0xA0 + test al, 0x80 + jnz GenericIRQLevel + jmp CascadedInterrupt + +IRQ7Level: + /* This is IRQ 7, check if it's spurious */ + mov al, 0xB + out 0x20, al + jmp $+2 + in al, 0x20 + test al, 0x80 + jnz GenericIRQLevel + + /* It is, return FALSE */ +SpuriousInterrupt: + mov eax, 0 + ret 12 + +IRQ13Level: + /* AT 80287 latch clear */ + xor al, al + out 0xF0, al + +GenericIRQLevel: + /* Save IRQL */ + xor eax, eax + mov al, [esp+4] + + /* Set IRQ mask in the PIC */ + mov eax, KiI8259MaskTable[eax*4] + or eax, PCR[KPCR_IDR] + out 0x21, al + shr eax, 8 + out 0xA1, al + + /* Compute new IRR */ + mov eax, ecx + mov ebx, 1 + add ecx, 4 + shl ebx, cl + or PCR[KPCR_IRR], ebx + + /* Get IRQLs */ + mov cl, [esp+4] + mov bl, PCR[KPCR_IRQL] + mov edx, [esp+12] + + /* Check to which PIC the EOI was sent */ + cmp eax, 8 + jnb Pic1Level + + /* Write mask to master PIC */ + or al, 0x60 + out 0x20, al + + /* Check for spurious */ + cmp cl, bl + jbe SpuriousInterrupt + + /* Write IRQL values */ + movzx ecx, cl + mov PCR[KPCR_IRQL], ecx + mov [edx], bl + + /* Enable interrupts and return TRUE */ + sti + mov eax, 1 + ret 12 + +Pic1Level: + /* Write mask to slave and master PIC */ + add al, 0x58 + out 0xA0, al + mov al, 0x62 + out 0x20, al + + /* Was this a lower interrupt? */ + cmp cl, bl + jbe SpuriousInterrupt + + /* Write IRQL values */ + movzx ecx, cl + mov PCR[KPCR_IRQL], ecx + mov [edx], bl + + /* Enable interrupts and return TRUE */ + sti + mov eax, 1 + ret 12 + .globl _HalEndSystemInterrupt@8 .func HalEndSystemInterrupt@8 _HalEndSystemInterrupt@8: - /* Get the IRQL and check if it's a software interrupt */ - movzx ecx, byte ptr [esp+4] + /* Read IRQL */ + xor ecx, ecx + mov cl, [esp+4] + + /* Check if it's a software interrupt */ cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL jbe SkipMask2 @@ -418,7 +639,7 @@ SkipMask2: /* Set IRQL and check if there are pending software interrupts */ mov PCR[KPCR_IRQL], ecx mov eax, PCR[KPCR_IRR] - mov al, SoftIntByteTable[eax] + mov al, SWInterruptLookUpTable[eax] cmp al, cl ja DoCall ret 8 @@ -427,7 +648,7 @@ DoCall: /* There are pending software interrupts, call their handlers */ add esp, 12 - jmp SoftIntHandlerTable2[eax*4] + jmp SWInterruptHandlerTable2[eax*4] .endfunc .globl @KfLowerIrql@4 @@ -435,19 +656,21 @@ DoCall: _@KfLowerIrql@4: @KfLowerIrql@4: - /* Save flags since we'll disable interrupts */ - pushf + /* Cleanup IRQL */ + and ecx, 0xFF /* Validate IRQL */ - movzx ecx, cl -#if DBG + #if DBG cmp cl, PCR[KPCR_IRQL] ja InvalidIrql -#endif + #endif + + /* Save flags since we'll disable interrupts */ + pushf + cli /* Disable interrupts and check if IRQL is below DISPATCH_LEVEL */ cmp dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL - cli jbe SkipMask /* Clear interrupt masks since there's a pending hardware interrupt */ @@ -462,7 +685,7 @@ SkipMask: /* Set the new IRQL and check if there's a pending software interrupt */ mov PCR[KPCR_IRQL], ecx mov eax, PCR[KPCR_IRR] - mov al, SoftIntByteTable[eax] + mov al, SWInterruptLookUpTable[eax] cmp al, cl ja DoCall3 @@ -487,7 +710,7 @@ InvalidIrql: DoCall3: /* There is, call it */ - call SoftIntHandlerTable[eax*4] + call SWInterruptHandlerTable[eax*4] /* Restore interrupts and return */ popf @@ -499,9 +722,9 @@ DoCall3: _@KfRaiseIrql@4: @KfRaiseIrql@4: - /* Get the IRQL */ - mov eax, PCR[KPCR_IRQL] + /* Get the IRQL */ movzx ecx, cl + mov eax, PCR[KPCR_IRQL] #if DBG /* Validate it */ @@ -521,7 +744,7 @@ _@KfRaiseIrql@4: cli /* Set the new IRQL */ - mov PCR[KPCR_IRQL], cl + mov PCR[KPCR_IRQL], ecx /* Mask the interrupts in the PIC */ mov eax, KiI8259MaskTable[ecx*4] @@ -536,7 +759,6 @@ _@KfRaiseIrql@4: ret SetIrql: - /* Set the IRQL and return */ mov PCR[KPCR_IRQL], ecx ret @@ -598,29 +820,17 @@ InvalidRaise: .func KeRaiseIrqlToSynchLevel@0 _KeRaiseIrqlToSynchLevel@0: - /* Disable interrupts */ - pushf - cli - - /* Mask out interrupts */ - mov eax, KiI8259MaskTable[SYNCH_LEVEL*4] - or eax, PCR[KPCR_IDR] - out 0x21, al - shr eax, 8 - out 0xA1, al - - /* Return the old IRQL, enable interrupts and set to SYNCH */ + /* Get the current IRQL */ mov eax, PCR[KPCR_IRQL] + + /* Set SYNCH_LEVEL */ mov dword ptr PCR[KPCR_IRQL], SYNCH_LEVEL - popf #if DBG - /* Validate raise */ + /* Make sure we were not higher then dispatch */ cmp eax, SYNCH_LEVEL ja InvalidSyRaise #endif - - /* Return */ ret #if DBG @@ -737,7 +947,7 @@ SoftwareInt: /* Check if there are pending software interrupts */ mov PCR[KPCR_IRQL], ecx mov eax, PCR[KPCR_IRR] - mov al, SoftIntByteTable[eax] + mov al, SWInterruptLookUpTable[eax] cmp al, cl ja DoCall2 ret 4 @@ -745,5 +955,5 @@ SoftwareInt: DoCall2: /* There are pending softwate interrupts, call their handlers */ add esp, 8 - jmp SoftIntHandlerTable2[eax*4] + jmp SWInterruptHandlerTable2[eax*4] .endfunc diff --git a/reactos/ntoskrnl/include/internal/i386/asmmacro.S b/reactos/ntoskrnl/include/internal/i386/asmmacro.S index fcc78c8ae19..e445ca46262 100644 --- a/reactos/ntoskrnl/include/internal/i386/asmmacro.S +++ b/reactos/ntoskrnl/include/internal/i386/asmmacro.S @@ -191,6 +191,40 @@ _KiUnexpectedInterrupt&Number: .endr .endm +// +// @name GENERATE_HAL_INT_HANDLER +// +// This macro creates a HAL hardware interrupt handler. +// +// @param None. +// +// @remark None. +// +.macro GENERATE_HAL_INT_HANDLER Number +.func HalpHardwareInterrupt&Number +_HalpHardwareInterrupt&Number: + int PRIMARY_VECTOR_BASE + Number + ret +.endfunc +.endm + +// +// @name GENERATE_HAL_INT_HANDLERS +// +// This macro creates the unexpected interrupt handlers. +// +// @param None. +// +// @remark None. +// +.macro GENERATE_HAL_INT_HANDLERS +.set i, 0 +.rept 16 + GENERATE_HAL_INT_HANDLER %i + .set i, i + 1 +.endr +.endm + // // @name INVALID_V86_OPCODE // From ba319b373fa7caac030a679ff9596a0f7f9455c9 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 12 Nov 2009 12:35:01 +0000 Subject: [PATCH 029/140] [Unused ReactOS setup] - Move duplicate code from LoadSetupData to a separate function - Fix a bug on line 1054 of the original file: SetupData.LangCount should be SetupData.KbLayoutCount (copy-paste mistake). This would have probably gone unnoticed if SetupData.LangCount > SetupData.KbLayoutCount due to other end of section checking. - Based on a patch from bug 4933. svn path=/trunk/; revision=44116 --- reactos/base/setup/reactos/reactos.c | 148 +++++++++------------------ 1 file changed, 49 insertions(+), 99 deletions(-) diff --git a/reactos/base/setup/reactos/reactos.c b/reactos/base/setup/reactos/reactos.c index 9704d275fcf..729592086b1 100644 --- a/reactos/base/setup/reactos/reactos.c +++ b/reactos/base/setup/reactos/reactos.c @@ -103,6 +103,8 @@ TCHAR abort_msg[512], abort_title[64]; HINSTANCE hInstance; BOOL isUnattend; +LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY gen,PINFCONTEXT context); + /* FUNCTIONS ****************************************************************/ static VOID @@ -995,13 +997,12 @@ void LoadSetupData() if (hTxtsetupSif != INVALID_HANDLE_VALUE) { // get language list - Count = SetupGetLineCount(hTxtsetupSif, _T("Language")); - if (Count > 0) + SetupData.LangCount = SetupGetLineCount(hTxtsetupSif, _T("Language")); + if (SetupData.LangCount > 0) { - SetupData.pLanguages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LANG) * Count); + SetupData.pLanguages = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LANG) * SetupData.LangCount); if (SetupData.pLanguages != NULL) { - SetupData.LangCount = Count; Count = 0; if (SetupFindFirstLine(hTxtsetupSif, _T("Language"), NULL, &InfContext)) { @@ -1020,19 +1021,18 @@ void LoadSetupData() &LineLength); ++Count; } - while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.LangCount); + while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.LangCount); } } } // get keyboard layout list - Count = SetupGetLineCount(hTxtsetupSif, _T("KeyboardLayout")); - if (Count > 0) + SetupData.KbLayoutCount = SetupGetLineCount(hTxtsetupSif, _T("KeyboardLayout")); + if (SetupData.KbLayoutCount > 0) { - SetupData.pKbLayouts = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KBLAYOUT) * Count); + SetupData.pKbLayouts = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KBLAYOUT) * SetupData.KbLayoutCount); if (SetupData.pKbLayouts != NULL) { - SetupData.KbLayoutCount = Count; Count = 0; if (SetupFindFirstLine(hTxtsetupSif, _T("KeyboardLayout"), NULL, &InfContext)) { @@ -1051,7 +1051,7 @@ void LoadSetupData() &LineLength); ++Count; } - while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.LangCount); + while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.KbLayoutCount); } } } @@ -1084,99 +1084,13 @@ void LoadSetupData() } // get computers list - Count = SetupGetLineCount(hTxtsetupSif, _T("Computer")); - if (Count > 0) - { - SetupData.pComputers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * Count); - if (SetupData.pComputers != NULL) - { - SetupData.CompCount = Count; - Count = 0; - if (SetupFindFirstLine(hTxtsetupSif, _T("Computer"), NULL, &InfContext)) - { - do - { - SetupGetStringField(&InfContext, - 0, - SetupData.pComputers[Count].Id, - sizeof(SetupData.pComputers[Count].Id) / sizeof(TCHAR), - &LineLength); - - SetupGetStringField(&InfContext, - 1, - SetupData.pComputers[Count].Value, - sizeof(SetupData.pComputers[Count].Value) / sizeof(TCHAR), - &LineLength); - ++Count; - } - while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.CompCount); - } - } - } + SetupData.CompCount = LoadGenentry(hTxtsetupSif,_T("Computer"),SetupData.pComputers,&InfContext); // get display list - Count = SetupGetLineCount(hTxtsetupSif, _T("Display")); - if (Count > 0) - { - SetupData.pDisplays = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * Count); - if (SetupData.pDisplays != NULL) - { - SetupData.DispCount = Count; - Count = 0; - - if (SetupFindFirstLine(hTxtsetupSif, _T("Display"), NULL, &InfContext)) - { - do - { - SetupGetStringField(&InfContext, - 0, - SetupData.pDisplays[Count].Id, - sizeof(SetupData.pDisplays[Count].Id) / sizeof(TCHAR), - &LineLength); - - SetupGetStringField(&InfContext, - 1, - SetupData.pDisplays[Count].Value, - sizeof(SetupData.pDisplays[Count].Value) / sizeof(TCHAR), - &LineLength); - ++Count; - } - while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.DispCount); - } - } - } + SetupData.DispCount = LoadGenentry(hTxtsetupSif,_T("Display"),SetupData.pDisplays,&InfContext); // get keyboard list - Count = SetupGetLineCount(hTxtsetupSif, _T("Keyboard")); - if (Count > 0) - { - SetupData.pKeyboards = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * Count); - if (SetupData.pKeyboards != NULL) - { - SetupData.KeybCount = Count; - Count = 0; - - if (SetupFindFirstLine(hTxtsetupSif, _T("Keyboard"), NULL, &InfContext)) - { - do - { - SetupGetStringField(&InfContext, - 0, - SetupData.pKeyboards[Count].Id, - sizeof(SetupData.pKeyboards[Count].Id) / sizeof(TCHAR), - &LineLength); - - SetupGetStringField(&InfContext, - 1, - SetupData.pKeyboards[Count].Value, - sizeof(SetupData.pKeyboards[Count].Value) / sizeof(TCHAR), - &LineLength); - ++Count; - } - while (SetupFindNextLine(&InfContext, &InfContext) && Count < SetupData.KeybCount); - } - } - } + SetupData.KeybCount = LoadGenentry(hTxtsetupSif, _T("Keyboard"),SetupData.pKeyboards,&InfContext); // get install directory if (SetupFindFirstLine(hTxtsetupSif, _T("SetupData"), _T("DefaultPath"), &InfContext)) @@ -1191,6 +1105,42 @@ void LoadSetupData() } } +LONG LoadGenentry(HINF hinf,PCTSTR name,PGENENTRY gen,PINFCONTEXT context) +{ + LONG TotalCount; + + TotalCount = SetupGetLineCount(hinf, name); + if (TotalCount > 0) + { + gen = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GENENTRY) * TotalCount); + if (gen != NULL) + { + if (SetupFindFirstLine(hinf, name, NULL, context)) + { + LONG Count = 0; + do + { + SetupGetStringField(context, + 0, + gen[Count].Id, + sizeof(gen[Count].Id) / sizeof(TCHAR), + NULL); + + SetupGetStringField(context, + 1, + gen[Count].Value, + sizeof(gen[Count].Value) / sizeof(TCHAR), + NULL); + Count++; + } + while (SetupFindNextLine(context, context) && Count < TotalCount); + } + } + } + + return TotalCount; +} + BOOL isUnattendSetup() { WCHAR szPath[MAX_PATH]; From 14442c0a340f45a91ba6d4115b5a517091545a9d Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 12 Nov 2009 13:55:51 +0000 Subject: [PATCH 030/140] [advapi32] Alexander Yastrebov - Return proper lengths of required buffer sizes in characters (including the termination NULL character) in LookupAccountSid. Fixes 4 "advapi32_winetest security" failures. See issue #4904 for more details. svn path=/trunk/; revision=44117 --- reactos/dll/win32/advapi32/sec/misc.c | 69 +++++++++++---------------- 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/reactos/dll/win32/advapi32/sec/misc.c b/reactos/dll/win32/advapi32/sec/misc.c index 2510f39ae7a..51cf09e1512 100644 --- a/reactos/dll/win32/advapi32/sec/misc.c +++ b/reactos/dll/win32/advapi32/sec/misc.c @@ -1146,6 +1146,7 @@ LookupAccountSidW(LPCWSTR pSystemName, PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain = NULL; PLSA_TRANSLATED_NAME TranslatedName = NULL; BOOL ret; + DWORD dwAccountName, dwDomainName; RtlInitUnicodeString ( &SystemName, pSystemName ); Status = LsaOpenPolicy ( &SystemName, &ObjectAttributes, POLICY_LOOKUP_NAMES, &PolicyHandle ); @@ -1166,49 +1167,37 @@ LookupAccountSidW(LPCWSTR pSystemName, else { ret = TRUE; - if ( TranslatedName ) + + dwAccountName = TranslatedName->Name.Length / sizeof(WCHAR); + if (ReferencedDomain && ReferencedDomain->Entries > 0) + dwDomainName = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR); + else + dwDomainName = 0; + + if (*pdwAccountName <= dwAccountName || *pdwDomainName <= dwDomainName) { - DWORD dwSrcLen = TranslatedName->Name.Length / sizeof(WCHAR); - if ( *pdwAccountName <= dwSrcLen ) - { - *pdwAccountName = dwSrcLen + 1; - ret = FALSE; - } - else - { - *pdwAccountName = dwSrcLen; - if (pAccountName) - { - RtlCopyMemory ( pAccountName, TranslatedName->Name.Buffer, TranslatedName->Name.Length ); - pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0'; - } - } - if ( peUse ) + /* One or two buffers are insufficient, add up a char for NULL termination */ + *pdwAccountName = dwAccountName + 1; + *pdwDomainName = dwDomainName + 1; + ret = FALSE; + } else + { + /* Lengths are sufficient, copy the data */ + if(dwAccountName) + RtlCopyMemory(pAccountName, TranslatedName->Name.Buffer, dwAccountName * sizeof(WCHAR)); + pAccountName[dwAccountName] = L'\0'; + + if(dwDomainName) + RtlCopyMemory(pDomainName, ReferencedDomain->Domains[0].Name.Buffer, dwDomainName * sizeof(WCHAR)); + pDomainName[dwDomainName] = L'\0'; + + *pdwAccountName = dwAccountName; + *pdwDomainName = dwDomainName; + + if (peUse) *peUse = TranslatedName->Use; } - - if ( ReferencedDomain ) - { - if ( ReferencedDomain->Entries > 0 ) - { - DWORD dwSrcLen = ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR); - if ( *pdwDomainName <= dwSrcLen ) - { - *pdwDomainName = dwSrcLen + 1; - ret = FALSE; - } - else - { - *pdwDomainName = dwSrcLen; - if (pDomainName) - { - RtlCopyMemory ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer, ReferencedDomain->Domains[0].Name.Length ); - pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0'; - } - } - } - } - + if ( !ret ) SetLastError(ERROR_INSUFFICIENT_BUFFER); } From 141ef5cfc300464719c29856da9b9f7ab5600ff3 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Thu, 12 Nov 2009 19:41:39 +0000 Subject: [PATCH 031/140] - Add missing synchronization for access to PsLoadedModuleList. Inserting and removing entries to the list was protected by a spinlock, but some places didn't acquire the lock before looping the list when searching for module information. For efficiency, use an executive resource for other access than inserting/removing entries so we can have shared locking in some common cases (spinlock stays so access can be synchronized with DPCs). - Make SystemUnloadGdiDriverInformation take the opaque SectionPointer (which is really the Loader Entry) from the SYSTEM_GDI_DRIVER_INFORMATION structure returned in SystemLoadGdiDriverInformation so it doesn't need to loop the loaded module list to find it. - Fix EngLoad/UnloadImage to do this. Also make EngLoadImage return the pointer to the internal structure as the "handle" so EngUnloadImage doesn't need to loop the driver list to find it. The code is still extremely broken and needs a rewrite. - Remove some externs from related variables in the code -- we use something called "headers". svn path=/trunk/; revision=44119 --- reactos/ntoskrnl/ex/sysinfo.c | 100 ++++++++----------- reactos/ntoskrnl/include/internal/mm.h | 2 + reactos/ntoskrnl/include/internal/ps.h | 2 + reactos/ntoskrnl/io/iomgr/driver.c | 2 - reactos/ntoskrnl/mm/ARM3/drvmgmt.c | 2 - reactos/ntoskrnl/mm/mminit.c | 1 - reactos/ntoskrnl/mm/sysldr.c | 18 +++- reactos/subsystems/win32/win32k/ldr/loader.c | 42 +++----- 8 files changed, 72 insertions(+), 97 deletions(-) diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 5f5450659a0..c0637d5e0c0 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -139,17 +139,6 @@ ExpQueryModuleInformation(IN PLIST_ENTRY KernelModeList, /* FUNCTIONS *****************************************************************/ -/* - * @implemented - */ -#undef ExGetPreviousMode -KPROCESSOR_MODE -NTAPI -ExGetPreviousMode (VOID) -{ - return KeGetPreviousMode(); -} - /* * @implemented */ @@ -1006,12 +995,23 @@ QSI_DEF(SystemCallTimeInformation) /* Class 11 - Module Information */ QSI_DEF(SystemModuleInformation) { - extern LIST_ENTRY PsLoadedModuleList; - return ExpQueryModuleInformation(&PsLoadedModuleList, - NULL, - (PRTL_PROCESS_MODULES)Buffer, - Size, - ReqSize); + NTSTATUS Status; + + /* Acquire system module list lock */ + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&PsLoadedModuleResource, TRUE); + + /* Call the generic handler with the system module list */ + Status = ExpQueryModuleInformation(&PsLoadedModuleList, + &MmLoadedUserImageList, + (PRTL_PROCESS_MODULES)Buffer, + Size, + ReqSize); + + /* Release list lock and return status */ + ExReleaseResourceLite(&PsLoadedModuleResource); + KeLeaveCriticalRegion(); + return Status; } /* Class 12 - Locks Information */ @@ -1322,10 +1322,9 @@ QSI_DEF(SystemFullMemoryInformation) SSI_DEF(SystemLoadGdiDriverInformation) { PSYSTEM_GDI_DRIVER_INFORMATION DriverInfo = (PVOID)Buffer; - KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); UNICODE_STRING ImageName; PVOID ImageBase; - PLDR_DATA_TABLE_ENTRY ModuleObject; + PVOID SectionPointer; ULONG_PTR EntryPoint; NTSTATUS Status; ULONG DirSize; @@ -1338,8 +1337,8 @@ SSI_DEF(SystemLoadGdiDriverInformation) return STATUS_INFO_LENGTH_MISMATCH; } - /* Only kernel-mode can call this function */ - if (PreviousMode != KernelMode) return STATUS_PRIVILEGE_NOT_HELD; + /* Only kernel mode can call this function */ + if (ExGetPreviousMode() != KernelMode) return STATUS_PRIVILEGE_NOT_HELD; /* Load the driver */ ImageName = DriverInfo->DriverName; @@ -1347,7 +1346,7 @@ SSI_DEF(SystemLoadGdiDriverInformation) NULL, NULL, 0, - (PVOID)&ModuleObject, + &SectionPointer, &ImageBase); if (!NT_SUCCESS(Status)) return Status; @@ -1365,7 +1364,7 @@ SSI_DEF(SystemLoadGdiDriverInformation) /* Save other data */ DriverInfo->ImageAddress = ImageBase; - DriverInfo->SectionPointer = NULL; + DriverInfo->SectionPointer = SectionPointer; DriverInfo->EntryPoint = (PVOID)EntryPoint; DriverInfo->ImageLength = NtHeader->OptionalHeader.SizeOfImage; @@ -1376,44 +1375,21 @@ SSI_DEF(SystemLoadGdiDriverInformation) /* Class 27 - Unload Image */ SSI_DEF(SystemUnloadGdiDriverInformation) { - PLDR_DATA_TABLE_ENTRY LdrEntry; - PLIST_ENTRY NextEntry; - PVOID BaseAddr = *((PVOID*)Buffer); + PVOID SectionPointer = Buffer; - if(Size != sizeof(PVOID)) + /* Validate size */ + if (Size != sizeof(PVOID)) + { + /* Incorrect length, fail */ return STATUS_INFO_LENGTH_MISMATCH; - - if(KeGetPreviousMode() != KernelMode) - return STATUS_PRIVILEGE_NOT_HELD; - - // Scan the module list - NextEntry = PsLoadedModuleList.Flink; - while(NextEntry != &PsLoadedModuleList) - { - LdrEntry = CONTAINING_RECORD(NextEntry, - LDR_DATA_TABLE_ENTRY, - InLoadOrderLinks); - - if (LdrEntry->DllBase == BaseAddr) - { - // Found it. - break; - } - - NextEntry = NextEntry->Flink; } - // Check if we found the image - if(NextEntry != &PsLoadedModuleList) - { - return MmUnloadSystemImage(LdrEntry); - } - else - { - DPRINT1("Image 0x%x not found.\n", BaseAddr); - return STATUS_DLL_NOT_FOUND; - } + /* Only kernel mode can call this function */ + if (ExGetPreviousMode() != KernelMode) return STATUS_PRIVILEGE_NOT_HELD; + /* Unload the image */ + MmUnloadSystemImage(SectionPointer); + return STATUS_SUCCESS; } /* Class 28 - Time Adjustment Information */ @@ -1986,7 +1962,6 @@ NtSetSystemInformation (IN SYSTEM_INFORMATION_CLASS SystemInformationClass, return STATUS_INVALID_INFO_CLASS; } - NTSTATUS NTAPI NtFlushInstructionCache(IN HANDLE ProcessHandle, @@ -2018,4 +1993,13 @@ NtGetCurrentProcessorNumber(VOID) return KeGetCurrentProcessorNumber(); } -/* EOF */ +/* + * @implemented + */ +#undef ExGetPreviousMode +KPROCESSOR_MODE +NTAPI +ExGetPreviousMode (VOID) +{ + return KeGetPreviousMode(); +} diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index d7dc087d826..79adab4672b 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -28,6 +28,8 @@ extern MEMORY_ALLOCATION_DESCRIPTOR MiFreeDescriptorOrg; extern LIST_ENTRY MmLoadedUserImageList; +extern KMUTANT MmSystemLoadLock; + extern ULONG MmNumberOfPagingFiles; extern PVOID MmUnloadedDrivers; diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index 50f32626f47..1d55e3068ff 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -434,6 +434,8 @@ extern POBJECT_TYPE PsJobType; extern LARGE_INTEGER ShortPsLockDelay; extern UNICODE_STRING PsNtDllPathName; extern LIST_ENTRY PsLoadedModuleList; +extern KSPIN_LOCK PsLoadedModuleSpinLock; +extern ERESOURCE PsLoadedModuleResource; extern ULONG_PTR PsNtosImageBase; // diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index c162bdb08dd..4dc022fb93f 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -692,8 +692,6 @@ MiResolveImageReferences(IN PVOID ImageBase, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports); -extern KSPIN_LOCK PsLoadedModuleSpinLock; - // // Used for images already loaded (boot drivers) // diff --git a/reactos/ntoskrnl/mm/ARM3/drvmgmt.c b/reactos/ntoskrnl/mm/ARM3/drvmgmt.c index 11ecbc1822d..4811a441dd4 100644 --- a/reactos/ntoskrnl/mm/ARM3/drvmgmt.c +++ b/reactos/ntoskrnl/mm/ARM3/drvmgmt.c @@ -21,8 +21,6 @@ MM_DRIVER_VERIFIER_DATA MmVerifierData; LIST_ENTRY MiVerifierDriverAddedThunkListHead; ULONG MiActiveVerifierThunks; -extern KMUTANT MmSystemLoadLock; -extern LIST_ENTRY PsLoadedModuleList; /* PRIVATE FUNCTIONS *********************************************************/ diff --git a/reactos/ntoskrnl/mm/mminit.c b/reactos/ntoskrnl/mm/mminit.c index d964c22388b..c9a837dd678 100644 --- a/reactos/ntoskrnl/mm/mminit.c +++ b/reactos/ntoskrnl/mm/mminit.c @@ -56,7 +56,6 @@ ULONG MmReadClusterSize; UCHAR MmDisablePagingExecutive = 1; // Forced to off PMMPTE MmSharedUserDataPte; PMMSUPPORT MmKernelAddressSpace; -extern KMUTANT MmSystemLoadLock; BOOLEAN MiDbgEnableMdDump = #ifdef _ARM_ TRUE; diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/sysldr.c index f6177e4479f..26f36f8ee20 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/sysldr.c @@ -30,6 +30,7 @@ sprintf_nt(IN PCHAR Buffer, LIST_ENTRY PsLoadedModuleList; LIST_ENTRY MmLoadedUserImageList; KSPIN_LOCK PsLoadedModuleSpinLock; +ERESOURCE PsLoadedModuleResource; ULONG_PTR PsNtosImageBase; KMUTANT MmSystemLoadLock; @@ -438,15 +439,21 @@ MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry, { KIRQL OldIrql; - /* Acquire the lock */ - KeAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql); + /* Acquire module list lock */ + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&PsLoadedModuleResource, TRUE); + + /* Acquire the spinlock too as we will insert or remove the entry */ + OldIrql = KeAcquireSpinLockRaiseToSynch(&PsLoadedModuleSpinLock); /* Insert or remove from the list */ Insert ? InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks) : RemoveEntryList(&LdrEntry->InLoadOrderLinks); - /* Release the lock */ + /* Release locks */ KeReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql); + ExReleaseResourceLite(&PsLoadedModuleResource); + KeLeaveCriticalRegion(); } VOID @@ -1332,7 +1339,8 @@ MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock) PLIST_ENTRY ListHead, NextEntry; ULONG EntrySize; - /* Setup the loaded module list and lock */ + /* Setup the loaded module list and locks */ + ExInitializeResourceLite(&PsLoadedModuleResource); KeInitializeSpinLock(&PsLoadedModuleSpinLock); InitializeListHead(&PsLoadedModuleList); @@ -2005,6 +2013,7 @@ MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName) /* Lock the list */ KeEnterCriticalRegion(); + ExAcquireResourceSharedLite(&PsLoadedModuleResource, TRUE); /* Loop the loaded module list */ NextEntry = PsLoadedModuleList.Flink; @@ -2046,6 +2055,7 @@ MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName) } /* Release the lock */ + ExReleaseResourceLite(&PsLoadedModuleResource); KeLeaveCriticalRegion(); /* Free the string and return */ diff --git a/reactos/subsystems/win32/win32k/ldr/loader.c b/reactos/subsystems/win32/win32k/ldr/loader.c index 945b0f4422d..838483efafe 100644 --- a/reactos/subsystems/win32/win32k/ldr/loader.c +++ b/reactos/subsystems/win32/win32k/ldr/loader.c @@ -29,12 +29,13 @@ typedef struct _DRIVERS { LIST_ENTRY ListEntry; - HANDLE ImageHandle; + PVOID SectionPointer; UNICODE_STRING DriverName; }DRIVERS, *PDRIVERS; extern LIST_ENTRY GlobalDriverListHead; + /* * Blatantly stolen from ldr/utils.c in ntdll. I can't link ntdll from * here, though. @@ -199,8 +200,8 @@ HANDLE APIENTRY EngLoadImage (LPWSTR DriverName) { - HANDLE hImageHandle = NULL; SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo; + PDRIVERS DriverInfo = NULL; NTSTATUS Status; RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName); @@ -213,14 +214,14 @@ EngLoadImage (LPWSTR DriverName) { Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry); if( Current && (0 == RtlCompareUnicodeString(&GdiDriverInfo.DriverName, &Current->DriverName, FALSE)) ) { - hImageHandle = Current->ImageHandle; + DriverInfo = Current; break; } CurrentEntry = CurrentEntry->Flink; }; } - if( !hImageHandle ) + if( !DriverInfo ) { /* the driver was not loaded before, so let's do that */ Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION)); @@ -228,19 +229,17 @@ EngLoadImage (LPWSTR DriverName) DPRINT1("ZwSetSystemInformation failed with Status 0x%lx\n", Status); } else { - PDRIVERS DriverInfo; - hImageHandle = (HANDLE)GdiDriverInfo.ImageAddress; DriverInfo = ExAllocatePool(PagedPool, sizeof(DRIVERS)); DriverInfo->DriverName.MaximumLength = GdiDriverInfo.DriverName.MaximumLength; DriverInfo->DriverName.Length = GdiDriverInfo.DriverName.Length; DriverInfo->DriverName.Buffer = ExAllocatePool(PagedPool, GdiDriverInfo.DriverName.MaximumLength); RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName); - DriverInfo->ImageHandle = hImageHandle; + DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer; InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry); } } - return hImageHandle; + return DriverInfo; } VOID @@ -248,11 +247,12 @@ APIENTRY EngUnloadImage ( IN HANDLE hModule ) { NTSTATUS Status; + PDRIVERS DriverInfo = (PDRIVERS)hModule; DPRINT("hModule 0x%x\n", hModule); Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation, - &hModule, sizeof(HANDLE)); + DriverInfo->SectionPointer, sizeof(PVOID)); if(!NT_SUCCESS(Status)) { @@ -261,27 +261,9 @@ EngUnloadImage ( IN HANDLE hModule ) } else { - /* remove from the list */ - if( !IsListEmpty(&GlobalDriverListHead) ) - { - PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink; - PDRIVERS Current; - /* probably the driver was already loaded, let's try to find it out */ - while( CurrentEntry != &GlobalDriverListHead ) - { - Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry); - - if( Current ) { - if(Current->ImageHandle == hModule) { - ExFreePool(Current->DriverName.Buffer); - RemoveEntryList(&Current->ListEntry); - ExFreePool(Current); - break; - } - } - CurrentEntry = CurrentEntry->Flink; - }; - } + ExFreePool(DriverInfo->DriverName.Buffer); + RemoveEntryList(&DriverInfo->ListEntry); + ExFreePool(DriverInfo); } } From 69b02e115558485c699e64998b9e1b154c707b6b Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Thu, 12 Nov 2009 20:41:12 +0000 Subject: [PATCH 032/140] - Win32k doesn't know what "opaque" means. Store the module base address in the structure too for the code that relied on the handle being the base address. svn path=/trunk/; revision=44120 --- reactos/subsystems/win32/win32k/include/driver.h | 12 +++++++----- reactos/subsystems/win32/win32k/ldr/loader.c | 10 ++-------- reactos/subsystems/win32/win32k/ntuser/kbdlayout.c | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/driver.h b/reactos/subsystems/win32/win32k/include/driver.h index 8c5e09a14f9..04cd33b986f 100644 --- a/reactos/subsystems/win32/win32k/include/driver.h +++ b/reactos/subsystems/win32/win32k/include/driver.h @@ -4,11 +4,13 @@ #include - - - - - +typedef struct _DRIVERS +{ + LIST_ENTRY ListEntry; + PVOID SectionPointer; + PVOID BaseAddress; + UNICODE_STRING DriverName; +}DRIVERS, *PDRIVERS; BOOL DRIVER_RegisterDriver(LPCWSTR Name, PFN_DrvEnableDriver EnableDriver); PFN_DrvEnableDriver DRIVER_FindExistingDDIDriver(LPCWSTR Name); diff --git a/reactos/subsystems/win32/win32k/ldr/loader.c b/reactos/subsystems/win32/win32k/ldr/loader.c index 838483efafe..9803c8d4009 100644 --- a/reactos/subsystems/win32/win32k/ldr/loader.c +++ b/reactos/subsystems/win32/win32k/ldr/loader.c @@ -26,13 +26,6 @@ #include -typedef struct _DRIVERS -{ - LIST_ENTRY ListEntry; - PVOID SectionPointer; - UNICODE_STRING DriverName; -}DRIVERS, *PDRIVERS; - extern LIST_ENTRY GlobalDriverListHead; @@ -181,7 +174,7 @@ EngFindImageProcAddress(IN HANDLE Module, return NULL; } RtlInitAnsiString(&ProcNameString, ProcName); - Status = LdrGetProcedureAddress(Module, + Status = LdrGetProcedureAddress(((PDRIVERS)Module)->BaseAddress, &ProcNameString, 0, &Function); @@ -235,6 +228,7 @@ EngLoadImage (LPWSTR DriverName) DriverInfo->DriverName.Buffer = ExAllocatePool(PagedPool, GdiDriverInfo.DriverName.MaximumLength); RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName); DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer; + DriverInfo->BaseAddress = GdiDriverInfo.ImageAddress; InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry); } } diff --git a/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c b/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c index cbb5a5fd50f..c43a6c2aae5 100644 --- a/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c +++ b/reactos/subsystems/win32/win32k/ntuser/kbdlayout.c @@ -163,7 +163,7 @@ static BOOL UserLoadKbdDll(WCHAR *wsKLID, DPRINT("Loaded %wZ\n", &FullLayoutPath); RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" ); - LdrGetProcedureAddress((PVOID)*phModule, + LdrGetProcedureAddress((*(PDRIVERS*)phModule)->BaseAddress, &kbdProcedureName, 0, (PVOID*)&layerDescGetFn); From a8286c3821d89004945ee3bd281470092994fda0 Mon Sep 17 00:00:00 2001 From: Stefan Ginsberg Date: Thu, 12 Nov 2009 21:46:52 +0000 Subject: [PATCH 033/140] - Documentative amendment to 44115: It incorrectly stated that the commit added "init(i)al support for PCI and ISA interrupts". What was added is (disabled) initial support for ISA, EISA and PCI configurations that require level-triggered interrupts (we only support edge-triggered interrupts right now) and PCI IRQ routing, along with proper handling of IRQ13. svn path=/trunk/; revision=44121 --- reactos/hal/halx86/generic/irq.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/hal/halx86/generic/irq.S b/reactos/hal/halx86/generic/irq.S index ae78a4b86e7..2b4e70f1062 100644 --- a/reactos/hal/halx86/generic/irq.S +++ b/reactos/hal/halx86/generic/irq.S @@ -20,7 +20,7 @@ PICInitTable: /* Master PIC */ .short 0x20 /* Port */ - .byte 0x11 /* Edge,, cascade, CAI 8, ICW4 */ + .byte 0x11 /* Edge, cascade, CAI 8, ICW4 */ .byte PRIMARY_VECTOR_BASE /* Base */ .byte 4 /* IRQ 4 connected to slave */ .byte 1 /* Non buffered, not nested, 8086 */ @@ -798,7 +798,7 @@ _KeRaiseIrqlToDpcLevel@0: mov dword ptr PCR[KPCR_IRQL], DISPATCH_LEVEL #if DBG - /* Make sure we were not higher then dispatch */ + /* Make sure we were not higher then synch */ cmp eax, DISPATCH_LEVEL ja InvalidRaise #endif From 61887111ab41b36e1f31d3ecd233304d78f47671 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 01:48:28 +0000 Subject: [PATCH 034/140] [WDMAUD_KERNEL] - Implement kernel side of notifying clients of volume / mute control changes svn path=/trunk/; revision=44122 --- .../drivers/wdm/audio/legacy/wdmaud/control.c | 2 + .../wdm/audio/legacy/wdmaud/deviface.c | 19 ++ .../drivers/wdm/audio/legacy/wdmaud/entry.c | 90 ++++++---- .../wdm/audio/legacy/wdmaud/interface.h | 25 +++ .../drivers/wdm/audio/legacy/wdmaud/mixer.c | 170 +++++++++++++++++- .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 31 +++- 6 files changed, 296 insertions(+), 41 deletions(-) diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 2bac8107ae2..3d4ceb2bb7e 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -372,6 +372,8 @@ WdmAudDeviceControl( return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_QUERYDEVICEINTERFACESTRING: return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo); + case IOCTL_GET_MIXER_EVENT: + return WdmAudGetMixerEvent(DeviceObject, Irp, DeviceInfo, ClientInfo); case IOCTL_GETPOS: case IOCTL_GETDEVID: case IOCTL_GETVOLUME: diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c b/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c index aa5a9c050a6..83309177a4c 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/deviface.c @@ -205,22 +205,41 @@ WdmAudOpenSysaudio( PWDMAUD_CLIENT Client; PWDMAUD_DEVICE_EXTENSION DeviceExtension; + /* get device extension */ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; if (!DeviceExtension->NumSysAudioDevices) + { + /* wdmaud failed to open sysaudio */ return STATUS_UNSUCCESSFUL; + } + /* sanity check */ ASSERT(!IsListEmpty(&DeviceExtension->SysAudioDeviceList)); + /* allocate client context struct */ Client = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_CLIENT)); + + /* check for allocation failure */ if (!Client) { + /* not enough memory */ return STATUS_INSUFFICIENT_RESOURCES; } + /* zero client context struct */ RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT)); + + /* initialize mixer event list */ + InitializeListHead(&Client->MixerEventList); + + /* store result */ *pClient = Client; + /* insert client into list */ + ExInterlockedInsertTailList(&DeviceExtension->WdmAudClientList, &Client->Entry, &DeviceExtension->Lock); + + /* done */ return STATUS_SUCCESS; } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c index 694719bf6fd..7d774da359d 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c @@ -54,6 +54,9 @@ WdmAudInstallDevice( /* initialize sysaudio device list */ InitializeListHead(&DeviceExtension->SysAudioDeviceList); + /* initialize client context device list */ + InitializeListHead(&DeviceExtension->WdmAudClientList); + /* initialize spinlock */ KeInitializeSpinLock(&DeviceExtension->Lock); @@ -123,14 +126,11 @@ WdmAudCreate( IN PIRP Irp) { NTSTATUS Status; - PIO_STACK_LOCATION IoStack; PWDMAUD_CLIENT pClient; - PWDMAUD_DEVICE_EXTENSION DeviceExtension; - DPRINT("WdmAudCreate\n"); - + /* get device extension */ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; #if KS_IMPLEMENTED @@ -146,8 +146,12 @@ WdmAudCreate( if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open sysaudio!\n"); - if (pClient) - ExFreePool(pClient); + + /* complete and forget */ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* done */ + return STATUS_UNSUCCESSFUL; } IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -170,8 +174,7 @@ WdmAudClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - DPRINT("WdmAudClose\n"); - + /* nothing to do complete request */ #if KS_IMPLEMENTED Status = KsDereferenceSoftwareBusObject(DeviceExtension->DeviceHeader); @@ -186,6 +189,7 @@ WdmAudClose( Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* done */ return STATUS_SUCCESS; } @@ -196,45 +200,67 @@ WdmAudCleanup( IN PIRP Irp) { PIO_STACK_LOCATION IoStack; - WDMAUD_CLIENT *pClient; + PWDMAUD_CLIENT pClient; + PWDMAUD_DEVICE_EXTENSION DeviceExtension; ULONG Index; + KIRQL OldIrql; - DPRINT("WdmAudCleanup\n"); + /* get device extension */ + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); - pClient = (WDMAUD_CLIENT*)IoStack->FileObject->FsContext; + /* sanity check */ + ASSERT(IoStack->FileObject); - if (pClient) + /* get client context struct */ + pClient = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext; + + /* sanity check */ + ASSERT(pClient); + + /* acquire client context list lock */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + + /* remove entry */ + RemoveEntryList(&pClient->Entry); + + /* release lock */ + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + + /* check if all audio pins have been closed */ + for (Index = 0; Index < pClient->NumPins; Index++) { - for (Index = 0; Index < pClient->NumPins; Index++) - { - DPRINT("Index %u Pin %p Type %x\n", Index, pClient->hPins[Index].Handle, pClient->hPins[Index].Type); - if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE) - { - ZwClose(pClient->hPins[Index].Handle); - } - } - - if (pClient->hPins) - { - ExFreePool(pClient->hPins); - } - - ExFreePool(pClient); - IoStack->FileObject->FsContext = NULL; + DPRINT("Index %u Pin %p Type %x\n", Index, pClient->hPins[Index].Handle, pClient->hPins[Index].Type); + if (pClient->hPins[Index].Handle && pClient->hPins[Index].Type != MIXER_DEVICE_TYPE) + { + /* found an still open audio pin */ + ZwClose(pClient->hPins[Index].Handle); + } } + /* free pin array */ + if (pClient->hPins) + ExFreePool(pClient->hPins); + + /* free client context struct */ + ExFreePool(pClient); + + /* clear old client pointer */ + IoStack->FileObject->FsContext = NULL; + + /* complete request */ Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); - DPRINT("WdmAudCleanup complete\n"); + + /* done */ return STATUS_SUCCESS; } - - -NTSTATUS NTAPI +NTSTATUS +NTAPI DriverEntry( IN PDRIVER_OBJECT Driver, IN PUNICODE_STRING Registry_path diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h index 44eef61c028..13e748fea0c 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h @@ -49,9 +49,17 @@ typedef struct LPWSTR DeviceInterfaceString; ULONG DeviceInterfaceStringSize; }Interface; + + struct + { + HANDLE hMixer; + ULONG NotificationType; + ULONG Value; + }MixerEvent; KSSTATE State; ULONG Volume; ULONG FrameSize; + HANDLE hNotifyEvent; }u; }WDMAUD_DEVICE_INFO, *PWDMAUD_DEVICE_INFO; @@ -336,4 +344,21 @@ typedef struct METHOD_BUFFERED, \ FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) +/// IOCTL_GET_MIXER_EVENT +/// +/// Description: This IOCTL queries for +/// +/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, +/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure +/// Note: The hDevice member must be set +/// Result: The result is returned in the struct MixerInfo +/// ReturnCode: STATUS_SUCCESS indicates success + +#define IOCTL_GET_MIXER_EVENT \ + CTL_CODE(FILE_DEVICE_SOUND, \ + 16, \ + METHOD_BUFFERED, \ + FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) + + #endif diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c index df9cad510fa..845263994f1 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -1770,6 +1770,7 @@ WdmAudControlOpenMixer( { /* re-use pseudo handle */ DeviceInfo->hDevice = (HANDLE)DeviceInfo->DeviceIndex; + ClientInfo->hPins[Index].hNotifyEvent = DeviceInfo->u.hNotifyEvent; return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); } } @@ -1787,6 +1788,7 @@ WdmAudControlOpenMixer( ClientInfo->hPins = Handels; ClientInfo->hPins[ClientInfo->NumPins].Handle = (HANDLE)DeviceInfo->DeviceIndex; ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE; + ClientInfo->hPins[ClientInfo->NumPins].hNotifyEvent = DeviceInfo->u.hNotifyEvent; ClientInfo->NumPins++; } else @@ -2049,11 +2051,95 @@ SetGetControlDetails( return Status; } +NTSTATUS +NotifyWdmAudClients( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG NotificationType, + IN HANDLE hMixer, + IN ULONG Value) +{ + PWDMAUD_DEVICE_EXTENSION DeviceExtension; + PLIST_ENTRY Entry; + PWDMAUD_CLIENT CurClient; + PKEVENT EventObject; + PMIXER_EVENT Event; + KIRQL OldIrql; + ULONG Index; + NTSTATUS Status; + + /* get device extension */ + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* acquire client context lock */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + + /* point to first entry */ + Entry = DeviceExtension->WdmAudClientList.Flink; + + /* iterate through all clients */ + while(Entry != &DeviceExtension->WdmAudClientList) + { + /* get client context */ + CurClient = (PWDMAUD_CLIENT)CONTAINING_RECORD(Entry, WDMAUD_CLIENT, Entry); + + /* now iterate through all pins and try to find an matching handle */ + for(Index = 0; Index < CurClient->NumPins; Index++) + { + if (CurClient->hPins[Index].Handle == hMixer && CurClient->hPins[Index].Type == MIXER_DEVICE_TYPE && CurClient->hPins[Index].hNotifyEvent) + { + /* found a matching mixer handle and a valid notify event */ + Status = ObReferenceObjectByHandle(CurClient->hPins[Index].hNotifyEvent, EVENT_MODIFY_STATE, ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Invalid notify event passed %p from client %p\n", CurClient->hPins[Index].hNotifyEvent, CurClient); + break; + } + + /* allocate event entry */ + Event = (PMIXER_EVENT)ExAllocatePool(NonPagedPool, sizeof(MIXER_EVENT)); + if (!Event) + { + /* no memory */ + ObDereferenceObject(EventObject); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* initialize event entry */ + Event->hMixer = hMixer; + Event->NotificationType = NotificationType; + Event->Value = Value; + + /* insert event entry */ + InsertTailList(&CurClient->MixerEventList, &Event->Entry); + + /* now signal the event */ + KeSetEvent(EventObject, 0, FALSE); + + /* dereference event */ + ObDereferenceObject(EventObject); + + /* search next client */ + break; + } + } + + /* move to next client */ + Entry = Entry->Flink; + } + + /* release client context lock */ + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + + /* done */ + return STATUS_SUCCESS; +} + NTSTATUS SetGetMuteControlDetails( IN PDEVICE_OBJECT DeviceObject, IN ULONG DeviceId, IN ULONG NodeId, + IN ULONG dwLineID, IN PWDMAUD_DEVICE_INFO DeviceInfo, IN ULONG bSet) { @@ -2074,9 +2160,21 @@ SetGetMuteControlDetails( /* set control details */ Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, MAXULONG, &Value); + if (!NT_SUCCESS(Status)) + return Status; + /* FIXME SEH */ if (!bSet) + { Input->fValue = Value; + return Status; + } + else + { + /* notify clients of a line change */ + NotifyWdmAudClients(DeviceObject, MM_MIXM_LINE_CHANGE, DeviceInfo->hDevice, dwLineID); + } + return Status; } @@ -2147,10 +2245,76 @@ SetGetVolumeControlDetails( } Input->dwValue = VolumeData->InputSteppingDelta * (VolumeData->ValuesCount-1); } - + else + { + /* notify clients of a line change */ + NotifyWdmAudClients(DeviceObject, MM_MIXM_CONTROL_CHANGE, DeviceInfo->hDevice, MixerControl->dwControlID); + } return Status; } +NTSTATUS +NTAPI +WdmAudGetMixerEvent( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo) +{ + PWDMAUD_DEVICE_EXTENSION DeviceExtension; + PMIXER_EVENT Event = NULL; + PLIST_ENTRY Entry; + KIRQL OldIrql; + + /* get device extension */ + DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* acquire client context lock */ + KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql); + + /* point to first entry */ + Entry = ClientInfo->MixerEventList.Flink; + + while(Entry != &ClientInfo->MixerEventList) + { + /* get mixer event */ + Event = (PMIXER_EVENT)CONTAINING_RECORD(Entry, MIXER_EVENT, Entry); + + if (Event->hMixer == DeviceInfo->hDevice) + { + /* found an event for that particular device */ + break; + } + + /* no match found */ + Event = NULL; + + /* move to next entry */ + Entry = Entry->Flink; + } + + + /* release client context lock */ + KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); + + if (!Event) + { + /* no events available */ + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + + /* store event result */ + DeviceInfo->u.MixerEvent.hMixer = Event->hMixer; + DeviceInfo->u.MixerEvent.NotificationType = Event->NotificationType; + DeviceInfo->u.MixerEvent.Value = Event->Value; + + /* free event info */ + ExFreePool(Event); + + /* done */ + return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); +} + NTSTATUS NTAPI WdmAudSetControlDetails( @@ -2193,7 +2357,7 @@ WdmAudSetControlDetails( if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) { /* send the request */ - Status = SetGetMuteControlDetails(DeviceObject, MixerLine->DeviceIndex, NodeId, DeviceInfo, TRUE); + Status = SetGetMuteControlDetails(DeviceObject, MixerLine->DeviceIndex, NodeId, MixerLine->Line.dwLineID, DeviceInfo, TRUE); } else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) { @@ -2245,7 +2409,7 @@ WdmAudGetControlDetails( if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) { /* send the request */ - Status = SetGetMuteControlDetails(DeviceObject, MixerLine->DeviceIndex, NodeId, DeviceInfo, FALSE); + Status = SetGetMuteControlDetails(DeviceObject, MixerLine->DeviceIndex, NodeId, MixerLine->Line.dwLineID, DeviceInfo, FALSE); } else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) { diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index 598d3747a4b..bc27c367f0f 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -18,19 +18,30 @@ typedef struct { - HANDLE Handle; - SOUND_DEVICE_TYPE Type; - ULONG FilterId; - ULONG PinId; -}WDMAUD_HANDLE, *PWDMAUD_HANDLE; + LIST_ENTRY Entry; + HANDLE hMixer; + ULONG NotificationType; + ULONG Value; +}MIXER_EVENT, *PMIXER_EVENT; typedef struct { + HANDLE Handle; + SOUND_DEVICE_TYPE Type; + ULONG FilterId; + ULONG PinId; + HANDLE hNotifyEvent; +}WDMAUD_HANDLE, *PWDMAUD_HANDLE; + +typedef struct +{ + LIST_ENTRY Entry; HANDLE hProcess; ULONG NumPins; WDMAUD_HANDLE * hPins; + LIST_ENTRY MixerEventList; }WDMAUD_CLIENT, *PWDMAUD_CLIENT; typedef struct @@ -115,7 +126,7 @@ typedef struct ULONG WaveOutDeviceCount; LIST_ENTRY WaveOutList; - + LIST_ENTRY WdmAudClientList; }WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION; NTSTATUS @@ -243,6 +254,14 @@ WdmAudSetControlDetails( IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo); +NTSTATUS +NTAPI +WdmAudGetMixerEvent( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo, + IN PWDMAUD_CLIENT ClientInfo); + NTSTATUS NTAPI WdmAudGetControlDetails( From e113d59df68c295c72e92075c1da199770d6b77b Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 11:42:23 +0000 Subject: [PATCH 035/140] - Implement updating volume position / mute state after receiving a notification svn path=/trunk/; revision=44127 --- reactos/dll/cpl/mmsys/volume.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/reactos/dll/cpl/mmsys/volume.c b/reactos/dll/cpl/mmsys/volume.c index c9f345bddd9..19f518bccea 100644 --- a/reactos/dll/cpl/mmsys/volume.c +++ b/reactos/dll/cpl/mmsys/volume.c @@ -299,8 +299,32 @@ VolumeDlgProc(HWND hwndDlg, pGlobalData = (PGLOBAL_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER); + + switch(uMsg) { + case MM_MIXM_LINE_CHANGE: + { + GetMuteState(pGlobalData); + if (pGlobalData->muteVal) + { + SendDlgItemMessage(hwndDlg, IDC_MUTE_CHECKBOX, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); + SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconMuted); + } + else + { + SendDlgItemMessage(hwndDlg, IDC_MUTE_CHECKBOX, BM_SETCHECK, (WPARAM)BST_UNCHECKED, (LPARAM)0); + SendDlgItemMessage(hwndDlg, IDC_MUTE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)pGlobalData->hIconUnMuted); + } + break; + } + case MM_MIXM_CONTROL_CHANGE: + { + GetVolumeValue(pGlobalData); + SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETSEL, (WPARAM)FALSE, (LPARAM)MAKELONG(pGlobalData->volumeMinimum, pGlobalData->volumeValue/VOLUME_DIVIDER)); + SendDlgItemMessage(hwndDlg, IDC_VOLUME_TRACKBAR, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)pGlobalData->volumeValue/VOLUME_DIVIDER); + break; + } case WM_INITDIALOG: { pGlobalData = (GLOBAL_DATA*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GLOBAL_DATA)); From f54043e5ae6857c349358cb4bc98bfe220e58585 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Fri, 13 Nov 2009 11:47:11 +0000 Subject: [PATCH 036/140] sync dwmapi with wine 1.1.32 svn path=/trunk/; revision=44128 --- reactos/dll/win32/dwmapi/dwmapi.spec | 6 +++--- reactos/dll/win32/dwmapi/dwmapi_main.c | 30 ++++++++++++++++++++++++++ reactos/include/psdk/dwmapi.h | 11 ++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/reactos/dll/win32/dwmapi/dwmapi.spec b/reactos/dll/win32/dwmapi/dwmapi.spec index f1c800f72cc..7c613d0ad46 100644 --- a/reactos/dll/win32/dwmapi/dwmapi.spec +++ b/reactos/dll/win32/dwmapi/dwmapi.spec @@ -29,9 +29,9 @@ @ stdcall DwmFlush() @ stdcall DwmGetColorizationColor(ptr long) @ stub DwmGetCompositionTimingInfo -@ stub DwmGetGraphicsStreamClient -@ stub DwmGetGraphicsStreamTransformHint -@ stub DwmGetTransportAttributes +@ stdcall DwmGetGraphicsStreamClient(long ptr) +@ stdcall DwmGetGraphicsStreamTransformHint(long ptr) +@ stdcall DwmGetTransportAttributes(ptr ptr ptr) @ stub DwmGetWindowAttribute @ stdcall DwmIsCompositionEnabled(ptr) @ stub DwmModifyPreviousDxFrameDuration diff --git a/reactos/dll/win32/dwmapi/dwmapi_main.c b/reactos/dll/win32/dwmapi/dwmapi_main.c index d7d6f5b6e2b..60420282966 100644 --- a/reactos/dll/win32/dwmapi/dwmapi_main.c +++ b/reactos/dll/win32/dwmapi/dwmapi_main.c @@ -110,6 +110,26 @@ HRESULT WINAPI DwmSetWindowAttribute(HWND hwnd, DWORD attributenum, LPCVOID attr return E_NOTIMPL; } +/********************************************************************** + * DwmGetGraphicsStreamClient (DWMAPI.@) + */ +HRESULT WINAPI DwmGetGraphicsStreamClient(UINT uIndex, UUID *pClientUuid) +{ + FIXME("(%d, %p) stub\n", uIndex, pClientUuid); + + return E_NOTIMPL; +} + +/********************************************************************** + * DwmGetTransportAttributes (DWMAPI.@) + */ +HRESULT WINAPI DwmGetTransportAttributes(BOOL *pfIsRemoting, BOOL *pfIsConnected, DWORD *pDwGeneration) +{ + FIXME("(%p, %p, %p) stub\n", pfIsRemoting, pfIsConnected, pDwGeneration); + + return E_NOTIMPL; +} + /********************************************************************** * DwmUnregisterThumbnail (DWMAPI.@) */ @@ -129,3 +149,13 @@ HRESULT WINAPI DwmEnableMMCSS(BOOL enableMMCSS) return S_OK; } + +/********************************************************************** + * DwmGetGraphicsStreamTransformHint (DWMAPI.@) + */ +HRESULT WINAPI DwmGetGraphicsStreamTransformHint(UINT uIndex, MilMatrix3x2D *pTransform) +{ + FIXME("(%d, %p) stub\n", uIndex, pTransform); + + return E_NOTIMPL; +} diff --git a/reactos/include/psdk/dwmapi.h b/reactos/include/psdk/dwmapi.h index 710e3f4dde7..4fe51bcdbe3 100644 --- a/reactos/include/psdk/dwmapi.h +++ b/reactos/include/psdk/dwmapi.h @@ -31,7 +31,18 @@ extern "C" { DECLARE_HANDLE(HTHUMBNAIL); +typedef struct _MilMatrix3x2D +{ + DOUBLE S_11; + DOUBLE S_12; + DOUBLE S_21; + DOUBLE S_22; + DOUBLE DX; + DOUBLE DY; +} MilMatrix3x2D; + DWMAPI DwmEnableComposition(UINT); +DWMAPI DwmEnableMMCSS(BOOL); DWMAPI DwmExtendFrameIntoClientArea(HWND,const MARGINS*); DWMAPI DwmGetColorizationColor(DWORD*,BOOL); DWMAPI DwmIsCompositionEnabled(BOOL*); From 08a2fdadeb9189d68e5c2fd1bb81cff0696f7d02 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Fri, 13 Nov 2009 12:40:20 +0000 Subject: [PATCH 037/140] sync dde with wine 1.1.32 svn path=/trunk/; revision=44129 --- reactos/dll/win32/user32/misc/dde.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/user32/misc/dde.c b/reactos/dll/win32/user32/misc/dde.c index f2f7f3e244d..14cb58e7f89 100644 --- a/reactos/dll/win32/user32/misc/dde.c +++ b/reactos/dll/win32/user32/misc/dde.c @@ -1638,7 +1638,7 @@ WDML_SERVER* WDML_AddServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTop WDML_IncHSZ(pInstance, hszService); DdeQueryStringW(pInstance->instanceID, hszService, buf1, 256, CP_WINUNICODE); - snprintfW(buf2, 256, fmtW, buf1, GetCurrentProcessId()); + snprintfW(buf2, 256, fmtW, buf1, 2*sizeof(ULONG_PTR), GetCurrentProcessId()); pServer->hszServiceSpec = DdeCreateStringHandleW(pInstance->instanceID, buf2, CP_WINUNICODE); pServer->atomService = WDML_MakeAtomFromHsz(pServer->hszService); From 8d0de240d5eabe5c5214aa90102a0761e1aa418e Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 13 Nov 2009 13:26:54 +0000 Subject: [PATCH 038/140] - Sync rpcrt4 with Wine-1.1.32. ReactOS-specific changes are: * Use overlapped named pipes access mode, and use GetOverlappedResult for reading/writing too. * Add patch for waiting for server calls in RpcMgmtWaitServerListen (not fully correct one, but enough for now). * Hacks around ntsecapi.h inclusion (it can't be used properly with winternl.h). * Total removal of HTTP transport. Could be enabled when dynamic linking to wininet.dll will be possible. - Change config.h to include new ASM macros. This is not platform independent. svn path=/trunk/; revision=44130 --- reactos/dll/win32/rpcrt4/cproxy.c | 203 +- reactos/dll/win32/rpcrt4/cpsf.c | 68 +- reactos/dll/win32/rpcrt4/cpsf.h | 33 +- reactos/dll/win32/rpcrt4/cstub.c | 212 +- reactos/dll/win32/rpcrt4/epm_towers.h | 2 +- reactos/dll/win32/rpcrt4/ndr_contexthandle.c | 4 +- reactos/dll/win32/rpcrt4/ndr_misc.h | 2 +- reactos/dll/win32/rpcrt4/ndr_ole.c | 24 + reactos/dll/win32/rpcrt4/ndr_stubless.c | 353 ++- reactos/dll/win32/rpcrt4/ndr_stubless.h | 3 +- reactos/dll/win32/rpcrt4/rpc_assoc.c | 6 +- reactos/dll/win32/rpcrt4/rpc_assoc.h | 3 +- reactos/dll/win32/rpcrt4/rpc_async.c | 16 +- reactos/dll/win32/rpcrt4/rpc_binding.c | 42 +- reactos/dll/win32/rpcrt4/rpc_binding.h | 4 + reactos/dll/win32/rpcrt4/rpc_defs.h | 28 +- reactos/dll/win32/rpcrt4/rpc_epmap.c | 60 +- reactos/dll/win32/rpcrt4/rpc_message.c | 390 +++- reactos/dll/win32/rpcrt4/rpc_message.h | 22 +- reactos/dll/win32/rpcrt4/rpc_server.c | 141 +- reactos/dll/win32/rpcrt4/rpc_server.h | 4 +- reactos/dll/win32/rpcrt4/rpc_transport.c | 2085 ++++++++++++++---- reactos/dll/win32/rpcrt4/rpcrt4.rbuild | 1 + reactos/dll/win32/rpcrt4/rpcrt4.spec | 5 +- reactos/dll/win32/rpcrt4/rpcrt4_main.c | 157 +- reactos/include/reactos/wine/config.h | 6 + 26 files changed, 2971 insertions(+), 903 deletions(-) diff --git a/reactos/dll/win32/rpcrt4/cproxy.c b/reactos/dll/win32/rpcrt4/cproxy.c index 6c26d181978..9ce555f7146 100644 --- a/reactos/dll/win32/rpcrt4/cproxy.c +++ b/reactos/dll/win32/rpcrt4/cproxy.c @@ -2,6 +2,7 @@ * COM proxy implementation * * Copyright 2001 Ove KĂĄven, TransGaming Technologies + * Copyright 2009 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,6 +21,9 @@ * TODO: Handle non-i386 architectures */ +#include "config.h" +#include "wine/port.h" + #include #define COBJMACROS @@ -37,21 +41,19 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); -struct StublessThunk; - /* I don't know what MS's std proxy structure looks like, so this probably doesn't match, but that shouldn't matter */ typedef struct { const IRpcProxyBufferVtbl *lpVtbl; LPVOID *PVtbl; LONG RefCount; - const MIDL_STUBLESS_PROXY_INFO *stubless; const IID* piid; LPUNKNOWN pUnkOuter; + IUnknown *base_object; /* must be at offset 0x10 from PVtbl */ + IRpcProxyBuffer *base_proxy; PCInterfaceName name; LPPSFACTORYBUFFER pPSFactory; LPRPCCHANNELBUFFER pChannel; - struct StublessThunk *thunks; } StdProxyImpl; static const IRpcProxyBufferVtbl StdProxy_Vtbl; @@ -62,66 +64,111 @@ static const IRpcProxyBufferVtbl StdProxy_Vtbl; #include "pshpack1.h" -struct StublessThunk { +struct thunk { BYTE push; DWORD index; - BYTE call; + BYTE jmp; LONG handler; - BYTE ret; - WORD bytes; - BYTE pad[3]; }; #include "poppack.h" -/* adjust the stack size since we don't use Windows's method */ -#define STACK_ADJUST sizeof(DWORD) +extern void call_stubless_func(void); +__ASM_GLOBAL_FUNC(call_stubless_func, + "pushl %esp\n\t" /* pointer to index */ + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + "call " __ASM_NAME("ObjectStubless") __ASM_STDCALL(4) "\n\t" + "popl %edx\n\t" /* args size */ + __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") + "movl (%esp),%ecx\n\t" /* return address */ + "addl %edx,%esp\n\t" + "jmp *%ecx" ); -#define FILL_STUBLESS(x,idx,stk) \ - x->push = 0x68; /* pushl [immediate] */ \ - x->index = (idx); \ - x->call = 0xe8; /* call [near] */ \ - x->handler = (char*)ObjectStubless - (char*)&x->ret; \ - x->ret = 0xc2; /* ret [immediate] */ \ - x->bytes = stk; \ - x->pad[0] = 0x8d; /* leal (%esi),%esi */ \ - x->pad[1] = 0x76; \ - x->pad[2] = 0x00; - -static HRESULT WINAPI ObjectStubless(DWORD index) +HRESULT WINAPI ObjectStubless(DWORD *args) { - char *args = (char*)(&index + 2); - LPVOID iface = *(LPVOID*)args; + DWORD index = args[0]; + void **iface = (void **)args[2]; + const void **vtbl = (const void **)*iface; + const MIDL_STUBLESS_PROXY_INFO *stubless = *(const MIDL_STUBLESS_PROXY_INFO **)(vtbl - 2); + const PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[index]; - ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); + /* store bytes to remove from stack */ + args[0] = *(const WORD*)(fs + 8); + TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, args[0], args[1]); - PFORMAT_STRING fs = This->stubless->ProcFormatString + This->stubless->FormatStringOffset[index]; - unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; - TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, bytes, *(DWORD*)(args+bytes)); + return NdrClientCall2(stubless->pStubDesc, fs, args + 2); +} - return NdrClientCall2(This->stubless->pStubDesc, fs, args); +#define BLOCK_SIZE 1024 +#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */ + +static const struct thunk *method_blocks[MAX_BLOCKS]; + +static const struct thunk *allocate_block( unsigned int num ) +{ + unsigned int i; + struct thunk *prev, *block; + + block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block), + MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); + if (!block) return NULL; + + for (i = 0; i < BLOCK_SIZE; i++) + { + block[i].push = 0x68; /* pushl */ + block[i].index = BLOCK_SIZE * num + i + 3; + block[i].jmp = 0xe9; /* jmp */ + block[i].handler = (char *)call_stubless_func - (char *)(&block[i].handler + 1); + } + VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL ); + prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL ); + if (prev) /* someone beat us to it */ + { + VirtualFree( block, 0, MEM_RELEASE ); + block = prev; + } + return block; +} + +static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num ) +{ + const void **entry = (const void **)(vtbl + 1); + DWORD i, j; + + if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) + { + FIXME( "%u methods not supported\n", num ); + return FALSE; + } + for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) + { + const struct thunk *block = method_blocks[i]; + if (!block && !(block = allocate_block( i ))) return FALSE; + for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++) + if (*entry == (LPVOID)-1) *entry = &block[j]; + } + return TRUE; } #else /* __i386__ */ -/* can't do that on this arch */ -struct StublessThunk { int dummy; }; -#define FILL_STUBLESS(x,idx,stk) \ - ERR("stubless proxies are not supported on this architecture\n"); -#define STACK_ADJUST 0 +static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num ) +{ + ERR("stubless proxies are not supported on this architecture\n"); + return FALSE; +} #endif /* __i386__ */ -HRESULT WINAPI StdProxy_Construct(REFIID riid, - LPUNKNOWN pUnkOuter, - const ProxyFileInfo *ProxyInfo, - int Index, - LPPSFACTORYBUFFER pPSFactory, - LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppvObj) +HRESULT StdProxy_Construct(REFIID riid, + LPUNKNOWN pUnkOuter, + const ProxyFileInfo *ProxyInfo, + int Index, + LPPSFACTORYBUFFER pPSFactory, + LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppvObj) { StdProxyImpl *This; - const MIDL_STUBLESS_PROXY_INFO *stubless = NULL; PCInterfaceName name = ProxyInfo->pNamesArray[Index]; CInterfaceProxyVtbl *vtbl = ProxyInfo->pProxyVtblList[Index]; @@ -129,14 +176,12 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid, /* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */ if (ProxyInfo->TableVersion > 1) { - stubless = *(const void **)vtbl; + ULONG count = ProxyInfo->pStubVtblList[Index]->header.DispatchTableCount; vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1); - TRACE("stubless=%p\n", stubless); + TRACE("stubless vtbl %p: count=%d\n", vtbl->Vtbl, count ); + fill_stubless_table( (IUnknownVtbl *)vtbl->Vtbl, count ); } - TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); - TRACE("vtbl=%p\n", vtbl->Vtbl); - if (!IsEqualGUID(vtbl->header.piid, riid)) { ERR("IID mismatch during proxy creation\n"); return RPC_E_UNEXPECTED; @@ -145,51 +190,37 @@ HRESULT WINAPI StdProxy_Construct(REFIID riid, This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl)); if (!This) return E_OUTOFMEMORY; - if (stubless) { - CInterfaceStubVtbl *svtbl = ProxyInfo->pStubVtblList[Index]; - unsigned long i, count = svtbl->header.DispatchTableCount; - /* Maybe the original vtbl is just modified directly to point at - * ObjectStublessClientXXX thunks in real Windows, but I don't like it - */ - TRACE("stubless thunks: count=%ld\n", count); - This->thunks = HeapAlloc(GetProcessHeap(),0,sizeof(struct StublessThunk)*count); - This->PVtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID)*count); - for (i=0; ithunks[i]; - if (vtbl->Vtbl[i] == (LPVOID)-1) { - PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[i]; - unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; - TRACE("method %ld: stacksize=%d\n", i, bytes); - FILL_STUBLESS(thunk, i, bytes) - This->PVtbl[i] = thunk; - } - else { - memset(thunk, 0, sizeof(struct StublessThunk)); - This->PVtbl[i] = vtbl->Vtbl[i]; - } - } - } - else - This->PVtbl = vtbl->Vtbl; - + if (!pUnkOuter) pUnkOuter = (IUnknown *)This; This->lpVtbl = &StdProxy_Vtbl; + This->PVtbl = vtbl->Vtbl; /* one reference for the proxy */ This->RefCount = 1; - This->stubless = stubless; This->piid = vtbl->header.piid; + This->base_object = NULL; + This->base_proxy = NULL; This->pUnkOuter = pUnkOuter; This->name = name; This->pPSFactory = pPSFactory; This->pChannel = NULL; + + if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index]) + { + HRESULT r = create_proxy( ProxyInfo->pDelegatedIIDs[Index], NULL, + &This->base_proxy, (void **)&This->base_object ); + if (FAILED(r)) + { + HeapFree( GetProcessHeap(), 0, This ); + return r; + } + } + *ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl; *ppvObj = &This->PVtbl; - /* if there is no outer unknown then the caller will control the lifetime - * of the proxy object through the proxy buffer, so no need to increment the - * ref count of the proxy object */ - if (pUnkOuter) - IUnknown_AddRef((IUnknown *)*ppvObj); + IUnknown_AddRef((IUnknown *)*ppvObj); IPSFactoryBuffer_AddRef(pPSFactory); + TRACE( "iid=%s this %p proxy %p obj %p vtbl %p base proxy %p base obj %p\n", + debugstr_guid(riid), This, *ppProxy, *ppvObj, This->PVtbl, This->base_proxy, This->base_object ); return S_OK; } @@ -200,11 +231,10 @@ static void StdProxy_Destruct(LPRPCPROXYBUFFER iface) if (This->pChannel) IRpcProxyBuffer_Disconnect(iface); + if (This->base_object) IUnknown_Release( This->base_object ); + if (This->base_proxy) IRpcProxyBuffer_Release( This->base_proxy ); + IPSFactoryBuffer_Release(This->pPSFactory); - if (This->thunks) { - HeapFree(GetProcessHeap(),0,This->PVtbl); - HeapFree(GetProcessHeap(),0,This->thunks); - } HeapFree(GetProcessHeap(),0,This); } @@ -259,6 +289,7 @@ static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface, This->pChannel = pChannel; IRpcChannelBuffer_AddRef(pChannel); + if (This->base_proxy) IRpcProxyBuffer_Connect( This->base_proxy, pChannel ); return S_OK; } @@ -267,6 +298,8 @@ static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface) ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); TRACE("(%p)->Disconnect()\n",This); + if (This->base_proxy) IRpcProxyBuffer_Disconnect( This->base_proxy ); + IRpcChannelBuffer_Release(This->pChannel); This->pChannel = NULL; } diff --git a/reactos/dll/win32/rpcrt4/cpsf.c b/reactos/dll/win32/rpcrt4/cpsf.c index bece899d964..ac1eccf56fa 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.c +++ b/reactos/dll/win32/rpcrt4/cpsf.c @@ -145,6 +145,41 @@ static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl = CStdPSFactory_CreateStub }; + +static void init_psfactory( CStdPSFactoryBuffer *psfac, const ProxyFileInfo **file_list ) +{ + DWORD i, j, k; + + psfac->lpVtbl = &CStdPSFactory_Vtbl; + psfac->RefCount = 0; + psfac->pProxyFileList = file_list; + for (i = 0; file_list[i]; i++) + { + const PCInterfaceProxyVtblList *proxies = file_list[i]->pProxyVtblList; + const PCInterfaceStubVtblList *stubs = file_list[i]->pStubVtblList; + + for (j = 0; j < file_list[i]->TableSize; j++) + { + /* FIXME: i think that different vtables should be copied for + * async interfaces */ + void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; + void **pRpcStubVtbl = (void **)&stubs[j]->Vtbl; + + if (file_list[i]->pDelegatedIIDs && file_list[i]->pDelegatedIIDs[j]) + { + void **vtbl = proxies[j]->Vtbl; + if (file_list[i]->TableVersion > 1) vtbl++; + fill_delegated_proxy_table( (IUnknownVtbl *)vtbl, stubs[j]->header.DispatchTableCount ); + pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; + } + + for (k = 0; k < sizeof(IRpcStubBufferVtbl)/sizeof(void *); k++) + if (!pRpcStubVtbl[k]) pRpcStubVtbl[k] = pSrcRpcStubVtbl[k]; + } + } +} + + /*********************************************************************** * NdrDllGetClassObject [RPCRT4.@] */ @@ -158,35 +193,8 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, pPSFactoryBuffer); *ppv = NULL; - if (!pPSFactoryBuffer->lpVtbl) { - const ProxyFileInfo **pProxyFileList2; - DWORD max_delegating_vtbl_size = 0; - pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; - pPSFactoryBuffer->RefCount = 0; - pPSFactoryBuffer->pProxyFileList = pProxyFileList; - for (pProxyFileList2 = pProxyFileList; *pProxyFileList2; pProxyFileList2++) { - int i; - for (i = 0; i < (*pProxyFileList2)->TableSize; i++) { - /* FIXME: i think that different vtables should be copied for - * async interfaces */ - void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; - void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl; - unsigned int j; + if (!pPSFactoryBuffer->lpVtbl) init_psfactory( pPSFactoryBuffer, pProxyFileList ); - if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) { - pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; - if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size) - max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount; - } - - for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++) - if (!pRpcStubVtbl[j]) - pRpcStubVtbl[j] = pSrcRpcStubVtbl[j]; - } - } - if(max_delegating_vtbl_size > 0) - create_delegating_vtbl(max_delegating_vtbl_size); - } if (pclsid && IsEqualGUID(rclsid, pclsid)) return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); else { @@ -207,7 +215,7 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, */ HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) { - return !(pPSFactoryBuffer->RefCount); + return pPSFactoryBuffer->RefCount != 0 ? S_FALSE : S_OK; } @@ -266,7 +274,7 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, if (len && len < sizeof(module)) { TRACE("registering CLSID %s => %s\n", debugstr_w(clsid), debugstr_w(module)); if (RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key) == ERROR_SUCCESS) { - RegSetValueExW(subkey, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW)); + RegSetValueExW(key, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW)); if (RegCreateKeyW(key, inprocserverW, &subkey) == ERROR_SUCCESS) { RegSetValueExW(subkey, NULL, 0, REG_SZ, (LPBYTE)module, (strlenW(module)+1)*sizeof(WCHAR)); RegSetValueExW(subkey, threadingmodelW, 0, REG_SZ, (const BYTE *)bothW, sizeof(bothW)); diff --git a/reactos/dll/win32/rpcrt4/cpsf.h b/reactos/dll/win32/rpcrt4/cpsf.h index d8867d40e60..9cc046ff7ca 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.h +++ b/reactos/dll/win32/rpcrt4/cpsf.h @@ -21,36 +21,25 @@ #ifndef __WINE_CPSF_H #define __WINE_CPSF_H -HRESULT WINAPI StdProxy_Construct(REFIID riid, - LPUNKNOWN pUnkOuter, - const ProxyFileInfo *ProxyInfo, - int Index, - LPPSFACTORYBUFFER pPSFactory, - LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppvObj); +HRESULT StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, const ProxyFileInfo *ProxyInfo, + int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppvObj); -HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub); +HRESULT CStdStubBuffer_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name, + CInterfaceStubVtbl *vtbl, LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub); -HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - REFIID delegating_iid, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub); +HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name, + CInterfaceStubVtbl *vtbl, REFIID delegating_iid, + LPPSFACTORYBUFFER pPSFactory, LPRPCSTUBBUFFER *ppStub); const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface); const IRpcStubBufferVtbl CStdStubBuffer_Vtbl; const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl; -void create_delegating_vtbl(DWORD num_methods); - +BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num); +HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv); HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub); #endif /* __WINE_CPSF_H */ diff --git a/reactos/dll/win32/rpcrt4/cstub.c b/reactos/dll/win32/rpcrt4/cstub.c index 85411cd81e9..95ac1d89af2 100644 --- a/reactos/dll/win32/rpcrt4/cstub.c +++ b/reactos/dll/win32/rpcrt4/cstub.c @@ -2,6 +2,7 @@ * COM stub (CStdStubBuffer) implementation * * Copyright 2001 Ove KĂĄven, TransGaming Technologies + * Copyright 2009 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -61,12 +62,12 @@ static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer)); } -HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub) +HRESULT CStdStubBuffer_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub) { CStdStubBuffer *This; IUnknown *pvServer; @@ -113,20 +114,16 @@ typedef struct { DWORD ref; DWORD size; - void **methods; IUnknownVtbl vtbl; /* remaining entries in vtbl */ } ref_counted_vtbl; -static struct -{ - ref_counted_vtbl *table; -} current_vtbl; +static ref_counted_vtbl *current_vtbl; static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv) { - *ppv = (void *)pUnk; + *ppv = pUnk; return S_OK; } @@ -161,87 +158,137 @@ typedef struct { } vtbl_method_t; #include "poppack.h" -static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num) -{ - vtbl_method_t *method; - void **entry; - DWORD i; +#define BLOCK_SIZE 1024 +#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */ +static const vtbl_method_t *method_blocks[MAX_BLOCKS]; + +static const vtbl_method_t *allocate_block( unsigned int num ) +{ + unsigned int i; + vtbl_method_t *prev, *block; + + block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block), + MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); + if (!block) return NULL; + + for (i = 0; i < BLOCK_SIZE; i++) + { + block[i].mov1 = 0x0424448b; + block[i].mov2 = 0x408b; + block[i].sixteen = 0x10; + block[i].mov3 = 0x04244489; + block[i].mov4 = 0x008b; + block[i].mov5 = 0x808b; + block[i].offset = (BLOCK_SIZE * num + i + 3) << 2; + block[i].jmp = 0xe0ff; + block[i].pad[0] = 0x8d; + block[i].pad[1] = 0x76; + block[i].pad[2] = 0x00; + } + VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL ); + prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL ); + if (prev) /* someone beat us to it */ + { + VirtualFree( block, 0, MEM_RELEASE ); + block = prev; + } + return block; +} + +static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num) +{ + const void **entry = (const void **)(vtbl + 1); + DWORD i, j; + + if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) + { + FIXME( "%u methods not supported\n", num ); + return FALSE; + } vtbl->QueryInterface = delegating_QueryInterface; vtbl->AddRef = delegating_AddRef; vtbl->Release = delegating_Release; - - method = (vtbl_method_t*)methods; - entry = (void**)(vtbl + 1); - - for(i = 3; i < num; i++) + for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) { - *entry = method; - method->mov1 = 0x0424448b; - method->mov2 = 0x408b; - method->sixteen = 0x10; - method->mov3 = 0x04244489; - method->mov4 = 0x008b; - method->mov5 = 0x808b; - method->offset = i << 2; - method->jmp = 0xe0ff; - method->pad[0] = 0x8d; - method->pad[1] = 0x76; - method->pad[2] = 0x00; - - method++; - entry++; + const vtbl_method_t *block = method_blocks[i]; + if (!block && !(block = allocate_block( i ))) return FALSE; + for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++) *entry++ = &block[j]; } + return TRUE; +} + +BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) +{ + const void **entry = (const void **)(vtbl + 1); + DWORD i, j; + + if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) + { + FIXME( "%u methods not supported\n", num ); + return FALSE; + } + vtbl->QueryInterface = IUnknown_QueryInterface_Proxy; + vtbl->AddRef = IUnknown_AddRef_Proxy; + vtbl->Release = IUnknown_Release_Proxy; + for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) + { + const vtbl_method_t *block = method_blocks[i]; + if (!block && !(block = allocate_block( i ))) return FALSE; + for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++) + if (!*entry) *entry = &block[j]; + } + return TRUE; } #else /* __i386__ */ -typedef struct {int dummy;} vtbl_method_t; -static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num) +static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num) { ERR("delegated stubs are not supported on this architecture\n"); + return FALSE; +} + +BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) +{ + ERR("delegated proxies are not supported on this architecture\n"); + return FALSE; } #endif /* __i386__ */ -void create_delegating_vtbl(DWORD num_methods) -{ - TRACE("%d\n", num_methods); - if(num_methods <= 3) - { - ERR("should have more than %d methods\n", num_methods); - return; - } - - EnterCriticalSection(&delegating_vtbl_section); - if(!current_vtbl.table || num_methods > current_vtbl.table->size) - { - DWORD size; - DWORD old_protect; - if(current_vtbl.table && current_vtbl.table->ref == 0) - { - TRACE("freeing old table\n"); - VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE); - HeapFree(GetProcessHeap(), 0, current_vtbl.table); - } - size = (num_methods - 3) * sizeof(vtbl_method_t); - current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); - current_vtbl.table->ref = 0; - current_vtbl.table->size = num_methods; - current_vtbl.table->methods = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); - fill_table(¤t_vtbl.table->vtbl, current_vtbl.table->methods, num_methods); - VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect); - } - LeaveCriticalSection(&delegating_vtbl_section); -} - -static IUnknownVtbl *get_delegating_vtbl(void) +static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods) { IUnknownVtbl *ret; + if (num_methods < 256) num_methods = 256; /* avoid frequent reallocations */ + EnterCriticalSection(&delegating_vtbl_section); - current_vtbl.table->ref++; - ret = ¤t_vtbl.table->vtbl; + + if(!current_vtbl || num_methods > current_vtbl->size) + { + ref_counted_vtbl *table = HeapAlloc(GetProcessHeap(), 0, + FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); + if (!table) + { + LeaveCriticalSection(&delegating_vtbl_section); + return NULL; + } + + table->ref = 0; + table->size = num_methods; + fill_delegated_stub_table(&table->vtbl, num_methods); + + if (current_vtbl && current_vtbl->ref == 0) + { + TRACE("freeing old table\n"); + HeapFree(GetProcessHeap(), 0, current_vtbl); + } + current_vtbl = table; + } + + current_vtbl->ref++; + ret = ¤t_vtbl->vtbl; LeaveCriticalSection(&delegating_vtbl_section); return ret; } @@ -253,22 +300,21 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl) EnterCriticalSection(&delegating_vtbl_section); table->ref--; TRACE("ref now %d\n", table->ref); - if(table->ref == 0 && table != current_vtbl.table) + if(table->ref == 0 && table != current_vtbl) { TRACE("... and we're not current so free'ing\n"); - VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE); HeapFree(GetProcessHeap(), 0, table); } LeaveCriticalSection(&delegating_vtbl_section); } -HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - REFIID delegating_iid, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub) +HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + REFIID delegating_iid, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub) { cstdstubbuffer_delegating_t *This; IUnknown *pvServer; @@ -294,7 +340,7 @@ HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, return E_OUTOFMEMORY; } - This->base_obj = get_delegating_vtbl(); + This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount ); r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub); if(FAILED(r)) { diff --git a/reactos/dll/win32/rpcrt4/epm_towers.h b/reactos/dll/win32/rpcrt4/epm_towers.h index 1afd3eb3376..3eec37aa228 100644 --- a/reactos/dll/win32/rpcrt4/epm_towers.h +++ b/reactos/dll/win32/rpcrt4/epm_towers.h @@ -19,7 +19,7 @@ * */ -#include "epm_c.h" +#include "epm.h" #define EPM_PROTOCOL_DNET_NSP 0x04 #define EPM_PROTOCOL_OSI_TP4 0x05 diff --git a/reactos/dll/win32/rpcrt4/ndr_contexthandle.c b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c index 15192a72878..cab0fc5d86e 100644 --- a/reactos/dll/win32/rpcrt4/ndr_contexthandle.c +++ b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c @@ -59,7 +59,7 @@ static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 }; static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext) { - struct context_handle_entry *che = (struct context_handle_entry*) CContext; + struct context_handle_entry *che = CContext; if (che->magic != NDR_CONTEXT_HANDLE_MAGIC) return NULL; @@ -111,7 +111,7 @@ void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff) } else { - ndr_context_handle *wire_data = (ndr_context_handle *)pBuff; + ndr_context_handle *wire_data = pBuff; wire_data->attributes = 0; wire_data->uuid = GUID_NULL; } diff --git a/reactos/dll/win32/rpcrt4/ndr_misc.h b/reactos/dll/win32/rpcrt4/ndr_misc.h index c3beff4d725..b0150c3a2eb 100644 --- a/reactos/dll/win32/rpcrt4/ndr_misc.h +++ b/reactos/dll/win32/rpcrt4/ndr_misc.h @@ -62,6 +62,6 @@ extern const NDR_BUFFERSIZE NdrBufferSizer[]; extern const NDR_MEMORYSIZE NdrMemorySizer[]; extern const NDR_FREE NdrFreer[]; -unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat); +ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat); #endif /* __WINE_NDR_MISC_H */ diff --git a/reactos/dll/win32/rpcrt4/ndr_ole.c b/reactos/dll/win32/rpcrt4/ndr_ole.c index a3264e70122..a4c23c2c5c2 100644 --- a/reactos/dll/win32/rpcrt4/ndr_ole.c +++ b/reactos/dll/win32/rpcrt4/ndr_ole.c @@ -369,6 +369,30 @@ void WINAPI NdrOleFree(void *NodeToFree) COM_MemFree(NodeToFree); } +/*********************************************************************** + * Helper function to create a proxy. + * Probably similar to NdrpCreateProxy. + */ +HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv) +{ + CLSID clsid; + IPSFactoryBuffer *psfac; + HRESULT r; + + if(!LoadCOM()) return E_FAIL; + + r = COM_GetPSClsid( iid, &clsid ); + if(FAILED(r)) return r; + + r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac ); + if(FAILED(r)) return r; + + r = IPSFactoryBuffer_CreateProxy(psfac, pUnkOuter, iid, pproxy, ppv); + + IPSFactoryBuffer_Release(psfac); + return r; +} + /*********************************************************************** * Helper function to create a stub. * This probably looks very much like NdrpCreateStub. diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.c b/reactos/dll/win32/rpcrt4/ndr_stubless.c index 645a0ca4729..8cb5f2b5e45 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.c +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.c @@ -173,7 +173,7 @@ static PFORMAT_STRING client_get_handle( if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); + pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; *phBinding = pGenPair->pfnBind(pObject); @@ -256,7 +256,7 @@ static void client_free_handle( if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); + pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; pGenPair->pfnUnbind(pObject, hBinding); @@ -867,9 +867,14 @@ __declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigne LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size); __ASM_GLOBAL_FUNC(call_server_func, "pushl %ebp\n\t" - "movl %esp, %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + "movl %esp,%ebp\n\t" + __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") "pushl %edi\n\t" /* Save registers */ + __ASM_CFI(".cfi_rel_offset %edi,-4\n\t") "pushl %esi\n\t" + __ASM_CFI(".cfi_rel_offset %esi,-8\n\t") "movl 16(%ebp), %eax\n\t" /* Get stack size */ "subl %eax, %esp\n\t" /* Make room in stack for arguments */ "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for Mac OS X */ @@ -882,9 +887,13 @@ __ASM_GLOBAL_FUNC(call_server_func, "call *8(%ebp)\n\t" /* Call function */ "leal -8(%ebp), %esp\n\t" /* Restore stack */ "popl %esi\n\t" /* Restore registers */ + __ASM_CFI(".cfi_same_value %esi\n\t") "popl %edi\n\t" + __ASM_CFI(".cfi_same_value %edi\n\t") "popl %ebp\n\t" - "ret\n" ) + __ASM_CFI(".cfi_def_cfa %esp,4\n\t") + __ASM_CFI(".cfi_same_value %ebp\n\t") + "ret" ) #else #warning call_server_func not implemented for your architecture LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size) @@ -1522,3 +1531,339 @@ void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg) DWORD dwPhase; NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase); } + +struct async_call_data +{ + MIDL_STUB_MESSAGE *pStubMsg; + const NDR_PROC_HEADER *pProcHeader; + PFORMAT_STRING pHandleFormat; + PFORMAT_STRING pParamFormat; + RPC_BINDING_HANDLE hBinding; + /* size of stack */ + unsigned short stack_size; + /* number of parameters. optional for client to give it to us */ + unsigned char number_of_params; + /* correlation cache */ + unsigned long NdrCorrCache[256]; +}; + +LONG_PTR WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc, + PFORMAT_STRING pFormat, ...) +{ + /* pointer to start of stack where arguments start */ + PRPC_MESSAGE pRpcMsg; + PMIDL_STUB_MESSAGE pStubMsg; + RPC_ASYNC_STATE *pAsync; + struct async_call_data *async_call_data; + /* procedure number */ + unsigned short procedure_number; + /* cache of Oif_flags from v2 procedure header */ + INTERPRETER_OPT_FLAGS Oif_flags = { 0 }; + /* cache of extension flags from NDR_PROC_HEADER_EXTS */ + INTERPRETER_OPT_FLAGS2 ext_flags = { 0 }; + /* the type of pass we are currently doing */ + int phase; + /* header for procedure string */ + const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; + /* -Oif or -Oicf generated format */ + BOOL bV2Format = FALSE; + + TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat); + + /* Later NDR language versions probably won't be backwards compatible */ + if (pStubDesc->Version > 0x50002) + { + FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); + RpcRaiseException(RPC_X_WRONG_STUB_VERSION); + } + + async_call_data = I_RpcAllocate(sizeof(*async_call_data) + sizeof(MIDL_STUB_MESSAGE) + sizeof(RPC_MESSAGE)); + if (!async_call_data) RpcRaiseException(ERROR_OUTOFMEMORY); + async_call_data->number_of_params = ~0; + async_call_data->pProcHeader = pProcHeader; + + async_call_data->pStubMsg = pStubMsg = (PMIDL_STUB_MESSAGE)(async_call_data + 1); + pRpcMsg = (PRPC_MESSAGE)(pStubMsg + 1); + + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) + { + const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; + async_call_data->stack_size = pProcHeader->stack_size; + procedure_number = pProcHeader->proc_num; + pFormat += sizeof(NDR_PROC_HEADER_RPC); + } + else + { + async_call_data->stack_size = pProcHeader->stack_size; + procedure_number = pProcHeader->proc_num; + pFormat += sizeof(NDR_PROC_HEADER); + } + TRACE("stack size: 0x%x\n", async_call_data->stack_size); + TRACE("proc num: %d\n", procedure_number); + + /* create the full pointer translation tables, if requested */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) + pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); + + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) + { + ERR("objects not supported\n"); + I_RpcFree(async_call_data); + RpcRaiseException(RPC_X_BAD_STUB_DATA); + } + + NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDesc, procedure_number); + + TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); + TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); + + /* needed for conformance of top-level objects */ +#ifdef __i386__ + pStubMsg->StackTop = I_RpcAllocate(async_call_data->stack_size); + /* FIXME: this may read one more DWORD than is necessary, but it shouldn't hurt */ + memcpy(pStubMsg->StackTop, *(unsigned char **)(&pFormat+1), async_call_data->stack_size); +#else +# warning Stack not retrieved for your CPU architecture +#endif + + pAsync = *(RPC_ASYNC_STATE **)pStubMsg->StackTop; + pAsync->StubInfo = async_call_data; + async_call_data->pHandleFormat = pFormat; + + pFormat = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, &async_call_data->hBinding); + if (!pFormat) return 0; + + bV2Format = (pStubDesc->Version >= 0x20000); + + if (bV2Format) + { + const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = + (const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat; + + Oif_flags = pOIFHeader->Oi2Flags; + async_call_data->number_of_params = pOIFHeader->number_of_params; + + pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); + } + + TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); + + if (Oif_flags.HasExtensions) + { + const NDR_PROC_HEADER_EXTS *pExtensions = + (const NDR_PROC_HEADER_EXTS *)pFormat; + ext_flags = pExtensions->Flags2; + pFormat += pExtensions->Size; + } + + async_call_data->pParamFormat = pFormat; + + pStubMsg->BufferLength = 0; + + /* store the RPC flags away */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) + pRpcMsg->RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; + + /* use alternate memory allocation routines */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) + NdrRpcSmSetClientToOsf(pStubMsg); + + if (Oif_flags.HasPipes) + { + FIXME("pipes not supported yet\n"); + RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ + /* init pipes package */ + /* NdrPipesInitialize(...) */ + } + if (ext_flags.HasNewCorrDesc) + { + /* initialize extra correlation package */ + NdrCorrelationInitialize(pStubMsg, async_call_data->NdrCorrCache, sizeof(async_call_data->NdrCorrCache), 0); + } + + /* order of phases: + * 1. PROXY_CALCSIZE - calculate the buffer size + * 2. PROXY_GETBUFFER - allocate the buffer + * 3. PROXY_MARHSAL - marshal [in] params into the buffer + * 4. PROXY_SENDRECEIVE - send buffer + * Then in NdrpCompleteAsyncClientCall: + * 1. PROXY_SENDRECEIVE - receive buffer + * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer + */ + for (phase = PROXY_CALCSIZE; phase <= PROXY_SENDRECEIVE; phase++) + { + RPC_STATUS status; + TRACE("phase = %d\n", phase); + switch (phase) + { + case PROXY_GETBUFFER: + /* allocate the buffer */ + if (Oif_flags.HasPipes) + /* NdrGetPipeBuffer(...) */ + FIXME("pipes not supported yet\n"); + else + { + if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) +#if 0 + NdrNsGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding); +#else + FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n"); +#endif + else + NdrGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding); + } + pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; + status = I_RpcAsyncSetHandle(pRpcMsg, pAsync); + if (status != RPC_S_OK) + RpcRaiseException(status); + break; + case PROXY_SENDRECEIVE: + pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; + /* send the [in] params only */ + if (Oif_flags.HasPipes) + /* NdrPipesSend(...) */ + FIXME("pipes not supported yet\n"); + else + { + if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) +#if 0 + NdrNsSend(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle); +#else + FIXME("using auto handle - call NdrNsSend when it gets implemented\n"); +#endif + else + { + pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer; + status = I_RpcSend(pStubMsg->RpcMsg); + if (status != RPC_S_OK) + RpcRaiseException(status); + } + } + + break; + case PROXY_CALCSIZE: + case PROXY_MARSHAL: + if (bV2Format) + client_do_args(pStubMsg, pFormat, phase, pStubMsg->StackTop, + async_call_data->number_of_params, NULL); + else + client_do_args_old_format(pStubMsg, pFormat, phase, + pStubMsg->StackTop, async_call_data->stack_size, NULL, + (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE); + break; + default: + ERR("shouldn't reach here. phase %d\n", phase); + break; + } + } + + TRACE("returning 0\n"); + return 0; +} + +RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply) +{ + /* pointer to start of stack where arguments start */ + PMIDL_STUB_MESSAGE pStubMsg; + struct async_call_data *async_call_data; + /* the type of pass we are currently doing */ + int phase; + /* header for procedure string */ + const NDR_PROC_HEADER * pProcHeader; + /* -Oif or -Oicf generated format */ + BOOL bV2Format; + RPC_STATUS status = RPC_S_OK; + + if (!pAsync->StubInfo) + return RPC_S_INVALID_ASYNC_HANDLE; + + async_call_data = pAsync->StubInfo; + pStubMsg = async_call_data->pStubMsg; + pProcHeader = async_call_data->pProcHeader; + + bV2Format = (pStubMsg->StubDesc->Version >= 0x20000); + + /* order of phases: + * 1. PROXY_CALCSIZE - calculate the buffer size + * 2. PROXY_GETBUFFER - allocate the buffer + * 3. PROXY_MARHSAL - marshal [in] params into the buffer + * 4. PROXY_SENDRECEIVE - send buffer + * Then in NdrpCompleteAsyncClientCall: + * 1. PROXY_SENDRECEIVE - receive buffer + * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer + */ + for (phase = PROXY_SENDRECEIVE; phase <= PROXY_UNMARSHAL; phase++) + { + switch (phase) + { + case PROXY_SENDRECEIVE: + pStubMsg->RpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; + /* receive the [out] params */ + if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) +#if 0 + NdrNsReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle); +#else + FIXME("using auto handle - call NdrNsReceive when it gets implemented\n"); +#endif + else + { + status = I_RpcReceive(pStubMsg->RpcMsg); + if (status != RPC_S_OK) + goto cleanup; + pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; + pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; + pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; + pStubMsg->Buffer = pStubMsg->BufferStart; + } + + /* convert strings, floating point values and endianess into our + * preferred format */ +#if 0 + if ((pStubMsg->RpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) + NdrConvert(pStubMsg, pFormat); +#endif + + break; + case PROXY_UNMARSHAL: + if (bV2Format) + client_do_args(pStubMsg, async_call_data->pParamFormat, phase, pStubMsg->StackTop, + async_call_data->number_of_params, Reply); + else + client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase, + pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE); + break; + default: + ERR("shouldn't reach here. phase %d\n", phase); + break; + } + } + +cleanup: + if (pStubMsg->fHasNewCorrDesc) + { + /* free extra correlation package */ + NdrCorrelationFree(pStubMsg); + } + + /* free the full pointer translation tables */ + if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) + NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables); + + /* free marshalling buffer */ + NdrFreeBuffer(pStubMsg); + client_free_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, async_call_data->hBinding); + + I_RpcFree(pStubMsg->StackTop); + I_RpcFree(async_call_data); + + TRACE("-- 0x%x\n", status); + return status; +} + +RPCRTAPI LONG RPC_ENTRY NdrAsyncStubCall(struct IRpcStubBuffer* pThis, + struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, + DWORD * pdwStubPhase) +{ + FIXME("unimplemented, expect crash!\n"); + return 0; +} diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.h b/reactos/dll/win32/rpcrt4/ndr_stubless.h index 9a6fb444783..87f603b6065 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.h +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.h @@ -85,7 +85,7 @@ typedef struct _NDR_PROC_HEADER_RPC * RPCF_Asynchronous = 0x4000 - [async] MIDL attribute * Reserved = 0x8000 */ - unsigned long rpc_flags; + unsigned int rpc_flags; unsigned short proc_num; unsigned short stack_size; @@ -240,3 +240,4 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, int phase, unsigned char *args, unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc, BOOL ignore_retval); +RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply); diff --git a/reactos/dll/win32/rpcrt4/rpc_assoc.c b/reactos/dll/win32/rpcrt4/rpc_assoc.c index 32e951a929a..117301f42c0 100644 --- a/reactos/dll/win32/rpcrt4/rpc_assoc.c +++ b/reactos/dll/win32/rpcrt4/rpc_assoc.c @@ -125,7 +125,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, - unsigned long assoc_gid, + ULONG assoc_gid, RpcAssoc **assoc_out) { RpcAssoc *assoc; @@ -223,7 +223,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection * RPC_MESSAGE msg; RPC_STATUS status; unsigned char *auth_data = NULL; - unsigned long auth_length; + ULONG auth_length; TRACE("sending bind request to server\n"); @@ -394,6 +394,7 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, if (status != RPC_S_OK) return status; + NewConnection->assoc = assoc; status = RPCRT4_OpenClientConnection(NewConnection); if (status != RPC_S_OK) { @@ -416,6 +417,7 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection) { assert(!Connection->server); + Connection->async_state = NULL; EnterCriticalSection(&assoc->cs); if (!assoc->assoc_group_id) assoc->assoc_group_id = Connection->assoc_group_id; list_add_head(&assoc->free_connection_pool, &Connection->conn_pool_entry); diff --git a/reactos/dll/win32/rpcrt4/rpc_assoc.h b/reactos/dll/win32/rpcrt4/rpc_assoc.h index 1ce1f135638..70fb664e31d 100644 --- a/reactos/dll/win32/rpcrt4/rpc_assoc.h +++ b/reactos/dll/win32/rpcrt4/rpc_assoc.h @@ -34,6 +34,7 @@ typedef struct _RpcAssoc /* id of this association group */ ULONG assoc_group_id; + UUID http_uuid; CRITICAL_SECTION cs; @@ -49,7 +50,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endp RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection); void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection); ULONG RpcAssoc_Release(RpcAssoc *assoc); -RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, unsigned long assoc_gid, RpcAssoc **assoc_out); +RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, ULONG assoc_gid, RpcAssoc **assoc_out); RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext); RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext); RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine); diff --git a/reactos/dll/win32/rpcrt4/rpc_async.c b/reactos/dll/win32/rpcrt4/rpc_async.c index 33fdc774304..891fc5ad725 100644 --- a/reactos/dll/win32/rpcrt4/rpc_async.c +++ b/reactos/dll/win32/rpcrt4/rpc_async.c @@ -29,11 +29,17 @@ #include "rpc_binding.h" #include "rpc_message.h" +#include "ndr_stubless.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); #define RPC_ASYNC_SIGNATURE 0x43595341 +static inline BOOL valid_async_handle(PRPC_ASYNC_STATE pAsync) +{ + return pAsync->Signature == RPC_ASYNC_SIGNATURE; +} + /*********************************************************************** * RpcAsyncInitializeHandle [RPCRT4.@] * @@ -104,8 +110,14 @@ RPC_STATUS WINAPI RpcAsyncGetCallStatus(PRPC_ASYNC_STATE pAsync) */ RPC_STATUS WINAPI RpcAsyncCompleteCall(PRPC_ASYNC_STATE pAsync, void *Reply) { - FIXME("(%p, %p): stub\n", pAsync, Reply); - return RPC_S_INVALID_ASYNC_HANDLE; + TRACE("(%p, %p)\n", pAsync, Reply); + + if (!valid_async_handle(pAsync)) + return RPC_S_INVALID_ASYNC_HANDLE; + + /* FIXME: check completed */ + + return NdrpCompleteAsyncClientCall(pAsync, Reply); } /*********************************************************************** diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.c b/reactos/dll/win32/rpcrt4/rpc_binding.c index 696887cb7b3..29e0709e54f 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.c +++ b/reactos/dll/win32/rpcrt4/rpc_binding.c @@ -661,11 +661,11 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU return RPC_S_OK; fail: - if (ObjUuid) RpcStringFreeA((unsigned char**)ObjUuid); - if (Protseq) RpcStringFreeA((unsigned char**)Protseq); - if (NetworkAddr) RpcStringFreeA((unsigned char**)NetworkAddr); - if (Endpoint) RpcStringFreeA((unsigned char**)Endpoint); - if (Options) RpcStringFreeA((unsigned char**)Options); + if (ObjUuid) RpcStringFreeA(ObjUuid); + if (Protseq) RpcStringFreeA(Protseq); + if (NetworkAddr) RpcStringFreeA(NetworkAddr); + if (Endpoint) RpcStringFreeA(Endpoint); + if (Options) RpcStringFreeA(Options); return RPC_S_INVALID_STRING_BINDING; } @@ -796,7 +796,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding ) RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) { RPC_STATUS status; - unsigned long c; + ULONG c; TRACE("(%p)\n", BindingVector); for (c=0; c<(*BindingVector)->Count; c++) { @@ -812,7 +812,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) */ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) { - RpcBinding* bind = (RpcBinding*)Binding; + RpcBinding* bind = Binding; TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid)); *ObjectUuid = bind->ObjectUuid; @@ -824,7 +824,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU */ RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) { - RpcBinding* bind = (RpcBinding*)Binding; + RpcBinding* bind = Binding; TRACE("(%p,%s)\n", Binding, debugstr_guid(ObjectUuid)); if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING; @@ -856,11 +856,11 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND if (ret == RPC_S_OK) ret = RPCRT4_CompleteBindingA(bind, (char*)NetworkAddr, (char*)Endpoint, (char*)Options); - RpcStringFreeA((unsigned char**)&Options); - RpcStringFreeA((unsigned char**)&Endpoint); - RpcStringFreeA((unsigned char**)&NetworkAddr); - RpcStringFreeA((unsigned char**)&Protseq); - RpcStringFreeA((unsigned char**)&ObjectUuid); + RpcStringFreeA(&Options); + RpcStringFreeA(&Endpoint); + RpcStringFreeA(&NetworkAddr); + RpcStringFreeA(&Protseq); + RpcStringFreeA(&ObjectUuid); if (ret == RPC_S_OK) *Binding = (RPC_BINDING_HANDLE)bind; @@ -915,7 +915,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding ) { RPC_STATUS ret; - RpcBinding* bind = (RpcBinding*)Binding; + RpcBinding* bind = Binding; RPC_CSTR ObjectUuid; TRACE("(%p,%p)\n", Binding, StringBinding); @@ -946,7 +946,7 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WS TRACE("(%p,%p)\n", Binding, StringBinding); ret = RpcBindingToStringBindingA(Binding, &str); *StringBinding = RPCRT4_strdupAtoW((char*)str); - RpcStringFreeA((unsigned char**)&str); + RpcStringFreeA(&str); return ret; } @@ -969,7 +969,7 @@ RPC_STATUS WINAPI I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding, unsi */ RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn) { - RpcBinding* bind = (RpcBinding*)Binding; + RpcBinding* bind = Binding; TRACE( "(%p,%p): stub\n", Binding, BlockingFn ); @@ -986,7 +986,7 @@ RPC_STATUS RPC_ENTRY RpcBindingCopy( RPC_BINDING_HANDLE* DestinationBinding) { RpcBinding *DestBinding; - RpcBinding *SrcBinding = (RpcBinding*)SourceBinding; + RpcBinding *SrcBinding = SourceBinding; RPC_STATUS status; TRACE("(%p, %p)\n", SourceBinding, DestinationBinding); @@ -1501,7 +1501,7 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, RPC_SECURITY_QOS *SecurityQos ) { - RpcBinding* bind = (RpcBinding*)Binding; + RpcBinding* bind = Binding; SECURITY_STATUS r; CredHandle cred; TimeStamp exp; @@ -1631,7 +1631,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, RPC_SECURITY_QOS *SecurityQos ) { - RpcBinding* bind = (RpcBinding*)Binding; + RpcBinding* bind = Binding; SECURITY_STATUS r; CredHandle cred; TimeStamp exp; @@ -1640,7 +1640,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, PSecPkgInfoW packages; ULONG cbMaxToken; - TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), + TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w(ServerPrincName), AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos); if (SecurityQos) @@ -1772,7 +1772,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel, ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr ) { - TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), + TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w(ServerPrincName), AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr); return RpcBindingSetAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL); } diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.h b/reactos/dll/win32/rpcrt4/rpc_binding.h index 5aa83079d51..036b59a5567 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.h +++ b/reactos/dll/win32/rpcrt4/rpc_binding.h @@ -24,6 +24,7 @@ #include "rpcndr.h" #include "security.h" #include "wine/list.h" +#include "rpc_defs.h" typedef struct _RpcAuthInfo @@ -66,6 +67,7 @@ typedef struct _RpcConnection TimeStamp exp; ULONG attr; RpcAuthInfo *AuthInfo; + ULONG auth_context_id; ULONG encryption_auth_len; ULONG signature_auth_len; RpcQualityOfService *QOS; @@ -74,6 +76,7 @@ typedef struct _RpcConnection struct list conn_pool_entry; ULONG assoc_group_id; /* association group returned during binding */ RPC_ASYNC_STATE *async_state; + struct _RpcAssoc *assoc; /* association this connection is part of */ /* server-only */ /* The active interface bound to server. */ @@ -96,6 +99,7 @@ struct connection_ops { int (*wait_for_incoming_data)(RpcConnection *conn); size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint); RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint); + RPC_STATUS (*receive_fragment)(RpcConnection *conn, RpcPktHdr **Header, void **Payload); }; /* don't know what MS's structure looks like */ diff --git a/reactos/dll/win32/rpcrt4/rpc_defs.h b/reactos/dll/win32/rpcrt4/rpc_defs.h index cae77c4f356..e70731a3818 100644 --- a/reactos/dll/win32/rpcrt4/rpc_defs.h +++ b/reactos/dll/win32/rpcrt4/rpc_defs.h @@ -31,13 +31,13 @@ typedef struct unsigned char drep[4]; /* Data representation */ unsigned short frag_len; /* Data size in bytes including header and tail. */ unsigned short auth_len; /* Authentication length */ - unsigned long call_id; /* Call identifier. */ + unsigned int call_id; /* Call identifier. */ } RpcPktCommonHdr; typedef struct { RpcPktCommonHdr common; - unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned short opnum; } RpcPktRequestHdr; @@ -45,7 +45,7 @@ typedef struct typedef struct { RpcPktCommonHdr common; - unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned char cancel_count; unsigned char reserved; @@ -54,12 +54,12 @@ typedef struct typedef struct { RpcPktCommonHdr common; - unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned char cancel_count; /* Received cancel count */ unsigned char reserved; /* Force alignment! */ - unsigned long status; /* Runtime fault code (RPC_STATUS) */ - unsigned long reserved2; + unsigned int status; /* Runtime fault code (RPC_STATUS) */ + unsigned int reserved2; } RpcPktFaultHdr; typedef struct @@ -67,7 +67,7 @@ typedef struct RpcPktCommonHdr common; unsigned short max_tsize; /* Maximum transmission fragment size */ unsigned short max_rsize; /* Maximum receive fragment size */ - unsigned long assoc_gid; /* Associated group id */ + unsigned int assoc_gid; /* Associated group id */ unsigned char num_elements; /* Number of elements */ unsigned char padding[3]; /* Force alignment! */ unsigned short context_id; /* Presentation context identifier */ @@ -99,7 +99,7 @@ typedef struct RpcPktCommonHdr common; unsigned short max_tsize; /* Maximum transmission fragment size */ unsigned short max_rsize; /* Maximum receive fragment size */ - unsigned long assoc_gid; /* Associated group id */ + unsigned int assoc_gid; /* Associated group id */ /* * Following this header are these fields: * RpcAddressString server_address; @@ -120,6 +120,14 @@ typedef struct } protocols[1]; } RpcPktBindNAckHdr; +/* undocumented packet sent during RPC over HTTP */ +typedef struct +{ + RpcPktCommonHdr common; + unsigned short flags; + unsigned short num_data_items; +} RpcPktHttpHdr; + /* Union representing all possible packet headers */ typedef union { @@ -130,6 +138,7 @@ typedef union RpcPktBindHdr bind; RpcPktBindAckHdr bind_ack; RpcPktBindNAckHdr bind_nack; + RpcPktHttpHdr http; } RpcPktHdr; typedef struct @@ -138,7 +147,7 @@ typedef struct unsigned char auth_level; /* RPC_C_AUTHN_LEVEL* */ unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */ unsigned char auth_reserved; /* reserved, must be zero */ - unsigned long auth_context_id; /* unique value for the authenticated connection */ + unsigned int auth_context_id; /* unique value for the authenticated connection */ } RpcAuthVerifier; #define RPC_AUTH_VERIFIER_LEN(common_hdr) \ @@ -174,6 +183,7 @@ typedef struct #define PKT_SHUTDOWN 17 #define PKT_CO_CANCEL 18 #define PKT_ORPHANED 19 +#define PKT_HTTP 20 #define RESULT_ACCEPT 0 #define RESULT_USER_REJECTION 1 diff --git a/reactos/dll/win32/rpcrt4/rpc_epmap.c b/reactos/dll/win32/rpcrt4/rpc_epmap.c index 286ffbf9973..60c425550ad 100644 --- a/reactos/dll/win32/rpcrt4/rpc_epmap.c +++ b/reactos/dll/win32/rpcrt4/rpc_epmap.c @@ -32,7 +32,7 @@ #include "wine/exception.h" #include "rpc_binding.h" -#include "epm_c.h" +#include "epm.h" #include "epm_towers.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -116,7 +116,7 @@ static BOOL start_rpcss(void) static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle) { - RpcBinding *bind = (RpcBinding *)handle; + RpcBinding *bind = handle; const char *protseq = bind->Protseq; const char *network_addr = bind->NetworkAddr; @@ -127,7 +127,7 @@ static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle) static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_HANDLE *epm_handle) { - RpcBinding *bind = (RpcBinding *)handle; + RpcBinding *bind = handle; const char * pszEndpoint = NULL; RPC_STATUS status; RpcBinding* epm_bind; @@ -149,7 +149,7 @@ static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_H status = RpcBindingCopy(handle, epm_handle); if (status != RPC_S_OK) return status; - epm_bind = (RpcBinding*)*epm_handle; + epm_bind = *epm_handle; if (epm_bind->AuthInfo) { /* don't bother with authenticating against the EPM by default @@ -187,8 +187,8 @@ static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *__eptr) RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, UUID_VECTOR *UuidVector, RPC_CSTR Annotation ) { - PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; - unsigned long i; + PRPC_SERVER_INTERFACE If = IfSpec; + ULONG i; RPC_STATUS status = RPC_S_OK; error_status_t status2; ept_entry_t *entries; @@ -197,13 +197,13 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation)); TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); for (i=0; iCount; i++) { - RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); - TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq)); - TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint)); + RpcBinding* bind = BindingVector->BindingH[i]; + TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq)); + TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint)); } if (UuidVector) { for (i=0; iCount; i++) - TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); + TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); } if (!BindingVector->Count) return RPC_S_OK; @@ -222,10 +222,9 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind for (i = 0; i < BindingVector->Count; i++) { unsigned j; - RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); + RpcBinding* bind = BindingVector->BindingH[i]; for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++) { - int len = strlen((char *)Annotation); status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, bind->Protseq, bind->Endpoint, bind->NetworkAddr, @@ -236,7 +235,9 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind memcpy(&entries[i * UuidVector->Count].object, &UuidVector->Uuid[j], sizeof(GUID)); else memset(&entries[i].object, 0, sizeof(entries[i].object)); - memcpy(entries[i].annotation, Annotation, min(len + 1, ept_max_annotation_size)); + if (Annotation) + memcpy(entries[i].annotation, Annotation, + min(strlen((char *)Annotation) + 1, ept_max_annotation_size)); } } @@ -280,14 +281,29 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind return status; } +/*********************************************************************** + * RpcEpRegisterW (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcEpRegisterW( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, + UUID_VECTOR *UuidVector, RPC_WSTR Annotation ) +{ + LPSTR annA = RPCRT4_strdupWtoA(Annotation); + RPC_STATUS status; + + status = RpcEpRegisterA(IfSpec, BindingVector, UuidVector, (RPC_CSTR)annA); + + HeapFree(GetProcessHeap(), 0, annA); + return status; +} + /*********************************************************************** * RpcEpUnregister (RPCRT4.@) */ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, UUID_VECTOR *UuidVector ) { - PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; - unsigned long i; + PRPC_SERVER_INTERFACE If = IfSpec; + ULONG i; RPC_STATUS status = RPC_S_OK; error_status_t status2; ept_entry_t *entries; @@ -296,13 +312,13 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector); TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); for (i=0; iCount; i++) { - RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); - TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq)); - TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint)); + RpcBinding* bind = BindingVector->BindingH[i]; + TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq)); + TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint)); } if (UuidVector) { for (i=0; iCount; i++) - TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); + TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); } entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1)); @@ -319,7 +335,7 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin for (i = 0; i < BindingVector->Count; i++) { unsigned j; - RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); + RpcBinding* bind = BindingVector->BindingH[i]; for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++) { status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, @@ -372,8 +388,8 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin */ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec ) { - PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec; - RpcBinding* bind = (RpcBinding*)Binding; + PRPC_CLIENT_INTERFACE If = IfSpec; + RpcBinding* bind = Binding; RPC_STATUS status; error_status_t status2; handle_t handle; diff --git a/reactos/dll/win32/rpcrt4/rpc_message.c b/reactos/dll/win32/rpcrt4/rpc_message.c index e4f96a9179e..5e7c857acdd 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.c +++ b/reactos/dll/win32/rpcrt4/rpc_message.c @@ -59,13 +59,13 @@ enum secure_packet_direction static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg); -static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) +DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) { static const DWORD header_sizes[] = { sizeof(Header->request), 0, sizeof(Header->response), sizeof(Header->fault), 0, 0, 0, 0, 0, 0, 0, sizeof(Header->bind), sizeof(Header->bind_ack), sizeof(Header->bind_nack), - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, sizeof(Header->http) }; ULONG ret = 0; @@ -76,7 +76,7 @@ static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) if (Header->common.flags & RPC_FLG_OBJECT_UUID) ret += sizeof(UUID); } else { - TRACE("invalid packet type\n"); + WARN("invalid packet type %u\n", Header->common.ptype); } return ret; @@ -96,7 +96,7 @@ static int packet_has_auth_verifier(const RpcPktHdr *Header) } static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType, - unsigned long DataRepresentation) + ULONG DataRepresentation) { Header->common.rpc_ver = RPC_VER_MAJOR; Header->common.rpc_ver_minor = RPC_VER_MINOR; @@ -111,8 +111,8 @@ static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType /* Flags and fragment length are computed in RPCRT4_Send. */ } -static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, - unsigned long BufferLength, +static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation, + ULONG BufferLength, unsigned short ProcNum, UUID *ObjectUuid) { @@ -141,8 +141,7 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, - unsigned long BufferLength) +RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength) { RpcPktHdr *header; @@ -158,8 +157,7 @@ RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, - RPC_STATUS Status) +RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status) { RpcPktHdr *header; @@ -175,10 +173,10 @@ RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, - unsigned long AssocGroupId, + ULONG AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId) { @@ -202,7 +200,7 @@ RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, return header; } -static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation) +static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation) { RpcPktHdr *header; @@ -218,7 +216,7 @@ static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation) return header; } -RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor) { @@ -239,17 +237,17 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, - unsigned long AssocGroupId, + ULONG AssocGroupId, LPCSTR ServerAddress, - unsigned long Result, - unsigned long Reason, + unsigned short Result, + unsigned short Reason, const RPC_SYNTAX_IDENTIFIER *TransferId) { RpcPktHdr *header; - unsigned long header_size; + ULONG header_size; RpcAddressString *server_address; RpcResults *results; RPC_SYNTAX_IDENTIFIER *transfer_id; @@ -283,6 +281,118 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, return header; } +RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation, + unsigned short flags, + unsigned short num_data_items, + unsigned int payload_size) +{ + RpcPktHdr *header; + + header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->http) + payload_size); + if (header == NULL) { + ERR("failed to allocate memory\n"); + return NULL; + } + + RPCRT4_BuildCommonHeader(header, PKT_HTTP, DataRepresentation); + /* since the packet isn't current sent using RPCRT4_Send, set the flags + * manually here */ + header->common.flags = RPC_FLG_FIRST|RPC_FLG_LAST; + header->common.call_id = 0; + header->common.frag_len = sizeof(header->http) + payload_size; + header->http.flags = flags; + header->http.num_data_items = num_data_items; + + return header; +} + +#define WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, type, value) \ + do { \ + *(unsigned int *)(payload) = (type); \ + (payload) += 4; \ + *(unsigned int *)(payload) = (value); \ + (payload) += 4; \ + } while (0) + +#define WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, type, uuid) \ + do { \ + *(unsigned int *)(payload) = (type); \ + (payload) += 4; \ + *(UUID *)(payload) = (uuid); \ + (payload) += sizeof(UUID); \ + } while (0) + +#define WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, flow_control_increment, uuid) \ + do { \ + *(unsigned int *)(payload) = 0x00000001; \ + (payload) += 4; \ + *(unsigned int *)(payload) = (bytes_transmitted); \ + (payload) += 4; \ + *(unsigned int *)(payload) = (flow_control_increment); \ + (payload) += 4; \ + *(UUID *)(payload) = (uuid); \ + (payload) += sizeof(UUID); \ + } while (0) + +RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, + const UUID *connection_uuid, + const UUID *pipe_uuid, + const UUID *association_uuid) +{ + RpcPktHdr *header; + unsigned int size; + char *payload; + + size = 8 + 4 + sizeof(UUID) + 4 + sizeof(UUID) + 8; + if (!out_pipe) + size += 8 + 4 + sizeof(UUID); + + header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, flags, + out_pipe ? 4 : 6, size); + if (!header) return NULL; + payload = (char *)(&header->http+1); + + /* FIXME: what does this part of the payload do? */ + WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000006, 0x00000001); + + WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *connection_uuid); + WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *pipe_uuid); + + if (out_pipe) + /* FIXME: what does this part of the payload do? */ + WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000000, 0x00010000); + else + { + /* FIXME: what does this part of the payload do? */ + WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000004, 0x40000000); + /* FIXME: what does this part of the payload do? */ + WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000005, 0x000493e0); + + WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x0000000c, *association_uuid); + } + + return header; +} + +RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, + ULONG flow_control_increment, + const UUID *pipe_uuid) +{ + RpcPktHdr *header; + char *payload; + + header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x2, 2, + 5 * sizeof(ULONG) + sizeof(UUID)); + if (!header) return NULL; + payload = (char *)(&header->http+1); + + WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x0000000d, (server ? 0x0 : 0x3)); + + WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, + flow_control_increment, *pipe_uuid); + return header; +} + VOID RPCRT4_FreeHeader(RpcPktHdr *Header) { HeapFree(GetProcessHeap(), 0, Header); @@ -362,6 +472,206 @@ static RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status) } } +/* assumes the common header fields have already been validated */ +BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, + unsigned short data_len) +{ + unsigned short i; + BYTE *p = data; + + for (i = 0; i < hdr->http.num_data_items; i++) + { + ULONG type; + + if (data_len < sizeof(ULONG)) + return FALSE; + + type = *(ULONG *)p; + p += sizeof(ULONG); + data_len -= sizeof(ULONG); + + switch (type) + { + case 0x3: + case 0xc: + if (data_len < sizeof(GUID)) + return FALSE; + p += sizeof(GUID); + data_len -= sizeof(GUID); + break; + case 0x0: + case 0x2: + case 0x4: + case 0x5: + case 0x6: + case 0xd: + if (data_len < sizeof(ULONG)) + return FALSE; + p += sizeof(ULONG); + data_len -= sizeof(ULONG); + break; + case 0x1: + if (data_len < 24) + return FALSE; + p += 24; + data_len -= 24; + break; + default: + FIXME("unimplemented type 0x%x\n", type); + break; + } + } + return TRUE; +} + +/* assumes the HTTP packet has been validated */ +static unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data) +{ + ULONG type; + + type = *(ULONG *)data; + data += sizeof(ULONG); + + switch (type) + { + case 0x3: + case 0xc: + return data + sizeof(GUID); + case 0x0: + case 0x2: + case 0x4: + case 0x5: + case 0x6: + case 0xd: + return data + sizeof(ULONG); + case 0x1: + return data + 24; + default: + FIXME("unimplemented type 0x%x\n", type); + return data; + } +} + +#define READ_HTTP_PAYLOAD_FIELD_TYPE(data) *(ULONG *)(data) +#define GET_HTTP_PAYLOAD_FIELD_DATA(data) ((data) + sizeof(ULONG)) + +/* assumes the HTTP packet has been validated */ +RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, + unsigned char *data, ULONG *field1) +{ + ULONG type; + if (header->http.flags != 0x0) + { + ERR("invalid flags 0x%x\n", header->http.flags); + return RPC_S_PROTOCOL_ERROR; + } + if (header->http.num_data_items != 1) + { + ERR("invalid number of data items %d\n", header->http.num_data_items); + return RPC_S_PROTOCOL_ERROR; + } + type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); + if (type != 0x00000002) + { + ERR("invalid type 0x%08x\n", type); + return RPC_S_PROTOCOL_ERROR; + } + *field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); + return RPC_S_OK; +} + +/* assumes the HTTP packet has been validated */ +RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, + unsigned char *data, ULONG *field1, + ULONG *bytes_until_next_packet, + ULONG *field3) +{ + ULONG type; + if (header->http.flags != 0x0) + { + ERR("invalid flags 0x%x\n", header->http.flags); + return RPC_S_PROTOCOL_ERROR; + } + if (header->http.num_data_items != 3) + { + ERR("invalid number of data items %d\n", header->http.num_data_items); + return RPC_S_PROTOCOL_ERROR; + } + + type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); + if (type != 0x00000006) + { + ERR("invalid type for field 1: 0x%08x\n", type); + return RPC_S_PROTOCOL_ERROR; + } + *field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); + data = RPCRT4_NextHttpHeaderField(data); + + type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); + if (type != 0x00000000) + { + ERR("invalid type for field 2: 0x%08x\n", type); + return RPC_S_PROTOCOL_ERROR; + } + *bytes_until_next_packet = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); + data = RPCRT4_NextHttpHeaderField(data); + + type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); + if (type != 0x00000002) + { + ERR("invalid type for field 3: 0x%08x\n", type); + return RPC_S_PROTOCOL_ERROR; + } + *field3 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); + + return RPC_S_OK; +} + +RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, + unsigned char *data, BOOL server, + ULONG *bytes_transmitted, + ULONG *flow_control_increment, + UUID *pipe_uuid) +{ + ULONG type; + if (header->http.flags != 0x2) + { + ERR("invalid flags 0x%x\n", header->http.flags); + return RPC_S_PROTOCOL_ERROR; + } + if (header->http.num_data_items != 2) + { + ERR("invalid number of data items %d\n", header->http.num_data_items); + return RPC_S_PROTOCOL_ERROR; + } + + type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); + if (type != 0x0000000d) + { + ERR("invalid type for field 1: 0x%08x\n", type); + return RPC_S_PROTOCOL_ERROR; + } + if (*(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data) != (server ? 0x3 : 0x0)) + { + ERR("invalid type for 0xd field data: 0x%08x\n", *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data)); + return RPC_S_PROTOCOL_ERROR; + } + data = RPCRT4_NextHttpHeaderField(data); + + type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); + if (type != 0x00000001) + { + ERR("invalid type for field 2: 0x%08x\n", type); + return RPC_S_PROTOCOL_ERROR; + } + *bytes_transmitted = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); + *flow_control_increment = *(ULONG *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 4); + *pipe_uuid = *(UUID *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 8); + + return RPC_S_OK; +} + + static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, @@ -509,7 +819,7 @@ static RPC_STATUS RPCRT4_SendWithAuth(RpcConnection *Connection, RpcPktHdr *Head auth_hdr->auth_pad_length = auth_pad_len; auth_hdr->auth_reserved = 0; /* a unique number... */ - auth_hdr->auth_context_id = (unsigned long)Connection; + auth_hdr->auth_context_id = Connection->auth_context_id; if (AuthLength) memcpy(auth_hdr + 1, Auth, AuthLength); @@ -687,7 +997,7 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, } /* validates version and frag_len fields */ -static RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) +RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) { DWORD hdr_length; @@ -716,11 +1026,11 @@ static RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) } /*********************************************************************** - * RPCRT4_receive_fragment (internal) + * RPCRT4_default_receive_fragment (internal) * * Receive a fragment from a connection. */ -static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) +static RPC_STATUS RPCRT4_default_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) { RPC_STATUS status; DWORD hdr_length; @@ -794,6 +1104,14 @@ fail: return status; } +static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) +{ + if (Connection->ops->receive_fragment) + return Connection->ops->receive_fragment(Connection, Header, Payload); + else + return RPCRT4_default_receive_fragment(Connection, Header, Payload); +} + /*********************************************************************** * RPCRT4_ReceiveWithAuth (internal) * @@ -803,14 +1121,14 @@ fail: RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, - unsigned long *auth_length_out) + ULONG *auth_length_out) { RPC_STATUS status; DWORD hdr_length; unsigned short first_flag; - unsigned long data_length; - unsigned long buffer_length; - unsigned long auth_length = 0; + ULONG data_length; + ULONG buffer_length; + ULONG auth_length = 0; unsigned char *auth_data = NULL; RpcPktHdr *CurrentHeader = NULL; void *payload = NULL; @@ -874,7 +1192,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, } if (CurrentHeader->common.auth_len != auth_length) { - WARN("auth_len header field changed from %ld to %d\n", + WARN("auth_len header field changed from %d to %d\n", auth_length, CurrentHeader->common.auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; @@ -888,7 +1206,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, data_length = CurrentHeader->common.frag_len - hdr_length - header_auth_len; if (data_length + buffer_length > pMsg->BufferLength) { - TRACE("allocation hint exceeded, new buffer length = %ld\n", + TRACE("allocation hint exceeded, new buffer length = %d\n", data_length + buffer_length); pMsg->BufferLength = data_length + buffer_length; status = I_RpcReAllocateBuffer(pMsg); @@ -998,7 +1316,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, */ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg) { - RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RpcBinding* bind = pMsg->Handle; RpcConnection* conn; RPC_STATUS status = RPC_S_OK; @@ -1063,7 +1381,7 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) { RPC_STATUS status; - RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RpcBinding* bind = pMsg->Handle; TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength); @@ -1120,7 +1438,7 @@ static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg) */ RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) { - RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RpcBinding* bind = pMsg->Handle; TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer); @@ -1214,7 +1532,7 @@ static DWORD WINAPI async_notifier_proc(LPVOID p) */ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) { - RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RpcBinding* bind = pMsg->Handle; RpcConnection* conn; RPC_STATUS status; RpcPktHdr *hdr; @@ -1268,7 +1586,7 @@ static inline BOOL is_hard_error(RPC_STATUS status) */ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) { - RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RpcBinding* bind = pMsg->Handle; RPC_STATUS status; RpcPktHdr *hdr = NULL; RpcConnection *conn; @@ -1287,7 +1605,7 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) case PKT_RESPONSE: break; case PKT_FAULT: - ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); + ERR ("we got fault packet with status 0x%x\n", hdr->fault.status); status = NCA2RPC_STATUS(hdr->fault.status); if (is_hard_error(status)) goto fail; @@ -1360,7 +1678,7 @@ RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) */ RPC_STATUS WINAPI I_RpcAsyncSetHandle(PRPC_MESSAGE pMsg, PRPC_ASYNC_STATE pAsync) { - RpcBinding* bind = (RpcBinding*)pMsg->Handle; + RpcBinding* bind = pMsg->Handle; RpcConnection *conn; TRACE("(%p, %p)\n", pMsg, pAsync); diff --git a/reactos/dll/win32/rpcrt4/rpc_message.h b/reactos/dll/win32/rpcrt4/rpc_message.h index e4033882feb..aeeef0773e5 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.h +++ b/reactos/dll/win32/rpcrt4/rpc_message.h @@ -25,15 +25,25 @@ typedef unsigned int NCA_STATUS; -RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status); -RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength); -RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); -RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); -RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); +RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status); +RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength); +RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); +RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); +RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, LPCSTR ServerAddress, unsigned short Result, unsigned short Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); +RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation, unsigned short flags, unsigned short num_data_items, unsigned int payload_size); +RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, const UUID *connection_uuid, const UUID *pipe_uuid, const UUID *association_uuid); +RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, ULONG flow_control_increment, const UUID *pipe_uuid); VOID RPCRT4_FreeHeader(RpcPktHdr *Header); RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength); RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg); -RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, unsigned long *auth_length_out); +RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, ULONG *auth_length_out); +DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header); +RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr); + +BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, unsigned short data_len); +RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, unsigned char *data, ULONG *field1); +RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, unsigned char *data, ULONG *field1, ULONG *bytes_until_next_packet, ULONG *field3); +RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, unsigned char *data, BOOL server, ULONG *bytes_transmitted, ULONG *flow_control_increment, UUID *pipe_uuid); NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status); RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, ULONG count); diff --git a/reactos/dll/win32/rpcrt4/rpc_server.c b/reactos/dll/win32/rpcrt4/rpc_server.c index 473c7ba9328..34006396220 100644 --- a/reactos/dll/win32/rpcrt4/rpc_server.c +++ b/reactos/dll/win32/rpcrt4/rpc_server.c @@ -367,7 +367,7 @@ static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg) static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) { - RpcConnection* conn = (RpcConnection*)the_arg; + RpcConnection* conn = the_arg; RpcPktHdr *hdr; RPC_MESSAGE *msg; RPC_STATUS status; @@ -449,27 +449,23 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) /* start waiting */ res = cps->ops->wait_for_new_connection(cps, count, objs); - if (res == -1) - break; - else if (res == 0) + + if (res == -1 || (res == 0 && !std_listen)) { - if (!std_listen) - { + /* cleanup */ + cps->ops->free_wait_array(cps, objs); + EnterCriticalSection(&cps->cs); + for (conn = cps->conn; conn; conn = conn->Next) + RPCRT4_CloseConnection(conn); + LeaveCriticalSection(&cps->cs); + + if (res == 0 && !std_listen) SetEvent(cps->server_ready_event); - break; - } - set_ready_event = TRUE; + break; } + else if (res == 0) + set_ready_event = TRUE; } - cps->ops->free_wait_array(cps, objs); - EnterCriticalSection(&cps->cs); - /* close connections */ - conn = cps->conn; - while (conn) { - RPCRT4_CloseConnection(conn); - conn = conn->Next; - } - LeaveCriticalSection(&cps->cs); return 0; } @@ -570,11 +566,32 @@ static void RPCRT4_stop_listen(BOOL auto_listen) LeaveCriticalSection(&listen_cs); } -static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint) +static BOOL RPCRT4_protseq_is_endpoint_registered(RpcServerProtseq *protseq, const char *endpoint) +{ + RpcConnection *conn; + EnterCriticalSection(&protseq->cs); + for (conn = protseq->conn; conn; conn = conn->Next) + { + if (!endpoint || !strcmp(endpoint, conn->Endpoint)) + break; + } + LeaveCriticalSection(&protseq->cs); + return (conn != NULL); +} + +static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, const char *endpoint) { RPC_STATUS status; - status = ps->ops->open_endpoint(ps, endpoint); + EnterCriticalSection(&ps->cs); + + if (RPCRT4_protseq_is_endpoint_registered(ps, endpoint)) + status = RPC_S_OK; + else + status = ps->ops->open_endpoint(ps, endpoint); + + LeaveCriticalSection(&ps->cs); + if (status != RPC_S_OK) return status; @@ -608,11 +625,8 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) count = 0; LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { EnterCriticalSection(&ps->cs); - conn = ps->conn; - while (conn) { + for (conn = ps->conn; conn; conn = conn->Next) count++; - conn = conn->Next; - } LeaveCriticalSection(&ps->cs); } if (count) { @@ -624,12 +638,10 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) count = 0; LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { EnterCriticalSection(&ps->cs); - conn = ps->conn; - while (conn) { + for (conn = ps->conn; conn; conn = conn->Next) { RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count], conn); count++; - conn = conn->Next; } LeaveCriticalSection(&ps->cs); } @@ -681,7 +693,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_W * * Must be called with server_cs held. */ -static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) +static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps) { const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq); @@ -695,7 +707,7 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerPr if (!*ps) return RPC_S_OUT_OF_RESOURCES; (*ps)->MaxCalls = MaxCalls; - (*ps)->Protseq = Protseq; + (*ps)->Protseq = RPCRT4_strdupA(Protseq); (*ps)->ops = ops; (*ps)->MaxCalls = 0; (*ps)->conn = NULL; @@ -711,8 +723,19 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerPr return RPC_S_OK; } +/* must be called with server_cs held */ +static void destroy_serverprotoseq(RpcServerProtseq *ps) +{ + RPCRT4_strfree(ps->Protseq); + DeleteCriticalSection(&ps->cs); + CloseHandle(ps->mgr_mutex); + CloseHandle(ps->server_ready_event); + list_remove(&ps->entry); + HeapFree(GetProcessHeap(), 0, ps); +} + /* Finds a given protseq or creates a new one if one doesn't already exist */ -static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) +static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps) { RPC_STATUS status; RpcServerProtseq *cps; @@ -741,19 +764,18 @@ static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protse RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor, PRPC_POLICY lpPolicy ) { - char *szps = (char*)Protseq, *szep = (char*)Endpoint; RpcServerProtseq* ps; RPC_STATUS status; - TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a(szps), MaxCalls, - debugstr_a(szep), SecurityDescriptor, + TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a((const char *)Protseq), + MaxCalls, debugstr_a((const char *)Endpoint), SecurityDescriptor, lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps); if (status != RPC_S_OK) return status; - return RPCRT4_use_protseq(ps, szep); + return RPCRT4_use_protseq(ps, (const char *)Endpoint); } /*********************************************************************** @@ -764,13 +786,16 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC { RpcServerProtseq* ps; RPC_STATUS status; + LPSTR ProtseqA; LPSTR EndpointA; TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor, lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps); + ProtseqA = RPCRT4_strdupWtoA(Protseq); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps); + RPCRT4_strfree(ProtseqA); if (status != RPC_S_OK) return status; @@ -785,8 +810,16 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC */ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) { + RPC_STATUS status; + RpcServerProtseq* ps; + TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor); - return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor); + + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps); + if (status != RPC_S_OK) + return status; + + return RPCRT4_use_protseq(ps, NULL); } /*********************************************************************** @@ -794,8 +827,36 @@ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, */ RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) { + RPC_STATUS status; + RpcServerProtseq* ps; + LPSTR ProtseqA; + TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor); - return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor); + + ProtseqA = RPCRT4_strdupWtoA(Protseq); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps); + RPCRT4_strfree(ProtseqA); + if (status != RPC_S_OK) + return status; + + return RPCRT4_use_protseq(ps, NULL); +} + +void RPCRT4_destroy_all_protseqs(void) +{ + RpcServerProtseq *cps, *cursor2; + + if (listen_count != 0) + std_listen = FALSE; + + EnterCriticalSection(&server_cs); + LIST_FOR_EACH_ENTRY_SAFE(cps, cursor2, &protseqs, RpcServerProtseq, entry) + { + if (listen_count != 0) + RPCRT4_sync_with_server_thread(cps); + destroy_serverprotoseq(cps); + } + LeaveCriticalSection(&server_cs); } /*********************************************************************** @@ -823,7 +884,7 @@ RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn ) { - PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + PRPC_SERVER_INTERFACE If = IfSpec; RpcServerInterface* sif; unsigned int i; @@ -876,7 +937,7 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, */ RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete ) { - PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + PRPC_SERVER_INTERFACE If = IfSpec; HANDLE event = NULL; BOOL found = FALSE; BOOL completed = TRUE; diff --git a/reactos/dll/win32/rpcrt4/rpc_server.h b/reactos/dll/win32/rpcrt4/rpc_server.h index ffd5b016e4b..cacce794e34 100644 --- a/reactos/dll/win32/rpcrt4/rpc_server.h +++ b/reactos/dll/win32/rpcrt4/rpc_server.h @@ -56,7 +56,7 @@ struct protseq_ops * new connection was established */ int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array); /* opens the endpoint and optionally begins listening */ - RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint); + RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, const char *endpoint); }; typedef struct _RpcServerInterface @@ -79,4 +79,6 @@ typedef struct _RpcServerInterface void RPCRT4_new_client(RpcConnection* conn); const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq); +void RPCRT4_destroy_all_protseqs(void); + #endif /* __WINE_RPC_SERVER_H */ diff --git a/reactos/dll/win32/rpcrt4/rpc_transport.c b/reactos/dll/win32/rpcrt4/rpc_transport.c index 735a19df648..dddc5135c9d 100644 --- a/reactos/dll/win32/rpcrt4/rpc_transport.c +++ b/reactos/dll/win32/rpcrt4/rpc_transport.c @@ -40,6 +40,8 @@ # ifndef EAGAIN # define EAGAIN WSAEWOULDBLOCK # endif +# undef errno +# define errno WSAGetLastError() #else # include # ifdef HAVE_UNISTD_H @@ -64,16 +66,21 @@ # ifdef HAVE_SYS_POLL_H # include # endif +# ifdef HAVE_SYS_FILIO_H +# include +# endif +# ifdef HAVE_SYS_IOCTL_H +# include +# endif # define closesocket close +# define ioctlsocket ioctl #endif /* defined(__MINGW32__) || defined (_MSC_VER) */ -#include -#include - #include "windef.h" #include "winbase.h" #include "winnls.h" #include "winerror.h" +#include "wininet.h" #include "winternl.h" #include "wine/unicode.h" @@ -83,16 +90,17 @@ #include "wine/debug.h" #include "rpc_binding.h" +#include "rpc_assoc.h" #include "rpc_message.h" #include "rpc_server.h" #include "epm_towers.h" -#include "unix_func.h" - #ifndef SOL_TCP # define SOL_TCP IPPROTO_TCP #endif +#define DEFAULT_NCACN_HTTP_TIMEOUT (60 * 1000) + WINE_DEFAULT_DEBUG_CHANNEL(rpc); static RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection); @@ -258,12 +266,23 @@ static RPC_STATUS rpcrt4_ncalrpc_open(RpcConnection* Connection) return r; } -static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, LPSTR endpoint) +static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, const char *endpoint) { static const char prefix[] = "\\\\.\\pipe\\lrpc\\"; RPC_STATUS r; LPSTR pname; RpcConnection *Connection; + char generated_endpoint[22]; + + if (!endpoint) + { + static LONG lrpc_nameless_id; + DWORD process_id = GetCurrentProcessId(); + ULONG id = InterlockedIncrement(&lrpc_nameless_id); + snprintf(generated_endpoint, sizeof(generated_endpoint), + "LRPC%08x.%08x", process_id, id); + endpoint = generated_endpoint; + } r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); @@ -305,12 +324,23 @@ static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection) return r; } -static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint) +static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, const char *endpoint) { static const char prefix[] = "\\\\."; RPC_STATUS r; LPSTR pname; RpcConnection *Connection; + char generated_endpoint[21]; + + if (!endpoint) + { + static LONG np_nameless_id; + DWORD process_id = GetCurrentProcessId(); + ULONG id = InterlockedExchangeAdd(&np_nameless_id, 1 ); + snprintf(generated_endpoint, sizeof(generated_endpoint), + "\\\\pipe\\\\%08x.%03x", process_id, id); + endpoint = generated_endpoint; + } r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); @@ -340,7 +370,7 @@ static void rpcrt4_conn_np_handoff(RpcConnection_np *old_npc, RpcConnection_np * new_npc->ovl[0] = old_npc->ovl[0]; new_npc->ovl[1] = old_npc->ovl[1]; old_npc->pipe = 0; - memset(&old_npc->ovl, 0, sizeof(old_npc->ovl)); + memset(&old_npc->ovl[0], 0, sizeof(old_npc->ovl)); old_npc->listening = FALSE; } @@ -392,11 +422,11 @@ static int rpcrt4_conn_np_read(RpcConnection *Connection, ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, &npc->ovl[0]); if ((!ret || !bytes_read) && (GetLastError() != ERROR_IO_PENDING)) break; - ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE); - if (!ret && (GetLastError() != ERROR_MORE_DATA)) + if (!ret && GetLastError() == ERROR_MORE_DATA) + ret = TRUE; + if (!ret || !bytes_read) break; - bytes_left -= bytes_read; buf += bytes_read; } @@ -417,11 +447,11 @@ static int rpcrt4_conn_np_write(RpcConnection *Connection, ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, &npc->ovl[1]); if ((!ret || !bytes_written) && (GetLastError() != ERROR_IO_PENDING)) break; - ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE); - if (!ret && (GetLastError() != ERROR_MORE_DATA)) + if (!ret && GetLastError() == ERROR_MORE_DATA) + ret = TRUE; + if (!ret || !bytes_written) break; - bytes_left -= bytes_written; buf += bytes_written; } @@ -756,377 +786,10 @@ static RPC_STATUS rpcrt4_ncalrpc_parse_top_of_tower(const unsigned char *tower_d /**** ncacn_ip_tcp support ****/ -#ifdef HAVE_SOCKETPAIR - -typedef struct _RpcConnection_tcp -{ - RpcConnection common; - int sock; - int cancel_fds[2]; -} RpcConnection_tcp; - -static RpcConnection *rpcrt4_conn_tcp_alloc(void) -{ - RpcConnection_tcp *tcpc; - tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp)); - if (tcpc == NULL) - return NULL; - tcpc->sock = -1; - if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0) - { - ERR("socketpair() failed: %s\n", strerror(errno)); - HeapFree(GetProcessHeap(), 0, tcpc); - return NULL; - } - return &tcpc->common; -} - -static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int sock; - int ret; - struct addrinfo *ai; - struct addrinfo *ai_cur; - struct addrinfo hints; - - TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); - - if (tcpc->sock != -1) - return RPC_S_OK; - - hints.ai_flags = 0; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_addr = NULL; - hints.ai_canonname = NULL; - hints.ai_next = NULL; - - ret = getaddrinfo(Connection->NetworkAddr, Connection->Endpoint, &hints, &ai); - if (ret) - { - ERR("getaddrinfo for %s:%s failed: %s\n", Connection->NetworkAddr, - Connection->Endpoint, gai_strerror(ret)); - return RPC_S_SERVER_UNAVAILABLE; - } - - for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) - { - int val; - - if (TRACE_ON(rpc)) - { - char host[256]; - char service[256]; - getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, - host, sizeof(host), service, sizeof(service), - NI_NUMERICHOST | NI_NUMERICSERV); - TRACE("trying %s:%s\n", host, service); - } - - sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); - if (sock == -1) - { - WARN("socket() failed: %s\n", strerror(errno)); - continue; - } - - if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen)) - { - WARN("connect() failed: %s\n", strerror(errno)); - closesocket(sock); - continue; - } - - /* RPC depends on having minimal latency so disable the Nagle algorithm */ - val = 1; - setsockopt(sock, SOL_TCP, TCP_NODELAY, &val, sizeof(val)); - fcntl(sock, F_SETFL, O_NONBLOCK); /* make socket nonblocking */ - - tcpc->sock = sock; - - freeaddrinfo(ai); - TRACE("connected\n"); - return RPC_S_OK; - } - - freeaddrinfo(ai); - ERR("couldn't connect to %s:%s\n", Connection->NetworkAddr, Connection->Endpoint); - return RPC_S_SERVER_UNAVAILABLE; -} - -static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint) -{ - RPC_STATUS status = RPC_S_CANT_CREATE_ENDPOINT; - int sock; - int ret; - struct addrinfo *ai; - struct addrinfo *ai_cur; - struct addrinfo hints; - RpcConnection *first_connection = NULL; - - TRACE("(%p, %s)\n", protseq, endpoint); - - hints.ai_flags = AI_PASSIVE /* for non-localhost addresses */; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_addr = NULL; - hints.ai_canonname = NULL; - hints.ai_next = NULL; - - ret = getaddrinfo(NULL, endpoint, &hints, &ai); - if (ret) - { - ERR("getaddrinfo for port %s failed: %s\n", endpoint, - gai_strerror(ret)); - if ((ret == EAI_SERVICE) || (ret == EAI_NONAME)) - return RPC_S_INVALID_ENDPOINT_FORMAT; - return RPC_S_CANT_CREATE_ENDPOINT; - } - - for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) - { - RpcConnection_tcp *tcpc; - RPC_STATUS create_status; - - if (TRACE_ON(rpc)) - { - char host[256]; - char service[256]; - getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, - host, sizeof(host), service, sizeof(service), - NI_NUMERICHOST | NI_NUMERICSERV); - TRACE("trying %s:%s\n", host, service); - } - - sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); - if (sock == -1) - { - WARN("socket() failed: %s\n", strerror(errno)); - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen); - if (ret < 0) - { - WARN("bind failed: %s\n", strerror(errno)); - closesocket(sock); - if (errno == EADDRINUSE) - status = RPC_S_DUPLICATE_ENDPOINT; - else - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE, - protseq->Protseq, NULL, - endpoint, NULL, NULL, NULL); - if (create_status != RPC_S_OK) - { - closesocket(sock); - status = create_status; - continue; - } - - tcpc->sock = sock; - ret = listen(sock, protseq->MaxCalls); - if (ret < 0) - { - WARN("listen failed: %s\n", strerror(errno)); - RPCRT4_DestroyConnection(&tcpc->common); - status = RPC_S_OUT_OF_RESOURCES; - continue; - } - /* need a non-blocking socket, otherwise accept() has a potential - * race-condition (poll() says it is readable, connection drops, - * and accept() blocks until the next connection comes...) - */ - ret = fcntl(sock, F_SETFL, O_NONBLOCK); - if (ret < 0) - { - WARN("couldn't make socket non-blocking, error %d\n", ret); - RPCRT4_DestroyConnection(&tcpc->common); - status = RPC_S_OUT_OF_RESOURCES; - continue; - } - - tcpc->common.Next = first_connection; - first_connection = &tcpc->common; - } - - freeaddrinfo(ai); - - /* if at least one connection was created for an endpoint then - * return success */ - if (first_connection) - { - RpcConnection *conn; - - /* find last element in list */ - for (conn = first_connection; conn->Next; conn = conn->Next) - ; - - EnterCriticalSection(&protseq->cs); - conn->Next = protseq->conn; - protseq->conn = first_connection; - LeaveCriticalSection(&protseq->cs); - - TRACE("listening on %s\n", endpoint); - return RPC_S_OK; - } - - ERR("couldn't listen on port %s\n", endpoint); - return status; -} - -static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection *new_conn) -{ - int ret; - struct sockaddr_in address; - socklen_t addrsize; - RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn; - RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn; - - addrsize = sizeof(address); - ret = accept(server->sock, (struct sockaddr*) &address, &addrsize); - if (ret < 0) - { - ERR("Failed to accept a TCP connection: error %d\n", ret); - return RPC_S_OUT_OF_RESOURCES; - } - /* reset to blocking behaviour */ - fcntl(ret, F_SETFL, 0); - client->sock = ret; - TRACE("Accepted a new TCP connection\n"); - return RPC_S_OK; -} - -static int rpcrt4_conn_tcp_read(RpcConnection *Connection, - void *buffer, unsigned int count) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int bytes_read = 0; - do - { - int r = recv(tcpc->sock, (char *)buffer + bytes_read, count - bytes_read, 0); - if (!r) - return -1; - else if (r > 0) - bytes_read += r; - else if (errno != EAGAIN) - { - WARN("recv() failed: %s\n", strerror(errno)); - return -1; - } - else - { - struct pollfd pfds[2]; - pfds[0].fd = tcpc->sock; - pfds[0].events = POLLIN; - pfds[1].fd = tcpc->cancel_fds[0]; - pfds[1].events = POLLIN; - if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) - { - ERR("poll() failed: %s\n", strerror(errno)); - return -1; - } - if (pfds[1].revents & POLLIN) /* canceled */ - { - char dummy; - read(pfds[1].fd, &dummy, sizeof(dummy)); - return -1; - } - } - } while (bytes_read != count); - TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_read); - return bytes_read; -} - -static int rpcrt4_conn_tcp_write(RpcConnection *Connection, - const void *buffer, unsigned int count) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int bytes_written = 0; - do - { - int r = send(tcpc->sock, (const char *)buffer + bytes_written, count - bytes_written, 0); - if (r >= 0) - bytes_written += r; - else if (errno != EAGAIN) - return -1; - else - { - struct pollfd pfd; - pfd.fd = tcpc->sock; - pfd.events = POLLOUT; - if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR) - { - ERR("poll() failed: %s\n", strerror(errno)); - return -1; - } - } - } while (bytes_written != count); - TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_written); - return bytes_written; -} - -static int rpcrt4_conn_tcp_close(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - - TRACE("%d\n", tcpc->sock); - - if (tcpc->sock != -1) - closesocket(tcpc->sock); - tcpc->sock = -1; - close(tcpc->cancel_fds[0]); - close(tcpc->cancel_fds[1]); - return 0; -} - -static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - char dummy = 1; - - TRACE("%p\n", Connection); - - write(tcpc->cancel_fds[1], &dummy, 1); -} - -static int rpcrt4_conn_tcp_wait_for_incoming_data(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - struct pollfd pfds[2]; - - TRACE("%p\n", Connection); - - pfds[0].fd = tcpc->sock; - pfds[0].events = POLLIN; - pfds[1].fd = tcpc->cancel_fds[0]; - pfds[1].events = POLLIN; - if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) - { - ERR("poll() failed: %s\n", strerror(errno)); - return -1; - } - if (pfds[1].revents & POLLIN) /* canceled */ - { - char dummy; - read(pfds[1].fd, &dummy, sizeof(dummy)); - return -1; - } - - return 0; -} - -static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data, - const char *networkaddr, - const char *endpoint) +static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data, + const char *networkaddr, + unsigned char tcp_protid, + const char *endpoint) { twr_tcp_floor_t *tcp_floor; twr_ipv4_floor_t *ipv4_floor; @@ -1146,7 +809,7 @@ static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data, ipv4_floor = (twr_ipv4_floor_t *)tower_data; tcp_floor->count_lhs = sizeof(tcp_floor->protid); - tcp_floor->protid = EPM_PROTOCOL_TCP; + tcp_floor->protid = tcp_protid; tcp_floor->count_rhs = sizeof(tcp_floor->port); ipv4_floor->count_lhs = sizeof(ipv4_floor->protid); @@ -1191,10 +854,11 @@ static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data, return size; } -static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, - size_t tower_size, - char **networkaddr, - char **endpoint) +static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, + size_t tower_size, + char **networkaddr, + unsigned char tcp_protid, + char **endpoint) { const twr_tcp_floor_t *tcp_floor = (const twr_tcp_floor_t *)tower_data; const twr_ipv4_floor_t *ipv4_floor; @@ -1214,7 +878,7 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *to ipv4_floor = (const twr_ipv4_floor_t *)tower_data; if ((tcp_floor->count_lhs != sizeof(tcp_floor->protid)) || - (tcp_floor->protid != EPM_PROTOCOL_TCP) || + (tcp_floor->protid != tcp_protid) || (tcp_floor->count_rhs != sizeof(tcp_floor->port)) || (ipv4_floor->count_lhs != sizeof(ipv4_floor->protid)) || (ipv4_floor->protid != EPM_PROTOCOL_IP) || @@ -1259,6 +923,528 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *to return RPC_S_OK; } +typedef struct _RpcConnection_tcp +{ + RpcConnection common; + int sock; +#ifdef HAVE_SOCKETPAIR + int cancel_fds[2]; +#else + HANDLE sock_event; + HANDLE cancel_event; +#endif +} RpcConnection_tcp; + +#ifdef HAVE_SOCKETPAIR + +static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc) +{ + if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0) + { + ERR("socketpair() failed: %s\n", strerror(errno)); + return FALSE; + } + return TRUE; +} + +static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc) +{ + struct pollfd pfds[2]; + pfds[0].fd = tcpc->sock; + pfds[0].events = POLLIN; + pfds[1].fd = tcpc->cancel_fds[0]; + pfds[1].events = POLLIN; + if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) + { + ERR("poll() failed: %s\n", strerror(errno)); + return FALSE; + } + if (pfds[1].revents & POLLIN) /* canceled */ + { + char dummy; + read(pfds[1].fd, &dummy, sizeof(dummy)); + return FALSE; + } + return TRUE; +} + +static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc) +{ + struct pollfd pfd; + pfd.fd = tcpc->sock; + pfd.events = POLLOUT; + if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR) + { + ERR("poll() failed: %s\n", strerror(errno)); + return FALSE; + } + return TRUE; +} + +static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc) +{ + char dummy = 1; + + write(tcpc->cancel_fds[1], &dummy, 1); +} + +static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc) +{ + close(tcpc->cancel_fds[0]); + close(tcpc->cancel_fds[1]); +} + +#else /* HAVE_SOCKETPAIR */ + +static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc) +{ + static BOOL wsa_inited; + if (!wsa_inited) + { + WSADATA wsadata; + WSAStartup(MAKEWORD(2, 2), &wsadata); + /* Note: WSAStartup can be called more than once so we don't bother with + * making accesses to wsa_inited thread-safe */ + wsa_inited = TRUE; + } + tcpc->sock_event = CreateEventW(NULL, FALSE, FALSE, NULL); + tcpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL); + if (!tcpc->sock_event || !tcpc->cancel_event) + { + ERR("event creation failed\n"); + if (tcpc->sock_event) CloseHandle(tcpc->sock_event); + return FALSE; + } + return TRUE; +} + +static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc) +{ + HANDLE wait_handles[2]; + DWORD res; + if (WSAEventSelect(tcpc->sock, tcpc->sock_event, FD_READ | FD_CLOSE) == SOCKET_ERROR) + { + ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); + return FALSE; + } + wait_handles[0] = tcpc->sock_event; + wait_handles[1] = tcpc->cancel_event; + res = WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE); + switch (res) + { + case WAIT_OBJECT_0: + return TRUE; + case WAIT_OBJECT_0 + 1: + return FALSE; + default: + ERR("WaitForMultipleObjects() failed with error %d\n", GetLastError()); + return FALSE; + } +} + +static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc) +{ + DWORD res; + if (WSAEventSelect(tcpc->sock, tcpc->sock_event, FD_WRITE | FD_CLOSE) == SOCKET_ERROR) + { + ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); + return FALSE; + } + res = WaitForSingleObject(tcpc->sock_event, INFINITE); + switch (res) + { + case WAIT_OBJECT_0: + return TRUE; + default: + ERR("WaitForMultipleObjects() failed with error %d\n", GetLastError()); + return FALSE; + } +} + +static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc) +{ + SetEvent(tcpc->cancel_event); +} + +static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc) +{ + CloseHandle(tcpc->sock_event); + CloseHandle(tcpc->cancel_event); +} + +#endif + +static RpcConnection *rpcrt4_conn_tcp_alloc(void) +{ + RpcConnection_tcp *tcpc; + tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp)); + if (tcpc == NULL) + return NULL; + tcpc->sock = -1; + if (!rpcrt4_sock_wait_init(tcpc)) + { + HeapFree(GetProcessHeap(), 0, tcpc); + return NULL; + } + return &tcpc->common; +} + +static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int sock; + int ret; + struct addrinfo *ai; + struct addrinfo *ai_cur; + struct addrinfo hints; + + TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); + + if (tcpc->sock != -1) + return RPC_S_OK; + + hints.ai_flags = 0; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + ret = getaddrinfo(Connection->NetworkAddr, Connection->Endpoint, &hints, &ai); + if (ret) + { + ERR("getaddrinfo for %s:%s failed: %s\n", Connection->NetworkAddr, + Connection->Endpoint, gai_strerror(ret)); + return RPC_S_SERVER_UNAVAILABLE; + } + + for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) + { + int val; + u_long nonblocking; + + if (ai_cur->ai_family != AF_INET && ai_cur->ai_family != AF_INET6) + { + TRACE("skipping non-IP/IPv6 address family\n"); + continue; + } + + if (TRACE_ON(rpc)) + { + char host[256]; + char service[256]; + getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, + host, sizeof(host), service, sizeof(service), + NI_NUMERICHOST | NI_NUMERICSERV); + TRACE("trying %s:%s\n", host, service); + } + + sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); + if (sock == -1) + { + WARN("socket() failed: %s\n", strerror(errno)); + continue; + } + + if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen)) + { + WARN("connect() failed: %s\n", strerror(errno)); + closesocket(sock); + continue; + } + + /* RPC depends on having minimal latency so disable the Nagle algorithm */ + val = 1; + setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); + nonblocking = 1; + ioctlsocket(sock, FIONBIO, &nonblocking); + + tcpc->sock = sock; + + freeaddrinfo(ai); + TRACE("connected\n"); + return RPC_S_OK; + } + + freeaddrinfo(ai); + ERR("couldn't connect to %s:%s\n", Connection->NetworkAddr, Connection->Endpoint); + return RPC_S_SERVER_UNAVAILABLE; +} + +static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, const char *endpoint) +{ + RPC_STATUS status = RPC_S_CANT_CREATE_ENDPOINT; + int sock; + int ret; + struct addrinfo *ai; + struct addrinfo *ai_cur; + struct addrinfo hints; + RpcConnection *first_connection = NULL; + + TRACE("(%p, %s)\n", protseq, endpoint); + + hints.ai_flags = AI_PASSIVE /* for non-localhost addresses */; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + ret = getaddrinfo(NULL, endpoint ? endpoint : "0", &hints, &ai); + if (ret) + { + ERR("getaddrinfo for port %s failed: %s\n", endpoint, + gai_strerror(ret)); + if ((ret == EAI_SERVICE) || (ret == EAI_NONAME)) + return RPC_S_INVALID_ENDPOINT_FORMAT; + return RPC_S_CANT_CREATE_ENDPOINT; + } + + for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) + { + RpcConnection_tcp *tcpc; + RPC_STATUS create_status; + struct sockaddr_storage sa; + socklen_t sa_len; + char service[NI_MAXSERV]; + u_long nonblocking; + + if (ai_cur->ai_family != AF_INET && ai_cur->ai_family != AF_INET6) + { + TRACE("skipping non-IP/IPv6 address family\n"); + continue; + } + + if (TRACE_ON(rpc)) + { + char host[256]; + getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, + host, sizeof(host), service, sizeof(service), + NI_NUMERICHOST | NI_NUMERICSERV); + TRACE("trying %s:%s\n", host, service); + } + + sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); + if (sock == -1) + { + WARN("socket() failed: %s\n", strerror(errno)); + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + + ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen); + if (ret < 0) + { + WARN("bind failed: %s\n", strerror(errno)); + closesocket(sock); + if (errno == EADDRINUSE) + status = RPC_S_DUPLICATE_ENDPOINT; + else + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + + sa_len = sizeof(sa); + if (getsockname(sock, (struct sockaddr *)&sa, &sa_len)) + { + WARN("getsockname() failed: %s\n", strerror(errno)); + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + + ret = getnameinfo((struct sockaddr *)&sa, sa_len, + NULL, 0, service, sizeof(service), + NI_NUMERICSERV); + if (ret) + { + WARN("getnameinfo failed: %s\n", gai_strerror(ret)); + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + + create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE, + protseq->Protseq, NULL, + service, NULL, NULL, NULL); + if (create_status != RPC_S_OK) + { + closesocket(sock); + status = create_status; + continue; + } + + tcpc->sock = sock; + ret = listen(sock, protseq->MaxCalls); + if (ret < 0) + { + WARN("listen failed: %s\n", strerror(errno)); + RPCRT4_DestroyConnection(&tcpc->common); + status = RPC_S_OUT_OF_RESOURCES; + continue; + } + /* need a non-blocking socket, otherwise accept() has a potential + * race-condition (poll() says it is readable, connection drops, + * and accept() blocks until the next connection comes...) + */ + nonblocking = 1; + ret = ioctlsocket(sock, FIONBIO, &nonblocking); + if (ret < 0) + { + WARN("couldn't make socket non-blocking, error %d\n", ret); + RPCRT4_DestroyConnection(&tcpc->common); + status = RPC_S_OUT_OF_RESOURCES; + continue; + } + + tcpc->common.Next = first_connection; + first_connection = &tcpc->common; + + /* since IPv4 and IPv6 share the same port space, we only need one + * successful bind to listen for both */ + break; + } + + freeaddrinfo(ai); + + /* if at least one connection was created for an endpoint then + * return success */ + if (first_connection) + { + RpcConnection *conn; + + /* find last element in list */ + for (conn = first_connection; conn->Next; conn = conn->Next) + ; + + EnterCriticalSection(&protseq->cs); + conn->Next = protseq->conn; + protseq->conn = first_connection; + LeaveCriticalSection(&protseq->cs); + + TRACE("listening on %s\n", endpoint); + return RPC_S_OK; + } + + ERR("couldn't listen on port %s\n", endpoint); + return status; +} + +static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection *new_conn) +{ + int ret; + struct sockaddr_in address; + socklen_t addrsize; + RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn; + RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn; + u_long nonblocking; + + addrsize = sizeof(address); + ret = accept(server->sock, (struct sockaddr*) &address, &addrsize); + if (ret < 0) + { + ERR("Failed to accept a TCP connection: error %d\n", ret); + return RPC_S_OUT_OF_RESOURCES; + } + nonblocking = 1; + ioctlsocket(ret, FIONBIO, &nonblocking); + client->sock = ret; + TRACE("Accepted a new TCP connection\n"); + return RPC_S_OK; +} + +static int rpcrt4_conn_tcp_read(RpcConnection *Connection, + void *buffer, unsigned int count) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int bytes_read = 0; + do + { + int r = recv(tcpc->sock, (char *)buffer + bytes_read, count - bytes_read, 0); + if (!r) + return -1; + else if (r > 0) + bytes_read += r; + else if (errno != EAGAIN) + { + WARN("recv() failed: %s\n", strerror(errno)); + return -1; + } + else + { + if (!rpcrt4_sock_wait_for_recv(tcpc)) + return -1; + } + } while (bytes_read != count); + TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_read); + return bytes_read; +} + +static int rpcrt4_conn_tcp_write(RpcConnection *Connection, + const void *buffer, unsigned int count) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int bytes_written = 0; + do + { + int r = send(tcpc->sock, (const char *)buffer + bytes_written, count - bytes_written, 0); + if (r >= 0) + bytes_written += r; + else if (errno != EAGAIN) + return -1; + else + { + if (!rpcrt4_sock_wait_for_send(tcpc)) + return -1; + } + } while (bytes_written != count); + TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_written); + return bytes_written; +} + +static int rpcrt4_conn_tcp_close(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + + TRACE("%d\n", tcpc->sock); + + if (tcpc->sock != -1) + closesocket(tcpc->sock); + tcpc->sock = -1; + rpcrt4_sock_wait_destroy(tcpc); + return 0; +} + +static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + TRACE("%p\n", Connection); + rpcrt4_sock_wait_cancel(tcpc); +} + +static int rpcrt4_conn_tcp_wait_for_incoming_data(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + + TRACE("%p\n", Connection); + + if (!rpcrt4_sock_wait_for_recv(tcpc)) + return -1; + return 0; +} + +static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data, + const char *networkaddr, + const char *endpoint) +{ + return rpcrt4_ip_tcp_get_top_of_tower(tower_data, networkaddr, + EPM_PROTOCOL_TCP, endpoint); +} + +#ifdef HAVE_SOCKETPAIR + typedef struct _RpcServerProtseq_sock { RpcServerProtseq common; @@ -1398,8 +1584,1100 @@ static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq return 1; } +#else /* HAVE_SOCKETPAIR */ + +typedef struct _RpcServerProtseq_sock +{ + RpcServerProtseq common; + HANDLE mgr_event; +} RpcServerProtseq_sock; + +static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void) +{ + RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps)); + if (ps) + { + static BOOL wsa_inited; + if (!wsa_inited) + { + WSADATA wsadata; + WSAStartup(MAKEWORD(2, 2), &wsadata); + /* Note: WSAStartup can be called more than once so we don't bother with + * making accesses to wsa_inited thread-safe */ + wsa_inited = TRUE; + } + ps->mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL); + } + return &ps->common; +} + +static void rpcrt4_protseq_sock_signal_state_changed(RpcServerProtseq *protseq) +{ + RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common); + SetEvent(sockps->mgr_event); +} + +static void *rpcrt4_protseq_sock_get_wait_array(RpcServerProtseq *protseq, void *prev_array, unsigned int *count) +{ + HANDLE *objs = prev_array; + RpcConnection_tcp *conn; + RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common); + + EnterCriticalSection(&protseq->cs); + + /* open and count connections */ + *count = 1; + conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); + while (conn) + { + if (conn->sock != -1) + (*count)++; + conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); + } + + /* make array of connections */ + if (objs) + objs = HeapReAlloc(GetProcessHeap(), 0, objs, *count*sizeof(HANDLE)); + else + objs = HeapAlloc(GetProcessHeap(), 0, *count*sizeof(HANDLE)); + if (!objs) + { + ERR("couldn't allocate objs\n"); + LeaveCriticalSection(&protseq->cs); + return NULL; + } + + objs[0] = sockps->mgr_event; + *count = 1; + conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); + while (conn) + { + if (conn->sock != -1) + { + int res = WSAEventSelect(conn->sock, conn->sock_event, FD_ACCEPT); + if (res == SOCKET_ERROR) + ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); + else + { + objs[*count] = conn->sock_event; + (*count)++; + } + } + conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); + } + LeaveCriticalSection(&protseq->cs); + return objs; +} + +static void rpcrt4_protseq_sock_free_wait_array(RpcServerProtseq *protseq, void *array) +{ + HeapFree(GetProcessHeap(), 0, array); +} + +static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq, unsigned int count, void *wait_array) +{ + HANDLE b_handle; + HANDLE *objs = wait_array; + DWORD res; + RpcConnection *cconn; + RpcConnection_tcp *conn; + + if (!objs) + return -1; + + do + { + /* an alertable wait isn't strictly necessary, but due to our + * overlapped I/O implementation in Wine we need to free some memory + * by the file user APC being called, even if no completion routine was + * specified at the time of starting the async operation */ + res = WaitForMultipleObjectsEx(count, objs, FALSE, INFINITE, TRUE); + } while (res == WAIT_IO_COMPLETION); + + if (res == WAIT_OBJECT_0) + return 0; + else if (res == WAIT_FAILED) + { + ERR("wait failed with error %d\n", GetLastError()); + return -1; + } + else + { + b_handle = objs[res - WAIT_OBJECT_0]; + /* find which connection got a RPC */ + EnterCriticalSection(&protseq->cs); + conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); + while (conn) + { + if (b_handle == conn->sock_event) break; + conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); + } + cconn = NULL; + if (conn) + RPCRT4_SpawnConnection(&cconn, &conn->common); + else + ERR("failed to locate connection for handle %p\n", b_handle); + LeaveCriticalSection(&protseq->cs); + if (cconn) + { + RPCRT4_new_client(cconn); + return 1; + } + else return -1; + } +} + #endif /* HAVE_SOCKETPAIR */ +static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, + size_t tower_size, + char **networkaddr, + char **endpoint) +{ + return rpcrt4_ip_tcp_parse_top_of_tower(tower_data, tower_size, + networkaddr, EPM_PROTOCOL_TCP, + endpoint); +} + +/**** ncacn_http support ****/ +#if 0 +/* 60 seconds is the period native uses */ +#define HTTP_IDLE_TIME 60000 + +/* reference counted to avoid a race between a cancelled call's connection + * being destroyed and the asynchronous InternetReadFileEx call being + * completed */ +typedef struct _RpcHttpAsyncData +{ + LONG refs; + HANDLE completion_event; + INTERNET_BUFFERSA inet_buffers; + void *destination_buffer; /* the address that inet_buffers.lpvBuffer will be + * copied into when the call completes */ + CRITICAL_SECTION cs; +} RpcHttpAsyncData; + +static ULONG RpcHttpAsyncData_AddRef(RpcHttpAsyncData *data) +{ + return InterlockedIncrement(&data->refs); +} + +static ULONG RpcHttpAsyncData_Release(RpcHttpAsyncData *data) +{ + ULONG refs = InterlockedDecrement(&data->refs); + if (!refs) + { + TRACE("destroying async data %p\n", data); + CloseHandle(data->completion_event); + HeapFree(GetProcessHeap(), 0, data->inet_buffers.lpvBuffer); + DeleteCriticalSection(&data->cs); + HeapFree(GetProcessHeap(), 0, data); + } + return refs; +} + +typedef struct _RpcConnection_http +{ + RpcConnection common; + HINTERNET app_info; + HINTERNET session; + HINTERNET in_request; + HINTERNET out_request; + HANDLE timer_cancelled; + HANDLE cancel_event; + DWORD last_sent_time; + ULONG bytes_received; + ULONG flow_control_mark; /* send a control packet to the server when this many bytes received */ + ULONG flow_control_increment; /* number of bytes to increment flow_control_mark by */ + UUID connection_uuid; + UUID in_pipe_uuid; + UUID out_pipe_uuid; + RpcHttpAsyncData *async_data; +} RpcConnection_http; + +static RpcConnection *rpcrt4_ncacn_http_alloc(void) +{ + RpcConnection_http *httpc; + httpc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*httpc)); + if (!httpc) return NULL; + httpc->async_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcHttpAsyncData)); + if (!httpc->async_data) + { + HeapFree(GetProcessHeap(), 0, httpc); + return NULL; + } + TRACE("async data = %p\n", httpc->async_data); + httpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL); + httpc->async_data->refs = 1; + httpc->async_data->inet_buffers.dwStructSize = sizeof(INTERNET_BUFFERSA); + httpc->async_data->inet_buffers.lpvBuffer = NULL; + httpc->async_data->destination_buffer = NULL; + InitializeCriticalSection(&httpc->async_data->cs); + return &httpc->common; +} + +typedef struct _HttpTimerThreadData +{ + PVOID timer_param; + DWORD *last_sent_time; + HANDLE timer_cancelled; +} HttpTimerThreadData; + +static VOID rpcrt4_http_keep_connection_active_timer_proc(PVOID param, BOOLEAN dummy) +{ + HINTERNET in_request = param; + RpcPktHdr *idle_pkt; + + idle_pkt = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x0001, + 0, 0); + if (idle_pkt) + { + DWORD bytes_written; + InternetWriteFile(in_request, idle_pkt, idle_pkt->common.frag_len, &bytes_written); + RPCRT4_FreeHeader(idle_pkt); + } +} + +static inline DWORD rpcrt4_http_timer_calc_timeout(DWORD *last_sent_time) +{ + DWORD cur_time = GetTickCount(); + DWORD cached_last_sent_time = *last_sent_time; + return HTTP_IDLE_TIME - (cur_time - cached_last_sent_time > HTTP_IDLE_TIME ? 0 : cur_time - cached_last_sent_time); +} + +static DWORD CALLBACK rpcrt4_http_timer_thread(PVOID param) +{ + HttpTimerThreadData *data_in = param; + HttpTimerThreadData data; + DWORD timeout; + + data = *data_in; + HeapFree(GetProcessHeap(), 0, data_in); + + for (timeout = HTTP_IDLE_TIME; + WaitForSingleObject(data.timer_cancelled, timeout) == WAIT_TIMEOUT; + timeout = rpcrt4_http_timer_calc_timeout(data.last_sent_time)) + { + /* are we too soon after last send? */ + if (GetTickCount() - HTTP_IDLE_TIME < *data.last_sent_time) + continue; + rpcrt4_http_keep_connection_active_timer_proc(data.timer_param, TRUE); + } + + CloseHandle(data.timer_cancelled); + return 0; +} + +static VOID WINAPI rpcrt4_http_internet_callback( + HINTERNET hInternet, + DWORD_PTR dwContext, + DWORD dwInternetStatus, + LPVOID lpvStatusInformation, + DWORD dwStatusInformationLength) +{ + RpcHttpAsyncData *async_data = (RpcHttpAsyncData *)dwContext; + + switch (dwInternetStatus) + { + case INTERNET_STATUS_REQUEST_COMPLETE: + TRACE("INTERNET_STATUS_REQUEST_COMPLETED\n"); + if (async_data) + { + if (async_data->inet_buffers.lpvBuffer) + { + EnterCriticalSection(&async_data->cs); + if (async_data->destination_buffer) + { + memcpy(async_data->destination_buffer, + async_data->inet_buffers.lpvBuffer, + async_data->inet_buffers.dwBufferLength); + async_data->destination_buffer = NULL; + } + LeaveCriticalSection(&async_data->cs); + } + HeapFree(GetProcessHeap(), 0, async_data->inet_buffers.lpvBuffer); + async_data->inet_buffers.lpvBuffer = NULL; + SetEvent(async_data->completion_event); + RpcHttpAsyncData_Release(async_data); + } + break; + } +} + +static RPC_STATUS rpcrt4_http_check_response(HINTERNET hor) +{ + BOOL ret; + DWORD status_code; + DWORD size; + DWORD index; + WCHAR buf[32]; + WCHAR *status_text = buf; + TRACE("\n"); + + index = 0; + size = sizeof(status_code); + ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status_code, &size, &index); + if (!ret) + return GetLastError(); + if (status_code < 400) + return RPC_S_OK; + index = 0; + size = sizeof(buf); + ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_TEXT, status_text, &size, &index); + if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + status_text = HeapAlloc(GetProcessHeap(), 0, size); + ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_TEXT, status_text, &size, &index); + } + + ERR("server returned: %d %s\n", status_code, ret ? debugstr_w(status_text) : ""); + if(status_text != buf) HeapFree(GetProcessHeap(), 0, status_text); + + if (status_code == HTTP_STATUS_DENIED) + return ERROR_ACCESS_DENIED; + return RPC_S_SERVER_UNAVAILABLE; +} + +static RPC_STATUS rpcrt4_http_internet_connect(RpcConnection_http *httpc) +{ + static const WCHAR wszUserAgent[] = {'M','S','R','P','C',0}; + LPWSTR proxy = NULL; + LPWSTR user = NULL; + LPWSTR password = NULL; + LPWSTR servername = NULL; + const WCHAR *option; + INTERNET_PORT port = INTERNET_INVALID_PORT_NUMBER; /* use default port */ + + if (httpc->common.QOS && + (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP)) + { + const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_cred = httpc->common.QOS->qos->u.HttpCredentials; + if (http_cred->TransportCredentials) + { + WCHAR *p; + const SEC_WINNT_AUTH_IDENTITY_W *cred = http_cred->TransportCredentials; + ULONG len = cred->DomainLength + 1 + cred->UserLength; + user = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); + if (!user) + return RPC_S_OUT_OF_RESOURCES; + p = user; + if (cred->DomainLength) + { + memcpy(p, cred->Domain, cred->DomainLength * sizeof(WCHAR)); + p += cred->DomainLength; + *p = '\\'; + p++; + } + memcpy(p, cred->User, cred->UserLength * sizeof(WCHAR)); + p[cred->UserLength] = 0; + + password = RPCRT4_strndupW(cred->Password, cred->PasswordLength); + } + } + + for (option = httpc->common.NetworkOptions; option; + option = (strchrW(option, ',') ? strchrW(option, ',')+1 : NULL)) + { + static const WCHAR wszRpcProxy[] = {'R','p','c','P','r','o','x','y','=',0}; + static const WCHAR wszHttpProxy[] = {'H','t','t','p','P','r','o','x','y','=',0}; + + if (!strncmpiW(option, wszRpcProxy, sizeof(wszRpcProxy)/sizeof(wszRpcProxy[0])-1)) + { + const WCHAR *value_start = option + sizeof(wszRpcProxy)/sizeof(wszRpcProxy[0])-1; + const WCHAR *value_end; + const WCHAR *p; + + value_end = strchrW(option, ','); + if (!value_end) + value_end = value_start + strlenW(value_start); + for (p = value_start; p < value_end; p++) + if (*p == ':') + { + port = atoiW(p+1); + value_end = p; + break; + } + TRACE("RpcProxy value is %s\n", debugstr_wn(value_start, value_end-value_start)); + servername = RPCRT4_strndupW(value_start, value_end-value_start); + } + else if (!strncmpiW(option, wszHttpProxy, sizeof(wszHttpProxy)/sizeof(wszHttpProxy[0])-1)) + { + const WCHAR *value_start = option + sizeof(wszHttpProxy)/sizeof(wszHttpProxy[0])-1; + const WCHAR *value_end; + + value_end = strchrW(option, ','); + if (!value_end) + value_end = value_start + strlenW(value_start); + TRACE("HttpProxy value is %s\n", debugstr_wn(value_start, value_end-value_start)); + proxy = RPCRT4_strndupW(value_start, value_end-value_start); + } + else + FIXME("unhandled option %s\n", debugstr_w(option)); + } + + httpc->app_info = InternetOpenW(wszUserAgent, proxy ? INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_PRECONFIG, + NULL, NULL, INTERNET_FLAG_ASYNC); + if (!httpc->app_info) + { + HeapFree(GetProcessHeap(), 0, password); + HeapFree(GetProcessHeap(), 0, user); + ERR("InternetOpenW failed with error %d\n", GetLastError()); + return RPC_S_SERVER_UNAVAILABLE; + } + InternetSetStatusCallbackW(httpc->app_info, rpcrt4_http_internet_callback); + + /* if no RpcProxy option specified, set the HTTP server address to the + * RPC server address */ + if (!servername) + { + servername = HeapAlloc(GetProcessHeap(), 0, (strlen(httpc->common.NetworkAddr) + 1)*sizeof(WCHAR)); + if (!servername) + { + HeapFree(GetProcessHeap(), 0, password); + HeapFree(GetProcessHeap(), 0, user); + return RPC_S_OUT_OF_RESOURCES; + } + MultiByteToWideChar(CP_ACP, 0, httpc->common.NetworkAddr, -1, servername, strlen(httpc->common.NetworkAddr) + 1); + } + + httpc->session = InternetConnectW(httpc->app_info, servername, port, user, password, + INTERNET_SERVICE_HTTP, 0, 0); + + HeapFree(GetProcessHeap(), 0, password); + HeapFree(GetProcessHeap(), 0, user); + HeapFree(GetProcessHeap(), 0, servername); + + if (!httpc->session) + { + ERR("InternetConnectW failed with error %d\n", GetLastError()); + return RPC_S_SERVER_UNAVAILABLE; + } + + return RPC_S_OK; +} + +/* prepare the in pipe for use by RPC packets */ +static RPC_STATUS rpcrt4_http_prepare_in_pipe(HINTERNET in_request, RpcHttpAsyncData *async_data, + const UUID *connection_uuid, + const UUID *in_pipe_uuid, + const UUID *association_uuid) +{ + BYTE packet[44]; + BOOL ret; + RPC_STATUS status; + RpcPktHdr *hdr; + INTERNET_BUFFERSW buffers_in; + DWORD bytes_read, bytes_written; + + /* prepare in pipe */ + ResetEvent(async_data->completion_event); + RpcHttpAsyncData_AddRef(async_data); + ret = HttpSendRequestW(in_request, NULL, 0, NULL, 0); + if (!ret) + { + if (GetLastError() == ERROR_IO_PENDING) + WaitForSingleObject(async_data->completion_event, INFINITE); + else + { + RpcHttpAsyncData_Release(async_data); + ERR("HttpSendRequestW failed with error %d\n", GetLastError()); + return RPC_S_SERVER_UNAVAILABLE; + } + } + status = rpcrt4_http_check_response(in_request); + if (status != RPC_S_OK) return status; + + InternetReadFile(in_request, packet, 20, &bytes_read); + /* FIXME: do something with retrieved data */ + + memset(&buffers_in, 0, sizeof(buffers_in)); + buffers_in.dwStructSize = sizeof(buffers_in); + /* FIXME: get this from the registry */ + buffers_in.dwBufferTotal = 1024 * 1024 * 1024; /* 1Gb */ + ResetEvent(async_data->completion_event); + RpcHttpAsyncData_AddRef(async_data); + ret = HttpSendRequestExW(in_request, &buffers_in, NULL, 0, 0); + if (!ret) + { + if (GetLastError() == ERROR_IO_PENDING) + WaitForSingleObject(async_data->completion_event, INFINITE); + else + { + RpcHttpAsyncData_Release(async_data); + ERR("HttpSendRequestExW failed with error %d\n", GetLastError()); + return RPC_S_SERVER_UNAVAILABLE; + } + } + + TRACE("sending HTTP connect header to server\n"); + hdr = RPCRT4_BuildHttpConnectHeader(0, FALSE, connection_uuid, in_pipe_uuid, association_uuid); + if (!hdr) return RPC_S_OUT_OF_RESOURCES; + ret = InternetWriteFile(in_request, hdr, hdr->common.frag_len, &bytes_written); + RPCRT4_FreeHeader(hdr); + if (!ret) + { + ERR("InternetWriteFile failed with error %d\n", GetLastError()); + return RPC_S_SERVER_UNAVAILABLE; + } + + return RPC_S_OK; +} + +static RPC_STATUS rpcrt4_http_read_http_packet(HINTERNET request, RpcPktHdr *hdr, BYTE **data) +{ + BOOL ret; + DWORD bytes_read; + unsigned short data_len; + + ret = InternetReadFile(request, hdr, sizeof(hdr->common), &bytes_read); + if (!ret) + return RPC_S_SERVER_UNAVAILABLE; + if (hdr->common.ptype != PKT_HTTP || hdr->common.frag_len < sizeof(hdr->http)) + { + ERR("wrong packet type received %d or wrong frag_len %d\n", + hdr->common.ptype, hdr->common.frag_len); + return RPC_S_PROTOCOL_ERROR; + } + + ret = InternetReadFile(request, &hdr->common + 1, sizeof(hdr->http) - sizeof(hdr->common), &bytes_read); + if (!ret) + return RPC_S_SERVER_UNAVAILABLE; + + data_len = hdr->common.frag_len - sizeof(hdr->http); + if (data_len) + { + *data = HeapAlloc(GetProcessHeap(), 0, data_len); + if (!*data) + return RPC_S_OUT_OF_RESOURCES; + ret = InternetReadFile(request, *data, data_len, &bytes_read); + if (!ret) + { + HeapFree(GetProcessHeap(), 0, *data); + return RPC_S_SERVER_UNAVAILABLE; + } + } + else + *data = NULL; + + if (!RPCRT4_IsValidHttpPacket(hdr, *data, data_len)) + { + ERR("invalid http packet\n"); + return RPC_S_PROTOCOL_ERROR; + } + + return RPC_S_OK; +} + +/* prepare the out pipe for use by RPC packets */ +static RPC_STATUS rpcrt4_http_prepare_out_pipe(HINTERNET out_request, + RpcHttpAsyncData *async_data, + const UUID *connection_uuid, + const UUID *out_pipe_uuid, + ULONG *flow_control_increment) +{ + BYTE packet[20]; + BOOL ret; + RPC_STATUS status; + RpcPktHdr *hdr; + DWORD bytes_read; + BYTE *data_from_server; + RpcPktHdr pkt_from_server; + ULONG field1, field3; + + ResetEvent(async_data->completion_event); + RpcHttpAsyncData_AddRef(async_data); + ret = HttpSendRequestW(out_request, NULL, 0, NULL, 0); + if (!ret) + { + if (GetLastError() == ERROR_IO_PENDING) + WaitForSingleObject(async_data->completion_event, INFINITE); + else + { + RpcHttpAsyncData_Release(async_data); + ERR("HttpSendRequestW failed with error %d\n", GetLastError()); + return RPC_S_SERVER_UNAVAILABLE; + } + } + status = rpcrt4_http_check_response(out_request); + if (status != RPC_S_OK) return status; + + InternetReadFile(out_request, packet, 20, &bytes_read); + /* FIXME: do something with retrieved data */ + + hdr = RPCRT4_BuildHttpConnectHeader(0, TRUE, connection_uuid, out_pipe_uuid, NULL); + if (!hdr) return RPC_S_OUT_OF_RESOURCES; + ResetEvent(async_data->completion_event); + RpcHttpAsyncData_AddRef(async_data); + ret = HttpSendRequestW(out_request, NULL, 0, hdr, hdr->common.frag_len); + if (!ret) + { + if (GetLastError() == ERROR_IO_PENDING) + WaitForSingleObject(async_data->completion_event, INFINITE); + else + { + RpcHttpAsyncData_Release(async_data); + ERR("HttpSendRequestW failed with error %d\n", GetLastError()); + RPCRT4_FreeHeader(hdr); + return RPC_S_SERVER_UNAVAILABLE; + } + } + RPCRT4_FreeHeader(hdr); + status = rpcrt4_http_check_response(out_request); + if (status != RPC_S_OK) return status; + + status = rpcrt4_http_read_http_packet(out_request, &pkt_from_server, + &data_from_server); + if (status != RPC_S_OK) return status; + status = RPCRT4_ParseHttpPrepareHeader1(&pkt_from_server, data_from_server, + &field1); + HeapFree(GetProcessHeap(), 0, data_from_server); + if (status != RPC_S_OK) return status; + TRACE("received (%d) from first prepare header\n", field1); + + status = rpcrt4_http_read_http_packet(out_request, &pkt_from_server, + &data_from_server); + if (status != RPC_S_OK) return status; + status = RPCRT4_ParseHttpPrepareHeader2(&pkt_from_server, data_from_server, + &field1, flow_control_increment, + &field3); + HeapFree(GetProcessHeap(), 0, data_from_server); + if (status != RPC_S_OK) return status; + TRACE("received (0x%08x 0x%08x %d) from second prepare header\n", field1, *flow_control_increment, field3); + + return RPC_S_OK; +} + +static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection) +{ + RpcConnection_http *httpc = (RpcConnection_http *)Connection; + static const WCHAR wszVerbIn[] = {'R','P','C','_','I','N','_','D','A','T','A',0}; + static const WCHAR wszVerbOut[] = {'R','P','C','_','O','U','T','_','D','A','T','A',0}; + static const WCHAR wszRpcProxyPrefix[] = {'/','r','p','c','/','r','p','c','p','r','o','x','y','.','d','l','l','?',0}; + static const WCHAR wszColon[] = {':',0}; + static const WCHAR wszAcceptType[] = {'a','p','p','l','i','c','a','t','i','o','n','/','r','p','c',0}; + LPCWSTR wszAcceptTypes[] = { wszAcceptType, NULL }; + WCHAR *url; + RPC_STATUS status; + BOOL secure; + HttpTimerThreadData *timer_data; + HANDLE thread; + + TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); + + if (Connection->server) + { + ERR("ncacn_http servers not supported yet\n"); + return RPC_S_SERVER_UNAVAILABLE; + } + + if (httpc->in_request) + return RPC_S_OK; + + httpc->async_data->completion_event = CreateEventW(NULL, FALSE, FALSE, NULL); + + status = UuidCreate(&httpc->connection_uuid); + status = UuidCreate(&httpc->in_pipe_uuid); + status = UuidCreate(&httpc->out_pipe_uuid); + + status = rpcrt4_http_internet_connect(httpc); + if (status != RPC_S_OK) + return status; + + url = HeapAlloc(GetProcessHeap(), 0, sizeof(wszRpcProxyPrefix) + (strlen(Connection->NetworkAddr) + 1 + strlen(Connection->Endpoint))*sizeof(WCHAR)); + if (!url) + return RPC_S_OUT_OF_MEMORY; + memcpy(url, wszRpcProxyPrefix, sizeof(wszRpcProxyPrefix)); + MultiByteToWideChar(CP_ACP, 0, Connection->NetworkAddr, -1, url+sizeof(wszRpcProxyPrefix)/sizeof(wszRpcProxyPrefix[0])-1, strlen(Connection->NetworkAddr)+1); + strcatW(url, wszColon); + MultiByteToWideChar(CP_ACP, 0, Connection->Endpoint, -1, url+strlenW(url), strlen(Connection->Endpoint)+1); + + secure = httpc->common.QOS && + (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) && + (httpc->common.QOS->qos->u.HttpCredentials->Flags & RPC_C_HTTP_FLAG_USE_SSL); + + httpc->in_request = HttpOpenRequestW(httpc->session, wszVerbIn, url, NULL, NULL, + wszAcceptTypes, + (secure ? INTERNET_FLAG_SECURE : 0)|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE, + (DWORD_PTR)httpc->async_data); + if (!httpc->in_request) + { + ERR("HttpOpenRequestW failed with error %d\n", GetLastError()); + return RPC_S_SERVER_UNAVAILABLE; + } + httpc->out_request = HttpOpenRequestW(httpc->session, wszVerbOut, url, NULL, NULL, + wszAcceptTypes, + (secure ? INTERNET_FLAG_SECURE : 0)|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE, + (DWORD_PTR)httpc->async_data); + if (!httpc->out_request) + { + ERR("HttpOpenRequestW failed with error %d\n", GetLastError()); + return RPC_S_SERVER_UNAVAILABLE; + } + + status = rpcrt4_http_prepare_in_pipe(httpc->in_request, + httpc->async_data, + &httpc->connection_uuid, + &httpc->in_pipe_uuid, + &Connection->assoc->http_uuid); + if (status != RPC_S_OK) + return status; + + status = rpcrt4_http_prepare_out_pipe(httpc->out_request, + httpc->async_data, + &httpc->connection_uuid, + &httpc->out_pipe_uuid, + &httpc->flow_control_increment); + if (status != RPC_S_OK) + return status; + + httpc->flow_control_mark = httpc->flow_control_increment / 2; + httpc->last_sent_time = GetTickCount(); + httpc->timer_cancelled = CreateEventW(NULL, FALSE, FALSE, NULL); + + timer_data = HeapAlloc(GetProcessHeap(), 0, sizeof(*timer_data)); + if (!timer_data) + return ERROR_OUTOFMEMORY; + timer_data->timer_param = httpc->in_request; + timer_data->last_sent_time = &httpc->last_sent_time; + timer_data->timer_cancelled = httpc->timer_cancelled; + /* FIXME: should use CreateTimerQueueTimer when implemented */ + thread = CreateThread(NULL, 0, rpcrt4_http_timer_thread, timer_data, 0, NULL); + if (!thread) + { + HeapFree(GetProcessHeap(), 0, timer_data); + return GetLastError(); + } + CloseHandle(thread); + + return RPC_S_OK; +} + +static RPC_STATUS rpcrt4_ncacn_http_handoff(RpcConnection *old_conn, RpcConnection *new_conn) +{ + assert(0); + return RPC_S_SERVER_UNAVAILABLE; +} + +static int rpcrt4_ncacn_http_read(RpcConnection *Connection, + void *buffer, unsigned int count) +{ + RpcConnection_http *httpc = (RpcConnection_http *) Connection; + char *buf = buffer; + BOOL ret = TRUE; + unsigned int bytes_left = count; + + ResetEvent(httpc->async_data->completion_event); + while (bytes_left) + { + RpcHttpAsyncData_AddRef(httpc->async_data); + httpc->async_data->inet_buffers.dwBufferLength = bytes_left; + httpc->async_data->inet_buffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, bytes_left); + httpc->async_data->destination_buffer = buf; + ret = InternetReadFileExA(httpc->out_request, &httpc->async_data->inet_buffers, IRF_ASYNC, 0); + if (ret) + { + /* INTERNET_STATUS_REQUEST_COMPLETED won't be sent, so release our + * async ref now */ + RpcHttpAsyncData_Release(httpc->async_data); + memcpy(buf, httpc->async_data->inet_buffers.lpvBuffer, + httpc->async_data->inet_buffers.dwBufferLength); + HeapFree(GetProcessHeap(), 0, httpc->async_data->inet_buffers.lpvBuffer); + httpc->async_data->inet_buffers.lpvBuffer = NULL; + httpc->async_data->destination_buffer = NULL; + } + else + { + if (GetLastError() == ERROR_IO_PENDING) + { + HANDLE handles[2] = { httpc->async_data->completion_event, httpc->cancel_event }; + DWORD result = WaitForMultipleObjects(2, handles, FALSE, DEFAULT_NCACN_HTTP_TIMEOUT); + if (result == WAIT_OBJECT_0) + ret = TRUE; + else + { + TRACE("call cancelled\n"); + EnterCriticalSection(&httpc->async_data->cs); + httpc->async_data->destination_buffer = NULL; + LeaveCriticalSection(&httpc->async_data->cs); + break; + } + } + else + { + HeapFree(GetProcessHeap(), 0, httpc->async_data->inet_buffers.lpvBuffer); + httpc->async_data->inet_buffers.lpvBuffer = NULL; + httpc->async_data->destination_buffer = NULL; + RpcHttpAsyncData_Release(httpc->async_data); + break; + } + } + if (!httpc->async_data->inet_buffers.dwBufferLength) + break; + bytes_left -= httpc->async_data->inet_buffers.dwBufferLength; + buf += httpc->async_data->inet_buffers.dwBufferLength; + } + TRACE("%p %p %u -> %s\n", httpc->out_request, buffer, count, ret ? "TRUE" : "FALSE"); + return ret ? count : -1; +} + +static RPC_STATUS rpcrt4_ncacn_http_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) +{ + RpcConnection_http *httpc = (RpcConnection_http *) Connection; + RPC_STATUS status; + DWORD hdr_length; + LONG dwRead; + RpcPktCommonHdr common_hdr; + + *Header = NULL; + + TRACE("(%p, %p, %p)\n", Connection, Header, Payload); + +again: + /* read packet common header */ + dwRead = rpcrt4_ncacn_http_read(Connection, &common_hdr, sizeof(common_hdr)); + if (dwRead != sizeof(common_hdr)) { + WARN("Short read of header, %d bytes\n", dwRead); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + if (!memcmp(&common_hdr, "HTTP/1.1", sizeof("HTTP/1.1")) || + !memcmp(&common_hdr, "HTTP/1.0", sizeof("HTTP/1.0"))) + { + FIXME("server returned %s\n", debugstr_a((const char *)&common_hdr)); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + + status = RPCRT4_ValidateCommonHeader(&common_hdr); + if (status != RPC_S_OK) goto fail; + + hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr); + if (hdr_length == 0) { + WARN("header length == 0\n"); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + + *Header = HeapAlloc(GetProcessHeap(), 0, hdr_length); + if (!*Header) + { + status = RPC_S_OUT_OF_RESOURCES; + goto fail; + } + memcpy(*Header, &common_hdr, sizeof(common_hdr)); + + /* read the rest of packet header */ + dwRead = rpcrt4_ncacn_http_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr)); + if (dwRead != hdr_length - sizeof(common_hdr)) { + WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + + if (common_hdr.frag_len - hdr_length) + { + *Payload = HeapAlloc(GetProcessHeap(), 0, common_hdr.frag_len - hdr_length); + if (!*Payload) + { + status = RPC_S_OUT_OF_RESOURCES; + goto fail; + } + + dwRead = rpcrt4_ncacn_http_read(Connection, *Payload, common_hdr.frag_len - hdr_length); + if (dwRead != common_hdr.frag_len - hdr_length) + { + WARN("bad data length, %d/%d\n", dwRead, common_hdr.frag_len - hdr_length); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + } + else + *Payload = NULL; + + if ((*Header)->common.ptype == PKT_HTTP) + { + if (!RPCRT4_IsValidHttpPacket(*Header, *Payload, common_hdr.frag_len - hdr_length)) + { + ERR("invalid http packet of length %d bytes\n", (*Header)->common.frag_len); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + if ((*Header)->http.flags == 0x0001) + { + TRACE("http idle packet, waiting for real packet\n"); + if ((*Header)->http.num_data_items != 0) + { + ERR("HTTP idle packet should have no data items instead of %d\n", (*Header)->http.num_data_items); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + } + else if ((*Header)->http.flags == 0x0002) + { + ULONG bytes_transmitted; + ULONG flow_control_increment; + UUID pipe_uuid; + status = RPCRT4_ParseHttpFlowControlHeader(*Header, *Payload, + Connection->server, + &bytes_transmitted, + &flow_control_increment, + &pipe_uuid); + if (status != RPC_S_OK) + goto fail; + TRACE("received http flow control header (0x%x, 0x%x, %s)\n", + bytes_transmitted, flow_control_increment, debugstr_guid(&pipe_uuid)); + /* FIXME: do something with parsed data */ + } + else + { + FIXME("unrecognised http packet with flags 0x%04x\n", (*Header)->http.flags); + status = RPC_S_PROTOCOL_ERROR; + goto fail; + } + RPCRT4_FreeHeader(*Header); + *Header = NULL; + HeapFree(GetProcessHeap(), 0, *Payload); + *Payload = NULL; + goto again; + } + + /* success */ + status = RPC_S_OK; + + httpc->bytes_received += common_hdr.frag_len; + + TRACE("httpc->bytes_received = 0x%x\n", httpc->bytes_received); + + if (httpc->bytes_received > httpc->flow_control_mark) + { + RpcPktHdr *hdr = RPCRT4_BuildHttpFlowControlHeader(httpc->common.server, + httpc->bytes_received, + httpc->flow_control_increment, + &httpc->out_pipe_uuid); + if (hdr) + { + DWORD bytes_written; + BOOL ret2; + TRACE("sending flow control packet at 0x%x\n", httpc->bytes_received); + ret2 = InternetWriteFile(httpc->in_request, hdr, hdr->common.frag_len, &bytes_written); + RPCRT4_FreeHeader(hdr); + if (ret2) + httpc->flow_control_mark = httpc->bytes_received + httpc->flow_control_increment / 2; + } + } + +fail: + if (status != RPC_S_OK) { + RPCRT4_FreeHeader(*Header); + *Header = NULL; + HeapFree(GetProcessHeap(), 0, *Payload); + *Payload = NULL; + } + return status; +} + +static int rpcrt4_ncacn_http_write(RpcConnection *Connection, + const void *buffer, unsigned int count) +{ + RpcConnection_http *httpc = (RpcConnection_http *) Connection; + DWORD bytes_written; + BOOL ret; + + httpc->last_sent_time = ~0U; /* disable idle packet sending */ + ret = InternetWriteFile(httpc->in_request, buffer, count, &bytes_written); + httpc->last_sent_time = GetTickCount(); + TRACE("%p %p %u -> %s\n", httpc->in_request, buffer, count, ret ? "TRUE" : "FALSE"); + return ret ? bytes_written : -1; +} + +static int rpcrt4_ncacn_http_close(RpcConnection *Connection) +{ + RpcConnection_http *httpc = (RpcConnection_http *) Connection; + + TRACE("\n"); + + SetEvent(httpc->timer_cancelled); + if (httpc->in_request) + InternetCloseHandle(httpc->in_request); + httpc->in_request = NULL; + if (httpc->out_request) + InternetCloseHandle(httpc->out_request); + httpc->out_request = NULL; + if (httpc->app_info) + InternetCloseHandle(httpc->app_info); + httpc->app_info = NULL; + if (httpc->session) + InternetCloseHandle(httpc->session); + httpc->session = NULL; + RpcHttpAsyncData_Release(httpc->async_data); + if (httpc->cancel_event) + CloseHandle(httpc->cancel_event); + + return 0; +} + +static void rpcrt4_ncacn_http_cancel_call(RpcConnection *Connection) +{ + RpcConnection_http *httpc = (RpcConnection_http *) Connection; + + SetEvent(httpc->cancel_event); +} + +static int rpcrt4_ncacn_http_wait_for_incoming_data(RpcConnection *Connection) +{ + BOOL ret; + RpcConnection_http *httpc = (RpcConnection_http *) Connection; + + RpcHttpAsyncData_AddRef(httpc->async_data); + ret = InternetQueryDataAvailable(httpc->out_request, + &httpc->async_data->inet_buffers.dwBufferLength, IRF_ASYNC, 0); + if (ret) + { + /* INTERNET_STATUS_REQUEST_COMPLETED won't be sent, so release our + * async ref now */ + RpcHttpAsyncData_Release(httpc->async_data); + } + else + { + if (GetLastError() == ERROR_IO_PENDING) + { + HANDLE handles[2] = { httpc->async_data->completion_event, httpc->cancel_event }; + DWORD result = WaitForMultipleObjects(2, handles, FALSE, DEFAULT_NCACN_HTTP_TIMEOUT); + if (result != WAIT_OBJECT_0) + { + TRACE("call cancelled\n"); + return -1; + } + } + else + { + RpcHttpAsyncData_Release(httpc->async_data); + return -1; + } + } + + /* success */ + return 0; +} + +static size_t rpcrt4_ncacn_http_get_top_of_tower(unsigned char *tower_data, + const char *networkaddr, + const char *endpoint) +{ + return rpcrt4_ip_tcp_get_top_of_tower(tower_data, networkaddr, + EPM_PROTOCOL_HTTP, endpoint); +} + +static RPC_STATUS rpcrt4_ncacn_http_parse_top_of_tower(const unsigned char *tower_data, + size_t tower_size, + char **networkaddr, + char **endpoint) +{ + return rpcrt4_ip_tcp_parse_top_of_tower(tower_data, tower_size, + networkaddr, EPM_PROTOCOL_HTTP, + endpoint); +} +#endif static const struct connection_ops conn_protseq_list[] = { { "ncacn_np", { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_SMB }, @@ -1413,6 +2691,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_wait_for_incoming_data, rpcrt4_ncacn_np_get_top_of_tower, rpcrt4_ncacn_np_parse_top_of_tower, + NULL, }, { "ncalrpc", { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE }, @@ -1426,8 +2705,8 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_wait_for_incoming_data, rpcrt4_ncalrpc_get_top_of_tower, rpcrt4_ncalrpc_parse_top_of_tower, + NULL, }, -#ifdef HAVE_SOCKETPAIR { "ncacn_ip_tcp", { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP }, rpcrt4_conn_tcp_alloc, @@ -1440,7 +2719,23 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_tcp_wait_for_incoming_data, rpcrt4_ncacn_ip_tcp_get_top_of_tower, rpcrt4_ncacn_ip_tcp_parse_top_of_tower, - } + NULL, + }, +#if 0 + { "ncacn_http", + { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP }, + rpcrt4_ncacn_http_alloc, + rpcrt4_ncacn_http_open, + rpcrt4_ncacn_http_handoff, + rpcrt4_ncacn_http_read, + rpcrt4_ncacn_http_write, + rpcrt4_ncacn_http_close, + rpcrt4_ncacn_http_cancel_call, + rpcrt4_ncacn_http_wait_for_incoming_data, + rpcrt4_ncacn_http_get_top_of_tower, + rpcrt4_ncacn_http_parse_top_of_tower, + rpcrt4_ncacn_http_receive_fragment, + }, #endif }; @@ -1465,7 +2760,6 @@ static const struct protseq_ops protseq_list[] = rpcrt4_protseq_np_wait_for_new_connection, rpcrt4_protseq_ncalrpc_open_endpoint, }, -#ifdef HAVE_SOCKETPAIR { "ncacn_ip_tcp", rpcrt4_protseq_sock_alloc, @@ -1475,7 +2769,6 @@ static const struct protseq_ops protseq_list[] = rpcrt4_protseq_sock_wait_for_new_connection, rpcrt4_protseq_ncacn_ip_tcp_open_endpoint, }, -#endif }; #define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) @@ -1524,6 +2817,7 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS) { + static LONG next_id; const struct connection_ops *ops; RpcConnection* NewConnection; @@ -1551,6 +2845,7 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, NewConnection->attr = 0; if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo); NewConnection->AuthInfo = AuthInfo; + NewConnection->auth_context_id = InterlockedIncrement( &next_id ); NewConnection->encryption_auth_len = 0; NewConnection->signature_auth_len = 0; if (QOS) RpcQualityOfService_AddRef(QOS); diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild index 67f05aebcfb..59f9fe29ea4 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild +++ b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild @@ -14,6 +14,7 @@ user32 advapi32 secur32 + iphlpapi ws2_32 ntdll diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.spec b/reactos/dll/win32/rpcrt4/rpcrt4.spec index 4550889f62a..0a047691822 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.spec +++ b/reactos/dll/win32/rpcrt4/rpcrt4.spec @@ -116,8 +116,9 @@ @ stdcall NDRSContextUnmarshallEx(ptr ptr ptr) @ stub NDRcopy @ stdcall NdrAllocate(ptr long) -@ stub NdrAsyncClientCall +@ varargs NdrAsyncClientCall(ptr ptr) @ stub NdrAsyncServerCall +@ stdcall NdrAsyncStubCall(ptr ptr ptr ptr) @ stdcall NdrByteCountPointerBufferSize(ptr ptr ptr) @ stdcall NdrByteCountPointerFree(ptr ptr ptr) @ stdcall NdrByteCountPointerMarshall(ptr ptr ptr) @@ -370,7 +371,7 @@ @ stdcall RpcEpRegisterA(ptr ptr ptr str) @ stub RpcEpRegisterNoReplaceA @ stub RpcEpRegisterNoReplaceW -@ stub RpcEpRegisterW +@ stdcall RpcEpRegisterW(ptr ptr ptr wstr) @ stdcall RpcEpResolveBinding(ptr ptr) @ stdcall RpcEpUnregister(ptr ptr ptr) @ stub RpcErrorAddRecord # wxp diff --git a/reactos/dll/win32/rpcrt4/rpcrt4_main.c b/reactos/dll/win32/rpcrt4/rpcrt4_main.c index 537a00537bc..2cc7429bf29 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4_main.c +++ b/reactos/dll/win32/rpcrt4/rpcrt4_main.c @@ -43,8 +43,10 @@ #include "winuser.h" #include "winnt.h" #include "winternl.h" -#include "iptypes.h" -#include "iphlpapi.h" +#define _NTDEF_ +typedef NTSTATUS *PNTSTATUS; +#include "ntsecapi.h" +#undef _NTDEF_ #include "wine/unicode.h" #include "rpc.h" @@ -53,6 +55,7 @@ #include "rpcproxy.h" #include "rpc_binding.h" +#include "rpc_server.h" #include "wine/debug.h" @@ -60,15 +63,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(rpc); static UUID uuid_nil; -static CRITICAL_SECTION uuid_cs; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &uuid_cs, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": uuid_cs") } -}; -static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; - static CRITICAL_SECTION threaddata_cs; static CRITICAL_SECTION_DEBUG threaddata_cs_debug = { @@ -135,6 +129,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) break; case DLL_PROCESS_DETACH: + RPCRT4_destroy_all_protseqs(); break; } @@ -280,61 +275,6 @@ RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid) return RPC_S_OK; } -/* Number of 100ns ticks per clock tick. To be safe, assume that the clock - resolution is at least 1000 * 100 * (1/1000000) = 1/10 of a second */ -#define TICKS_PER_CLOCK_TICK 1000 -#define SECSPERDAY 86400 -#define TICKSPERSEC 10000000 -/* UUID system time starts at October 15, 1582 */ -#define SECS_15_OCT_1582_TO_1601 ((17 + 30 + 31 + 365 * 18 + 5) * SECSPERDAY) -#define TICKS_15_OCT_1582_TO_1601 ((ULONGLONG)SECS_15_OCT_1582_TO_1601 * TICKSPERSEC) - -static void RPC_UuidGetSystemTime(ULONGLONG *time) -{ - FILETIME ft; - - GetSystemTimeAsFileTime(&ft); - - *time = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime; - *time += TICKS_15_OCT_1582_TO_1601; -} - -/* Assume that a hardware address is at least 6 bytes long */ -#define ADDRESS_BYTES_NEEDED 6 - -static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) -{ - int i; - DWORD status = RPC_S_OK; - - ULONG buflen = sizeof(IP_ADAPTER_INFO); - PIP_ADAPTER_INFO adapter = HeapAlloc(GetProcessHeap(), 0, buflen); - - if (GetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) { - HeapFree(GetProcessHeap(), 0, adapter); - adapter = HeapAlloc(GetProcessHeap(), 0, buflen); - } - - if (GetAdaptersInfo(adapter, &buflen) == NO_ERROR) { - for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { - address[i] = adapter->Address[i]; - } - } - /* We can't get a hardware address, just use random numbers. - Set the multicast bit to prevent conflicts with real cards. */ - else { - for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { - address[i] = rand() & 0xff; - } - - address[0] |= 0x01; - status = RPC_S_UUID_LOCAL_ONLY; - } - - HeapFree(GetProcessHeap(), 0, adapter); - return status; -} - /************************************************************************* * UuidCreate [RPCRT4.@] * @@ -345,83 +285,26 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) * RPC_S_OK if successful. * RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique. * - * FIXME: No compensation for changes across reloading - * this dll or across reboots (e.g. clock going - * backwards and swapped network cards). The RFC - * suggests using NVRAM for storing persistent - * values. + * NOTES + * + * Follows RFC 4122, section 4.4 (Algorithms for Creating a UUID from + * Truly Random or Pseudo-Random Numbers) */ RPC_STATUS WINAPI UuidCreate(UUID *Uuid) { - static int initialised, count; - - ULONGLONG time; - static ULONGLONG timelast; - static WORD sequence; - - static DWORD status; - static BYTE address[MAX_ADAPTER_ADDRESS_LENGTH]; - - EnterCriticalSection(&uuid_cs); - - if (!initialised) { - RPC_UuidGetSystemTime(&timelast); - count = TICKS_PER_CLOCK_TICK; - - sequence = ((rand() & 0xff) << 8) + (rand() & 0xff); - sequence &= 0x1fff; - - status = RPC_UuidGetNodeAddress(address); - initialised = 1; - } - - /* Generate time element of the UUID. Account for going faster - than our clock as well as the clock going backwards. */ - while (1) { - RPC_UuidGetSystemTime(&time); - if (time > timelast) { - count = 0; - break; - } - if (time < timelast) { - sequence = (sequence + 1) & 0x1fff; - count = 0; - break; - } - if (count < TICKS_PER_CLOCK_TICK) { - count++; - break; - } - } - - timelast = time; - time += count; - - /* Pack the information into the UUID structure. */ - - Uuid->Data1 = (unsigned long)(time & 0xffffffff); - Uuid->Data2 = (unsigned short)((time >> 32) & 0xffff); - Uuid->Data3 = (unsigned short)((time >> 48) & 0x0fff); - - /* This is a version 1 UUID */ - Uuid->Data3 |= (1 << 12); - - Uuid->Data4[0] = sequence & 0xff; - Uuid->Data4[1] = (sequence & 0x3f00) >> 8; - Uuid->Data4[1] |= 0x80; - - Uuid->Data4[2] = address[0]; - Uuid->Data4[3] = address[1]; - Uuid->Data4[4] = address[2]; - Uuid->Data4[5] = address[3]; - Uuid->Data4[6] = address[4]; - Uuid->Data4[7] = address[5]; - - LeaveCriticalSection(&uuid_cs); + RtlGenRandom(Uuid, sizeof(*Uuid)); + /* Clear the version bits and set the version (4) */ + Uuid->Data3 &= 0x0fff; + Uuid->Data3 |= (4 << 12); + /* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as + * specified in RFC 4122, section 4.4. + */ + Uuid->Data4[0] &= 0x3f; + Uuid->Data4[0] |= 0x80; TRACE("%s\n", debugstr_guid(Uuid)); - return status; + return RPC_S_OK; } /************************************************************************* diff --git a/reactos/include/reactos/wine/config.h b/reactos/include/reactos/wine/config.h index b45073bd20c..cb26f59512c 100644 --- a/reactos/include/reactos/wine/config.h +++ b/reactos/include/reactos/wine/config.h @@ -975,12 +975,18 @@ `char[]'. */ #define YYTEXT_POINTER 1 +/* Define to a macro to output a .cfi assembly pseudo-op */ +#define __ASM_CFI(x) + /* Define to a macro to generate an assembly function directive */ #define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef" /* Define to a macro to generate an assembly name from a C symbol */ #define __ASM_NAME(name) "_" name +/* Define to a macro to generate an stdcall suffix */ +#define __ASM_STDCALL(args) "@" #args + /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ From 052e7f510657cc182465aeb7cab3c2c70ca61a22 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 14:13:22 +0000 Subject: [PATCH 039/140] [KS] - Silent debug traces on request of Christoph [CMIDRIVER] - Remove link hacks [WDMAUD_KERNEL] - Silent debug traces on request of Christoph - Reference notification event when the mixer is openend - Fix a bug in the notification handler (double free due entry not removed from list) svn path=/trunk/; revision=44132 --- reactos/drivers/ksfilter/ks/irp.c | 3 +- .../wdm/audio/drivers/CMIDriver/mintopo.cpp | 2 + .../audio/drivers/CMIDriver/mintopotables.hpp | 4 +- .../wdm/audio/drivers/CMIDriver/minwave.cpp | 5 +- .../audio/drivers/CMIDriver/minwavetables.hpp | 2 +- .../wdm/audio/drivers/directory.rbuild | 4 + .../drivers/wdm/audio/legacy/wdmaud/control.c | 12 ++- .../drivers/wdm/audio/legacy/wdmaud/entry.c | 6 +- .../drivers/wdm/audio/legacy/wdmaud/mixer.c | 88 +++++++++++-------- .../drivers/wdm/audio/legacy/wdmaud/wdmaud.h | 2 +- 10 files changed, 81 insertions(+), 47 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c index 4fdebe90302..e50490aad58 100644 --- a/reactos/drivers/ksfilter/ks/irp.c +++ b/reactos/drivers/ksfilter/ks/irp.c @@ -1790,7 +1790,8 @@ KspCreate( PKSIOBJECT_HEADER ObjectHeader; NTSTATUS Status; - DPRINT1("KS / CREATE\n"); + DPRINT("KS / CREATE\n"); + /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* get device extension */ diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp index 7ced5096ce1..48af5f33e41 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp @@ -33,6 +33,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma code_seg("PAGE") +const GUID KSPROPSETID_CMI = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFF}}; + HRESULT NTAPI CreateMiniportTopologyCMI(PUNKNOWN* Unknown, REFCLSID, PUNKNOWN UnknownOuter, POOL_TYPE PoolType) { //PAGED_CODE(); diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp index 96656d682f4..dce93b1cf44 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopotables.hpp @@ -354,13 +354,13 @@ static PCPROPERTY_ITEM PropertiesFilter[] = (PCPFNPROPERTY_HANDLER)PropertyHandler_ComponentId }, { - &GUID_NULL,//&KSPROPSETID_CMI, //HACK + &KSPROPSETID_CMI, KSPROPERTY_CMI_GET, KSPROPERTY_TYPE_GET, (PCPFNPROPERTY_HANDLER)PropertyHandler_Private }, { - &GUID_NULL,//&KSPROPSETID_CMI, //HACK + &KSPROPSETID_CMI, KSPROPERTY_CMI_SET, KSPROPERTY_TYPE_SET, (PCPFNPROPERTY_HANDLER)PropertyHandler_Private diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp index ddc9b588d19..4a0477133d5 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwave.cpp @@ -469,6 +469,9 @@ NTSTATUS CMiniportWaveCMI::validateFormat(PKSDATAFORMAT format, ULONG PinID, BOO STDMETHODIMP CMiniportWaveCMI::DataRangeIntersection(ULONG PinId, PKSDATARANGE ClientDataRange, PKSDATARANGE MyDataRange, ULONG OutputBufferLength, PVOID ResultantFormat, PULONG ResultantFormatLength) { //PAGED_CODE(); + static const GUID KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF = {0x00000092L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; + + DBGPRINT(("CMiniportWaveCMI[%p]::DataRangeIntersection(%d, %p, %p, %d, %p, %p)", this, PinId, ClientDataRange, MyDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength)); if (PinId == PIN_WAVE_AC3_RENDER_SINK) { @@ -482,7 +485,7 @@ STDMETHODIMP CMiniportWaveCMI::DataRangeIntersection(ULONG PinId, PKSDATARANGE C } - if (!IsEqualGUIDAligned(ClientDataRange->SubFormat, GUID_NULL)//KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) //HACK + if (!IsEqualGUIDAligned(ClientDataRange->SubFormat, KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF) && !IsEqualGUIDAligned(ClientDataRange->SubFormat, KSDATAFORMAT_SUBTYPE_WILDCARD)) { // check for Vista isAC3Pin = false; diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp index e380a1ce2fc..0c0326ca21c 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/minwavetables.hpp @@ -65,7 +65,7 @@ static KSDATARANGE_AUDIO WavePinDataRangesAC3Stream[] = 0, 0, STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO), - STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),//STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF), //HACK + STATICGUIDOF(KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF), STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX) }, MAX_CHANNELS_AC3, diff --git a/reactos/drivers/wdm/audio/drivers/directory.rbuild b/reactos/drivers/wdm/audio/drivers/directory.rbuild index af2a40e8340..dbabf9e8d5f 100644 --- a/reactos/drivers/wdm/audio/drivers/directory.rbuild +++ b/reactos/drivers/wdm/audio/drivers/directory.rbuild @@ -4,6 +4,10 @@ + + + + diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 3d4ceb2bb7e..6dda4dee4c2 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -86,7 +86,7 @@ WdmAudControlDeviceState( ULONG BytesReturned; PFILE_OBJECT FileObject; - //DPRINT1("WdmAudControlDeviceState\n"); + DPRINT("WdmAudControlDeviceState\n"); Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) @@ -105,7 +105,7 @@ WdmAudControlDeviceState( ObDereferenceObject(FileObject); - //DPRINT1("WdmAudControlDeviceState Status %x\n", Status); + DPRINT("WdmAudControlDeviceState Status %x\n", Status); return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); } @@ -155,6 +155,14 @@ WdmAudIoctlClose( SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); return STATUS_SUCCESS; } + else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE) + { + if (ClientInfo->hPins[Index].NotifyEvent) + { + ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent); + ClientInfo->hPins[Index].NotifyEvent = NULL; + } + } } SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO)); diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c index 7d774da359d..013be6aa020 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c @@ -22,7 +22,7 @@ WdmAudInstallDevice( NTSTATUS Status; PWDMAUD_DEVICE_EXTENSION DeviceExtension; - DPRINT1("WdmAudInstallDevice called\n"); + DPRINT("WdmAudInstallDevice called\n"); Status = IoCreateDevice(DriverObject, sizeof(WDMAUD_DEVICE_EXTENSION), @@ -95,7 +95,7 @@ NTAPI WdmAudUnload( IN PDRIVER_OBJECT driver) { - DPRINT1("WdmAudUnload called\n"); + DPRINT("WdmAudUnload called\n"); } NTSTATUS @@ -266,7 +266,7 @@ DriverEntry( IN PUNICODE_STRING Registry_path ) { - DPRINT1("Wdmaud.sys loaded\n"); + DPRINT("Wdmaud.sys loaded\n"); Driver->DriverUnload = WdmAudUnload; diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c index 845263994f1..946d45bb9c8 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -1752,25 +1752,39 @@ WdmAudControlOpenMixer( ULONG Index; PWDMAUD_HANDLE Handels; PWDMAUD_DEVICE_EXTENSION DeviceExtension; + NTSTATUS Status; + PKEVENT EventObject = NULL; DPRINT("WdmAudControlOpenMixer\n"); DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; - if (DeviceInfo->DeviceIndex >= DeviceExtension->MixerInfoCount) { /* mixer index doesnt exist */ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } + if (DeviceInfo->u.hNotifyEvent) + { + Status = ObReferenceObjectByHandle(DeviceInfo->u.hNotifyEvent, EVENT_MODIFY_STATE, ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Invalid notify event passed %p from client %p\n", DeviceInfo->u.hNotifyEvent, ClientInfo); + DbgBreakPoint(); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + } + + for(Index = 0; Index < ClientInfo->NumPins; Index++) { if (ClientInfo->hPins[Index].Handle == (HANDLE)DeviceInfo->DeviceIndex && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE) { /* re-use pseudo handle */ DeviceInfo->hDevice = (HANDLE)DeviceInfo->DeviceIndex; - ClientInfo->hPins[Index].hNotifyEvent = DeviceInfo->u.hNotifyEvent; + ClientInfo->hPins[Index].NotifyEvent = EventObject; return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); } } @@ -1788,7 +1802,7 @@ WdmAudControlOpenMixer( ClientInfo->hPins = Handels; ClientInfo->hPins[ClientInfo->NumPins].Handle = (HANDLE)DeviceInfo->DeviceIndex; ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE; - ClientInfo->hPins[ClientInfo->NumPins].hNotifyEvent = DeviceInfo->u.hNotifyEvent; + ClientInfo->hPins[ClientInfo->NumPins].NotifyEvent = EventObject; ClientInfo->NumPins++; } else @@ -1849,7 +1863,7 @@ WdmAudGetLineInfo( if (DeviceInfo->u.MixLine.dwSource >= MixerLineSrc->Line.cConnections) { - DPRINT1("dwSource %u Destinations %u\n", DeviceInfo->u.MixLine.dwSource, MixerLineSrc->Line.cConnections); + DPRINT1("dwSource %u > Destinations %u\n", DeviceInfo->u.MixLine.dwSource, MixerLineSrc->Line.cConnections); /* invalid parameter */ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); } @@ -1903,7 +1917,7 @@ WdmAudGetLineInfo( return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); } - DPRINT1("Flags %x\n", DeviceInfo->Flags); + DPRINT("Flags %x\n", DeviceInfo->Flags); UNIMPLEMENTED; //DbgBreakPoint(); @@ -1960,14 +1974,14 @@ WdmAudGetLineControls( Index = 0; for(Index = 0; Index < MixerLineSrc->Line.cControls; Index++) { - DPRINT1("dwControlType %x\n", MixerLineSrc->LineControls[Index].dwControlType); + DPRINT("dwControlType %x\n", MixerLineSrc->LineControls[Index].dwControlType); if (DeviceInfo->u.MixControls.dwControlType == MixerLineSrc->LineControls[Index].dwControlType) { RtlMoveMemory(DeviceInfo->u.MixControls.pamxctrl, &MixerLineSrc->LineControls[Index], sizeof(MIXERCONTROLW)); return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); } } - DPRINT1("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", DeviceInfo->u.MixControls.dwControlType, DeviceInfo->u.MixControls.dwLineID, MixerLineSrc->Line.cControls); + DPRINT("DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n", DeviceInfo->u.MixControls.dwControlType, DeviceInfo->u.MixControls.dwLineID, MixerLineSrc->Line.cControls); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); } else if (DeviceInfo->Flags == MIXER_GETLINECONTROLSF_ONEBYID) @@ -1977,7 +1991,7 @@ WdmAudGetLineControls( /* invalid parameter */ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); } - DPRINT1("MixerId %u ControlId %u\n",(ULONG_PTR)DeviceInfo->hDevice, DeviceInfo->u.MixControls.dwControlID); + DPRINT("MixerId %u ControlId %u\n",(ULONG_PTR)DeviceInfo->hDevice, DeviceInfo->u.MixControls.dwControlID); Status = GetMixerControlById(&DeviceExtension->MixerInfo[(ULONG_PTR)DeviceInfo->hDevice], DeviceInfo->u.MixControls.dwControlID, NULL, &MixerControl, NULL); if (NT_SUCCESS(Status)) { @@ -2047,7 +2061,7 @@ SetGetControlDetails( *InputValue = Value; } - DPRINT1("Status %x bSet %u NodeId %u Value %d PropertyId %u\n", Status, bSet, NodeId, Value, PropertyId); + DPRINT("Status %x bSet %u NodeId %u Value %d PropertyId %u\n", Status, bSet, NodeId, Value, PropertyId); return Status; } @@ -2061,11 +2075,9 @@ NotifyWdmAudClients( PWDMAUD_DEVICE_EXTENSION DeviceExtension; PLIST_ENTRY Entry; PWDMAUD_CLIENT CurClient; - PKEVENT EventObject; PMIXER_EVENT Event; KIRQL OldIrql; ULONG Index; - NTSTATUS Status; /* get device extension */ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; @@ -2085,22 +2097,13 @@ NotifyWdmAudClients( /* now iterate through all pins and try to find an matching handle */ for(Index = 0; Index < CurClient->NumPins; Index++) { - if (CurClient->hPins[Index].Handle == hMixer && CurClient->hPins[Index].Type == MIXER_DEVICE_TYPE && CurClient->hPins[Index].hNotifyEvent) + if (CurClient->hPins[Index].Handle == hMixer && CurClient->hPins[Index].Type == MIXER_DEVICE_TYPE && CurClient->hPins[Index].NotifyEvent) { - /* found a matching mixer handle and a valid notify event */ - Status = ObReferenceObjectByHandle(CurClient->hPins[Index].hNotifyEvent, EVENT_MODIFY_STATE, ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Invalid notify event passed %p from client %p\n", CurClient->hPins[Index].hNotifyEvent, CurClient); - break; - } - /* allocate event entry */ Event = (PMIXER_EVENT)ExAllocatePool(NonPagedPool, sizeof(MIXER_EVENT)); if (!Event) { /* no memory */ - ObDereferenceObject(EventObject); return STATUS_INSUFFICIENT_RESOURCES; } @@ -2112,11 +2115,12 @@ NotifyWdmAudClients( /* insert event entry */ InsertTailList(&CurClient->MixerEventList, &Event->Entry); - /* now signal the event */ - KeSetEvent(EventObject, 0, FALSE); + DPRINT("Notifying %p hMixer %p Value %x NotificationType %u\n", CurClient->hPins[Index].NotifyEvent, hMixer, Value, NotificationType); + + /* now signal the event */ + KeSetEvent(CurClient->hPins[Index].NotifyEvent, 0, FALSE); + - /* dereference event */ - ObDereferenceObject(EventObject); /* search next client */ break; @@ -2179,6 +2183,24 @@ SetGetMuteControlDetails( return Status; } +ULONG +GetVolumeControlIndex( + LPMIXERVOLUME_DATA VolumeData, + LONG Value) +{ + ULONG Index; + + for(Index = 0; Index < VolumeData->ValuesCount; Index++) + { + if (VolumeData->Values[Index] > Value) + { + return VolumeData->InputSteppingDelta * Index; + } + } + return VolumeData->InputSteppingDelta * (VolumeData->ValuesCount-1); +} + + NTSTATUS SetGetVolumeControlDetails( IN PDEVICE_OBJECT DeviceObject, @@ -2191,6 +2213,7 @@ SetGetVolumeControlDetails( { LPMIXERCONTROLDETAILS_UNSIGNED Input; LONG Value, Index, Channel = 0; + ULONG dwValue; NTSTATUS Status; LPMIXERVOLUME_DATA VolumeData; @@ -2234,16 +2257,9 @@ SetGetVolumeControlDetails( if (!bSet) { - for(Index = 0; Index < VolumeData->ValuesCount; Index++) - { - if (VolumeData->Values[Index] > Value) - { - /* FIXME SEH */ - Input->dwValue = VolumeData->InputSteppingDelta * Index; - return Status; - } - } - Input->dwValue = VolumeData->InputSteppingDelta * (VolumeData->ValuesCount-1); + dwValue = GetVolumeControlIndex(VolumeData, (LONG)Value); + /* FIXME SEH */ + Input->dwValue = dwValue; } else { @@ -2283,6 +2299,7 @@ WdmAudGetMixerEvent( if (Event->hMixer == DeviceInfo->hDevice) { /* found an event for that particular device */ + RemoveEntryList(&Event->Entry); break; } @@ -2293,7 +2310,6 @@ WdmAudGetMixerEvent( Entry = Entry->Flink; } - /* release client context lock */ KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql); diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h index bc27c367f0f..c8e53320e1e 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h @@ -31,7 +31,7 @@ typedef struct SOUND_DEVICE_TYPE Type; ULONG FilterId; ULONG PinId; - HANDLE hNotifyEvent; + PRKEVENT NotifyEvent; }WDMAUD_HANDLE, *PWDMAUD_HANDLE; typedef struct From ccc63ddced5d4dce0ad7ee544cf143abb19103d6 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 14:22:11 +0000 Subject: [PATCH 040/140] [PSDK] - Fix MIXEROPENDESC struct(x64 compability issue) [MMEBUDDY] - Fix usage of MIXEROPENDESC [WDMAUD.DRV] - Implement a listening thread which waits for volume level / mute control changes svn path=/trunk/; revision=44133 --- reactos/dll/win32/wdmaud.drv/wdmaud.c | 80 +++++++++++++++++++ reactos/include/psdk/mmddk.h | 7 +- reactos/include/reactos/libs/sound/mmebuddy.h | 10 ++- .../drivers/sound/mmebuddy/deviceinstance.c | 4 +- 4 files changed, 92 insertions(+), 9 deletions(-) diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index 48d0b687e25..325df20f881 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -260,6 +260,13 @@ CloseWdmSoundDevice( NULL); } + if (DeviceType == MIXER_DEVICE_TYPE) + { + SetEvent(SoundDeviceInstance->hStopEvent); + CloseHandle(SoundDeviceInstance->hStopEvent); + CloseHandle(SoundDeviceInstance->hNotifyEvent); + } + --OpenCount; if ( OpenCount < 1 ) @@ -283,6 +290,62 @@ QueryWdmWaveDeviceFormatSupport( } +DWORD +WINAPI +MixerEventThreadRoutine( + LPVOID Parameter) +{ + HANDLE WaitObjects[2]; + DWORD dwResult; + MMRESULT Result; + WDMAUD_DEVICE_INFO DeviceInfo; + PSOUND_DEVICE_INSTANCE Instance = (PSOUND_DEVICE_INSTANCE)Parameter; + + /* setup wait objects */ + WaitObjects[0] = Instance->hNotifyEvent; + WaitObjects[1] = Instance->hStopEvent; + + /* zero device info */ + ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); + + DeviceInfo.hDevice = Instance->Handle; + DeviceInfo.DeviceType = MIXER_DEVICE_TYPE; + + do + { + dwResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE); + + if (dwResult == WAIT_OBJECT_0 + 1) + { + /* stop event was signalled */ + break; + } + + Result = SyncOverlappedDeviceIoControl(KernelHandle, + IOCTL_GET_MIXER_EVENT, + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + NULL); + + if (Result == MMSYSERR_NOERROR) + { + DriverCallback(Instance->WinMM.ClientCallback, + HIWORD(Instance->WinMM.Flags), + Instance->WinMM.Handle, + DeviceInfo.u.MixerEvent.NotificationType, + Instance->WinMM.ClientCallbackInstanceData, + (DWORD_PTR)DeviceInfo.u.MixerEvent.Value, + 0); + } + }while(TRUE); + + /* done */ + return 0; +} + + MMRESULT SetWdmMixerDeviceFormat( IN PSOUND_DEVICE_INSTANCE Instance, @@ -292,6 +355,7 @@ SetWdmMixerDeviceFormat( { MMRESULT Result; WDMAUD_DEVICE_INFO DeviceInfo; + HANDLE hThread; if (Instance->Handle != KernelHandle) { @@ -299,10 +363,18 @@ SetWdmMixerDeviceFormat( return MMSYSERR_NOERROR; } + Instance->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if ( ! Instance->hNotifyEvent ) + return MMSYSERR_NOMEM; + + Instance->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL); + if ( ! Instance->hStopEvent ) + return MMSYSERR_NOMEM; ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); DeviceInfo.DeviceType = MIXER_DEVICE_TYPE; DeviceInfo.DeviceIndex = DeviceId; + DeviceInfo.u.hNotifyEvent = Instance->hNotifyEvent; Result = SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_OPEN_WDMAUD, @@ -314,9 +386,17 @@ SetWdmMixerDeviceFormat( if ( ! MMSUCCESS(Result) ) { + CloseHandle(Instance->hNotifyEvent); + CloseHandle(Instance->hStopEvent); return TranslateInternalMmResult(Result); } + hThread = CreateThread(NULL, 0, MixerEventThreadRoutine, (LPVOID)Instance, 0, NULL); + if ( hThread ) + { + CloseHandle(hThread); + } + /* Store sound device handle instance handle */ Instance->Handle = (PVOID)DeviceInfo.hDevice; diff --git a/reactos/include/psdk/mmddk.h b/reactos/include/psdk/mmddk.h index fa9512a3de1..18ea88dccd4 100644 --- a/reactos/include/psdk/mmddk.h +++ b/reactos/include/psdk/mmddk.h @@ -416,9 +416,10 @@ typedef struct { typedef struct tMIXEROPENDESC { HMIXEROBJ hmx; - LPVOID pReserved0; - DWORD dwCallback; - DWORD dwInstance; + LPVOID pReserved0; + DWORD_PTR dwCallback; + DWORD_PTR dwInstance; + DWORD_PTR dnDevNode; } MIXEROPENDESC, *LPMIXEROPENDESC; typedef struct { diff --git a/reactos/include/reactos/libs/sound/mmebuddy.h b/reactos/include/reactos/libs/sound/mmebuddy.h index b145c16b4d8..9f2ce0fe657 100644 --- a/reactos/include/reactos/libs/sound/mmebuddy.h +++ b/reactos/include/reactos/libs/sound/mmebuddy.h @@ -334,8 +334,8 @@ typedef struct _SOUND_DEVICE_INSTANCE { HDRVR Handle; DWORD Flags; - DWORD ClientCallback; - DWORD ClientCallbackInstanceData; + DWORD_PTR ClientCallback; + DWORD_PTR ClientCallbackInstanceData; } WinMM; /* DO NOT TOUCH THESE OUTSIDE OF THE SOUND THREAD */ @@ -357,6 +357,8 @@ typedef struct _SOUND_DEVICE_INSTANCE DWORD FrameSize; DWORD BufferCount; WAVEFORMATEX WaveFormatEx; + HANDLE hNotifyEvent; + HANDLE hStopEvent; } SOUND_DEVICE_INSTANCE, *PSOUND_DEVICE_INSTANCE; /* This lives in WAVEHDR.reserved */ @@ -561,8 +563,8 @@ MMRESULT SetSoundDeviceInstanceMmeData( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN HDRVR MmeHandle, - IN DWORD ClientCallback, - IN DWORD ClientCallbackData, + IN DWORD_PTR ClientCallback, + IN DWORD_PTR ClientCallbackData, IN DWORD Flags); diff --git a/reactos/lib/drivers/sound/mmebuddy/deviceinstance.c b/reactos/lib/drivers/sound/mmebuddy/deviceinstance.c index 790429ef524..0558b2b4501 100644 --- a/reactos/lib/drivers/sound/mmebuddy/deviceinstance.c +++ b/reactos/lib/drivers/sound/mmebuddy/deviceinstance.c @@ -353,8 +353,8 @@ MMRESULT SetSoundDeviceInstanceMmeData( IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN HDRVR MmeHandle, - IN DWORD ClientCallback, - IN DWORD ClientCallbackData, + IN DWORD_PTR ClientCallback, + IN DWORD_PTR ClientCallbackData, IN DWORD Flags) { VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) ); From 955b60c3ad55a4d265e360aff7f4777bac230fe8 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 15:00:33 +0000 Subject: [PATCH 041/140] - Silence svn path=/trunk/; revision=44135 --- reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c index 2f57fb90c6e..86e63773c0e 100644 --- a/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c +++ b/reactos/lib/drivers/sound/mmebuddy/mixer/mxdMessage.c @@ -30,7 +30,7 @@ MmeGetLineInfo( PSOUND_DEVICE SoundDevice; PMMFUNCTION_TABLE FunctionTable; - SND_TRACE(L"Getting mixer info %u\n", Message); + //SND_TRACE(L"Getting mixer info %u\n", Message); VALIDATE_MMSYS_PARAMETER( PrivateHandle ); SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle; From 17dd5fb45cb387852463e239a1257d9209d5ed62 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 15:04:19 +0000 Subject: [PATCH 042/140] - Silence (on request of Christoph) svn path=/trunk/; revision=44136 --- reactos/ntoskrnl/io/iomgr/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/io/iomgr/file.c b/reactos/ntoskrnl/io/iomgr/file.c index 82ce49da21e..b6a63d9af66 100644 --- a/reactos/ntoskrnl/io/iomgr/file.c +++ b/reactos/ntoskrnl/io/iomgr/file.c @@ -470,7 +470,7 @@ IopParseDevice(IN PVOID ParseObject, ((OpenPacket->RelatedFileObject) || (RemainingName->Length)) && (!VolumeOpen)) { - DPRINT1("Fix Secure FSD support!!!\n"); + DPRINT("Fix Secure FSD support!!!\n"); } /* Allocate the IRP */ From 165c423eed7850037ed94cfba14d98fdc1e97732 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 15:08:00 +0000 Subject: [PATCH 043/140] Silence for Christoph & buildbot svn path=/trunk/; revision=44137 --- reactos/drivers/wdm/audio/sysaudio/dispatcher.c | 4 ++-- reactos/drivers/wdm/audio/sysaudio/main.c | 6 +++--- reactos/drivers/wdm/audio/sysaudio/pin.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index d2ee704aee2..e29b8b4d936 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -67,7 +67,7 @@ DispatchCreateSysAudio( KSOBJECT_HEADER ObjectHeader; PKSOBJECT_CREATE_ITEM CreateItem; - DPRINT1("DispatchCreateSysAudio entered\n"); + DPRINT("DispatchCreateSysAudio entered\n"); /* allocate create item */ CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); @@ -89,7 +89,7 @@ DispatchCreateSysAudio( /* allocate object header */ Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable); - DPRINT1("KsAllocateObjectHeader result %x\n", Status); + DPRINT("KsAllocateObjectHeader result %x\n", Status); /* complete the irp */ Irp->IoStatus.Information = 0; Irp->IoStatus.Status = Status; diff --git a/reactos/drivers/wdm/audio/sysaudio/main.c b/reactos/drivers/wdm/audio/sysaudio/main.c index d1134c88360..6e0fceeb16b 100644 --- a/reactos/drivers/wdm/audio/sysaudio/main.c +++ b/reactos/drivers/wdm/audio/sysaudio/main.c @@ -37,7 +37,7 @@ SysAudio_Shutdown( PSYSAUDIODEVEXT DeviceExtension; PLIST_ENTRY Entry; - DPRINT1("SysAudio_Shutdown called\n"); + DPRINT("SysAudio_Shutdown called\n"); DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; @@ -46,7 +46,7 @@ SysAudio_Shutdown( Entry = RemoveHeadList(&DeviceExtension->KsAudioDeviceList); DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); - DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName); + DPRINT("Freeing item %wZ\n", &DeviceEntry->DeviceName); /* dereference audio device file object */ ObDereferenceObject(DeviceEntry->FileObject); @@ -149,7 +149,7 @@ SysAudio_InstallDevice( if (!NT_SUCCESS(Status)) { IoDeleteDevice(DeviceObject); - DPRINT("Failed to create sysaudio symlink!\n"); + DPRINT1("Failed to create sysaudio symlink!\n"); return Status; } } diff --git a/reactos/drivers/wdm/audio/sysaudio/pin.c b/reactos/drivers/wdm/audio/sysaudio/pin.c index edcd3c307b9..a2271a98c12 100644 --- a/reactos/drivers/wdm/audio/sysaudio/pin.c +++ b/reactos/drivers/wdm/audio/sysaudio/pin.c @@ -362,7 +362,7 @@ InstantiatePins( DispatchContext->AudioEntry = DeviceEntry; - DPRINT1("RealPinHandle %p\n", RealPinHandle); + DPRINT("RealPinHandle %p\n", RealPinHandle); /* Do we need to transform the audio stream */ if (OutputFormat != NULL) From 5a56a7c2da315f097ea39b26eb1a3c1ba5694d5c Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 17:31:02 +0000 Subject: [PATCH 044/140] [KERNEL32] - Don't access freed memory in GetVolumeNameForVolumeMountPointW svn path=/trunk/; revision=44141 --- reactos/dll/win32/kernel32/file/volume.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/kernel32/file/volume.c b/reactos/dll/win32/kernel32/file/volume.c index 09e07ab5883..0283def92cf 100644 --- a/reactos/dll/win32/kernel32/file/volume.c +++ b/reactos/dll/win32/kernel32/file/volume.c @@ -996,15 +996,16 @@ GetVolumeNameForVolumeMountPointW( MountPoints, BufferLength); if (!NT_SUCCESS(Status)) { - RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); if (Status == STATUS_BUFFER_OVERFLOW) { BufferLength = MountPoints->Size; + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); continue; } else if (!NT_SUCCESS(Status)) { RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint); + RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints); NtClose(FileHandle); SetLastErrorByStatus(Status); return FALSE; From 6db29a3b515117702dfbd6376329868abe5bff4b Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 13 Nov 2009 17:47:03 +0000 Subject: [PATCH 045/140] [CMIDRIVER] - Fix build breakage by Sylvain Petreolle svn path=/trunk/; revision=44142 --- reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp | 2 +- reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp index 4f86166eb59..da825b788c3 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/adapter.hpp @@ -30,7 +30,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "interfaces.hpp" #include "debug.hpp" -#include "DMusicKS.h" +#include "dmusicks.h" #ifdef UART const ULONG MAX_MINIPORTS = 3; diff --git a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp index 48af5f33e41..23584dd1dcd 100644 --- a/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp +++ b/reactos/drivers/wdm/audio/drivers/CMIDriver/mintopo.cpp @@ -29,7 +29,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "mintopo.hpp" #include "mintopotables.hpp" #define NTSTRSAFE_LIB //for Windows 2000 compatibility -#include "NtStrsafe.h" +#include "ntstrsafe.h" #pragma code_seg("PAGE") From f0816148d167319a886d410e57028fea33d94aed Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 14 Nov 2009 11:22:29 +0000 Subject: [PATCH 046/140] - Add VK_ICO_* codes. svn path=/trunk/; revision=44153 --- reactos/include/psdk/winuser.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reactos/include/psdk/winuser.h b/reactos/include/psdk/winuser.h index aacf4fa4880..f21c54c5276 100644 --- a/reactos/include/psdk/winuser.h +++ b/reactos/include/psdk/winuser.h @@ -2222,6 +2222,8 @@ extern "C" { #if (_WIN32_WINNT >= 0x0500) #define VK_OEM_102 0xE2 #endif +#define VK_ICO_HELP 0xE3 /* Help key on ICO */ +#define VK_ICO_00 0xE4 /* 00 key on ICO */ #define VK_PROCESSKEY 0xE5 #if (_WIN32_WINNT >= 0x0500) #define VK_PACKET 0xE7 From 960d3e56d410c99080fed174a275574f3c8b84d0 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Sat, 14 Nov 2009 15:44:02 +0000 Subject: [PATCH 047/140] Forgotten French translation for Fraginator lost on my HD svn path=/trunk/; revision=44157 --- rosapps/applications/fraginator/Fraginator.rc | 1 + rosapps/applications/fraginator/lang/fr-FR.rc | 230 ++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 rosapps/applications/fraginator/lang/fr-FR.rc diff --git a/rosapps/applications/fraginator/Fraginator.rc b/rosapps/applications/fraginator/Fraginator.rc index 5635e0fd4a6..62b2f346899 100644 --- a/rosapps/applications/fraginator/Fraginator.rc +++ b/rosapps/applications/fraginator/Fraginator.rc @@ -15,5 +15,6 @@ #include "lang/en-US.rc" #include "lang/es-ES.rc" +#include "lang/fr-FR.rc" #include "lang/no-NO.rc" #include "lang/sk-SK.rc" diff --git a/rosapps/applications/fraginator/lang/fr-FR.rc b/rosapps/applications/fraginator/lang/fr-FR.rc new file mode 100644 index 00000000000..be1f3795566 --- /dev/null +++ b/rosapps/applications/fraginator/lang/fr-FR.rc @@ -0,0 +1,230 @@ +// Microsoft Visual C++ generated resource script. +// + +///////////////////////////////////////////////////////////////////////////// +// French resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MAIN DIALOGEX 0, 0, 346, 103 +STYLE DS_SHELLFONT | DS_CENTERMOUSE | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | + WS_CAPTION | WS_SYSMENU +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + COMBOBOX IDC_DRIVES_LIST,78,52,29,111,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_METHODS_LIST,135,52,77,79,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_PRIORITY_LIST,223,52,59,91,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Démarrer",IDC_STARTSTOP,294,7,45,15 + PUSHBUTTON "Aide",ID_MAIN_HELP,294,28,45,15 + PUSHBUTTON "Quitter",IDC_QUIT,294,49,45,15 + CONTROL 110,-1,"Static",SS_BITMAP | SS_SUNKEN | + WS_BORDER,7,7,63,58 + LTEXT "Choisissez un lecteur :",-1,78,40,50,8 + LTEXT "Choisissez une action :",-1,135,40,58,8 + CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER | + 0x1,7,71,299,10 + CONTROL "Static",IDC_STATUS,"Static",SS_LEFTNOWORDWRAP | + SS_SUNKEN | WS_GROUP,7,86,332,10 + LTEXT "Je suis un singe, ententez-moi eeK",IDC_WISECRACKS,78,15,91,8 + LTEXT "100.00%",IDC_PERCENT,311,71,28,8,0,WS_EX_RIGHT + LTEXT "Priorité du processus :",-1,223,40,51,8 +END + +IDD_REPORT DIALOGEX 0, 0, 391, 169 +STYLE DS_SHELLFONT | WS_POPUP | WS_CAPTION +CAPTION "Rapport" +FONT 8, "MS Shell Dlg" +BEGIN + DEFPUSHBUTTON "Octets",IDC_BYTES,7,148,50,14 + DEFPUSHBUTTON "Kilooctets",IDC_KILOBYTES,61,148,50,14 + DEFPUSHBUTTON "Mégaoctets",IDC_MEGABYTES,115,148,50,14 + DEFPUSHBUTTON "Gigaoctets",IDC_GIGABYTES,169,148,50,14 + DEFPUSHBUTTON "OK",IDC_REPORTOK,334,148,50,14 + RTEXT "Volume",-1,7,7,24,8 + LTEXT "Capacité",-1,7,51,28,8 + RTEXT "(Lettre du lecteur)",IDC_DRIVELETTER,63,7,117,10,SS_SUNKEN + RTEXT "(Taille du disque, Octets)",IDC_DISKSIZEBYTES,63,51,117,10, + SS_SUNKEN + RTEXT "(Taille du disque, Clusters)",IDC_DISKSIZECLUSTERS,63,73,117, + 10,SS_SUNKEN + LTEXT "Nombre de clusters",-1,7,73,43,8 + RTEXT "(Taille d'un Cluster)",IDC_DISKCLUSTERSIZE,63,84,117,10, + SS_SUNKEN + LTEXT "Taille d'un cluster",-1,7,84,36,8 + RTEXT "(Nombre de fichiers)",IDC_FILESCOUNT,267,18,117,10,SS_SUNKEN + RTEXT "(Taille des fichiers, octets)",IDC_FILESSIZEBYTES,267,29,117,10, + SS_SUNKEN + LTEXT "# des fichiers",-1,194,18,28,8 + LTEXT "Taille totale",-1,194,29,31,8 + LTEXT "Taille sur le disque",-1,194,40,39,8 + RTEXT "(Taille totale, octets)",IDC_FILESSIZEONDISK,267,40,117,10, + SS_SUNKEN + RTEXT "(Octets perdus par les fichiers)",IDC_FILESSLACKBYTES,267,51,117,10, + SS_SUNKEN + LTEXT "Espace perdu",-1,194,51,44,8 + RTEXT "(Espace libre, octets)",IDC_DISKFREEBYTES,63,62,117,10, + SS_SUNKEN + LTEXT "Espace libre",-1,7,62,36,8 + RTEXT "(Fichiers fragmentés, nombre)",IDC_FILESFRAGGED,267,62,117, + 10,SS_SUNKEN + LTEXT "Fichiers fragmentés",-1,194,62,52,8 + RTEXT "(Nombre de répertoires)",IDC_DIRSCOUNT,267,7,117,10,SS_SUNKEN + LTEXT "# répertoires",-1,194,7,48,8 + RTEXT "Systčme de fichiers",-1,7,40,36,8 + RTEXT "(Nom du systčme de fichiers)",IDC_FILESYSTEM,63,40,117,10, + SS_SUNKEN + RTEXT "Nom du volume",-1,7,18,44,8 + RTEXT "(Nom du volume)",IDC_VOLUMELABEL,63,18,117,10,SS_SUNKEN + RTEXT "Numéro de série",-1,7,29,18,8 + RTEXT "(Numéro de série du volume)",IDC_VOLUMESERIAL,63,29,117,10, + SS_SUNKEN + RTEXT "(Fragements par fichier en moyenne)",IDC_AVERAGEFRAGS,267,73,117, + 10,SS_SUNKEN + LTEXT "Fragements par fichier en moyenne",-1,194,73,60,20 + LTEXT "XX.X% des fichiers sur ce lecteur sont fragmentés. Il est recommandé que vous effectuiez une défragmentation.", + IDC_RECOMMEND,7,106,377,38,SS_SUNKEN + LTEXT "Recommandations :",-1,7,96,62,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_MAIN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 96 + END + + IDD_REPORT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 384 + TOPMARGIN, 7 + BOTTOMMARGIN, 162 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,3,0,0 + PRODUCTVERSION 1,3,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", " " + VALUE "FileDescription", "Fraginator" + VALUE "FileVersion", "1.03" + VALUE "InternalName", "Fraginator" + VALUE "LegalCopyright", "Copyright © 2000-2002 Rick Brewster" + VALUE "OriginalFilename", "Fraginator.exe" + VALUE "ProductName", "Fraginator" + VALUE "ProductVersion", "1.03" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_LOGO BITMAP "Fraginator Motif Icon.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON ICON "icon1.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// RT_MANIFEST +// + +1 RT_MANIFEST "default1.bin" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + From 283fdbd5105a35e93c350b491272885f3ad27e4f Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Sat, 14 Nov 2009 15:44:27 +0000 Subject: [PATCH 048/140] GetCurrencyFormatW() formatting bug fix by Viliam Lejcik svn path=/trunk/; revision=44158 --- reactos/dll/win32/kernel32/misc/lcformat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/kernel32/misc/lcformat.c b/reactos/dll/win32/kernel32/misc/lcformat.c index 5cce484333f..2cbabe8fa5e 100644 --- a/reactos/dll/win32/kernel32/misc/lcformat.c +++ b/reactos/dll/win32/kernel32/misc/lcformat.c @@ -1587,7 +1587,7 @@ GetCurrencyFormatW_Error: dwState |= NF_DIGITS_OUT; dwCurrentGroupCount++; - if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount) + if (szSrc >= lpszValue && dwCurrentGroupCount == dwGroupCount && *szSrc != '-') { LPWSTR lpszGrp = lpFormat->lpThousandSep + strlenW(lpFormat->lpThousandSep) - 1; From f3d4211e560f5d8059339a6b3af9ccf75d1f3766 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 14 Nov 2009 18:38:02 +0000 Subject: [PATCH 049/140] - Use a spin lock to protect OSKit instead of a recursive mutex - Remove the now unused recursive mutex code - Don't clear the SS_ISCONNECTING flag when soconnect returns EINPROGRESS because it causes a crash during soreceive - Lock CONNECTION_ENDPOINT and ADDRESS_FILE structs better - Remove incorrect IoMarkIrpPending calls - Remove useless ASSERT_LOCKED - Don't destroy so_connection when we close a connection - Remove useless FileFindConnectionByContext - Remove SignalledConnectionsList and SignalledConnectionsLock and simply loop through ConnectionEndpointList for signalled connections - Add connections to ConnectionEndpointList in TCPAllocateConnectionEndpoint instead of FileOpenConnection so we don't miss listeners - Remove connections from ConnectionEndpointList in TCPFreeConnectionEndpoint instead of FileCloseConnection so we don't miss listeners - Use ExInterlockedRemoveHeadList to remove entries in the address file's request lists - Remove useless members, flags, and variables in titypes.h and tcp.h - Fixes bug 4955 and 4434 svn path=/trunk/; revision=44163 --- .../drivers/network/tcpip/include/fileobjs.h | 3 - reactos/drivers/network/tcpip/include/tcp.h | 6 - .../drivers/network/tcpip/include/titypes.h | 26 - .../drivers/network/tcpip/recmutex/recmutex.c | 61 -- .../drivers/network/tcpip/recmutex/recmutex.h | 21 - reactos/drivers/network/tcpip/tcpip.rbuild | 3 - .../drivers/network/tcpip/tcpip/dispatch.c | 9 +- .../drivers/network/tcpip/tcpip/fileobjs.c | 79 +-- reactos/drivers/network/tcpip/tcpip/lock.c | 13 - .../drivers/network/tcpip/tcpip/mocklock.c | 8 - .../drivers/ip/transport/datagram/datagram.c | 109 ++- .../lib/drivers/ip/transport/rawip/rawip.c | 13 + reactos/lib/drivers/ip/transport/tcp/accept.c | 22 +- reactos/lib/drivers/ip/transport/tcp/event.c | 58 +- reactos/lib/drivers/ip/transport/tcp/tcp.c | 662 +++++++++--------- reactos/lib/drivers/ip/transport/udp/udp.c | 11 + .../lib/drivers/oskittcp/include/oskittcp.h | 27 +- .../lib/drivers/oskittcp/oskittcp/interface.c | 144 ++-- 18 files changed, 566 insertions(+), 709 deletions(-) delete mode 100644 reactos/drivers/network/tcpip/recmutex/recmutex.c delete mode 100644 reactos/drivers/network/tcpip/recmutex/recmutex.h diff --git a/reactos/drivers/network/tcpip/include/fileobjs.h b/reactos/drivers/network/tcpip/include/fileobjs.h index bff07a64b40..12327701db8 100644 --- a/reactos/drivers/network/tcpip/include/fileobjs.h +++ b/reactos/drivers/network/tcpip/include/fileobjs.h @@ -13,7 +13,6 @@ extern KSPIN_LOCK AddressFileListLock; extern LIST_ENTRY ConnectionEndpointListHead; extern KSPIN_LOCK ConnectionEndpointListLock; - NTSTATUS FileOpenAddress( PTDI_REQUEST Request, PTA_IP_ADDRESS AddrList, @@ -27,8 +26,6 @@ NTSTATUS FileOpenConnection( PTDI_REQUEST Request, PVOID ClientContext); -PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ); - NTSTATUS FileCloseConnection( PTDI_REQUEST Request); diff --git a/reactos/drivers/network/tcpip/include/tcp.h b/reactos/drivers/network/tcpip/include/tcp.h index e80d17f2500..32c3ec907e7 100644 --- a/reactos/drivers/network/tcpip/include/tcp.h +++ b/reactos/drivers/network/tcpip/include/tcp.h @@ -84,11 +84,6 @@ typedef struct _SLEEPING_THREAD { #define SRF_FIN TCP_FIN extern LONG TCP_IPIdentification; -extern LIST_ENTRY SignalledConnectionsList; -extern KSPIN_LOCK SignalledConnectionsLock; -extern LIST_ENTRY SleepingThreadsList; -extern FAST_MUTEX SleepingThreadsLock; -extern RECURSIVE_MUTEX TCPLock; /* accept.c */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, @@ -105,7 +100,6 @@ NTSTATUS TCPAccept PVOID Context ); /* tcp.c */ -ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ); PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ); VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ); diff --git a/reactos/drivers/network/tcpip/include/titypes.h b/reactos/drivers/network/tcpip/include/titypes.h index eaac15a1496..9ac9561e0bb 100644 --- a/reactos/drivers/network/tcpip/include/titypes.h +++ b/reactos/drivers/network/tcpip/include/titypes.h @@ -153,7 +153,6 @@ typedef struct _ADDRESS_FILE { LIST_ENTRY ListEntry; /* Entry on list */ KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ - USHORT Flags; /* Flags for address file (see below) */ IP_ADDRESS Address; /* Address of this address file */ USHORT Family; /* Address family */ USHORT Protocol; /* Protocol number */ @@ -213,29 +212,6 @@ typedef struct _ADDRESS_FILE { BOOLEAN RegisteredChainedReceiveExpeditedHandler; } ADDRESS_FILE, *PADDRESS_FILE; -/* Address File Flag constants */ -#define AFF_VALID 0x0001 /* Address file object is valid for use */ -#define AFF_BUSY 0x0002 /* Address file object is exclusive to someone */ -#define AFF_DELETE 0x0004 /* Address file object is sheduled to be deleted */ -#define AFF_SEND 0x0008 /* A send request is pending */ -#define AFF_RECEIVE 0x0010 /* A receive request is pending */ -#define AFF_PENDING 0x001C /* A request is pending */ - -/* Macros for manipulating address file object flags */ - -#define AF_IS_VALID(ADF) ((ADF)->Flags & AFF_VALID) -#define AF_SET_VALID(ADF) ((ADF)->Flags |= AFF_VALID) -#define AF_CLR_VALID(ADF) ((ADF)->Flags &= ~AFF_VALID) - -#define AF_IS_BUSY(ADF) ((ADF)->Flags & AFF_BUSY) -#define AF_SET_BUSY(ADF) ((ADF)->Flags |= AFF_BUSY) -#define AF_CLR_BUSY(ADF) ((ADF)->Flags &= ~AFF_BUSY) - -#define AF_IS_PENDING(ADF, X) (ADF->Flags & X) -#define AF_SET_PENDING(ADF, X) (ADF->Flags |= X) -#define AF_CLR_PENDING(ADF, X) (ADF->Flags &= ~X) - - /* Structure used to search through Address Files */ typedef struct _AF_SEARCH { PLIST_ENTRY Next; /* Next address file to check */ @@ -306,8 +282,6 @@ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY SendRequest; /* Queued send requests */ /* Signals */ - LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for - * notification service to the client */ UINT SignalState; /* Active signals from oskit */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; diff --git a/reactos/drivers/network/tcpip/recmutex/recmutex.c b/reactos/drivers/network/tcpip/recmutex/recmutex.c deleted file mode 100644 index 3450ab8567f..00000000000 --- a/reactos/drivers/network/tcpip/recmutex/recmutex.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include "recmutex.h" - -VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { - RtlZeroMemory( RecMutex, sizeof(*RecMutex) ); - ExInitializeFastMutex( &RecMutex->Mutex ); - KeInitializeEvent( &RecMutex->StateLockedEvent, - NotificationEvent, FALSE ); -} - -/* NOTE: When we leave, the FAST_MUTEX must have been released. The result -* is that we always exit in the same irql as entering */ -VOID RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) { - NTSTATUS Status = STATUS_SUCCESS; - PVOID CurrentThread = KeGetCurrentThread(); - - ASSERT(RecMutex); - ASSERT(KeGetCurrentIrql() <= APC_LEVEL); - - /* Wait for the previous user to unlock the RecMutex state. There might be - * multiple waiters waiting to change the state. We need to check each - * time we get the event whether somebody still has the state locked */ - - ExAcquireFastMutex( &RecMutex->Mutex ); - - if( CurrentThread == RecMutex->CurrentThread ) { - RecMutex->LockCount++; - ExReleaseFastMutex( &RecMutex->Mutex ); - return; - } - - while( RecMutex->LockCount != 0 ) { - ExReleaseFastMutex( &RecMutex->Mutex ); - Status = KeWaitForSingleObject( &RecMutex->StateLockedEvent, - UserRequest, - KernelMode, - FALSE, - NULL ); - ExAcquireFastMutex( &RecMutex->Mutex ); - } - RecMutex->CurrentThread = CurrentThread; - RecMutex->LockCount++; - ExReleaseFastMutex( &RecMutex->Mutex ); -} - -VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { - ASSERT(RecMutex); - - ExAcquireFastMutex( &RecMutex->Mutex ); - - ASSERT(RecMutex->LockCount > 0); - RecMutex->LockCount--; - - if( !RecMutex->LockCount ) { - KePulseEvent( &RecMutex->StateLockedEvent, IO_NETWORK_INCREMENT, - FALSE ); - } - - ExReleaseFastMutex( &RecMutex->Mutex ); -} - diff --git a/reactos/drivers/network/tcpip/recmutex/recmutex.h b/reactos/drivers/network/tcpip/recmutex/recmutex.h deleted file mode 100644 index 3479268e3bd..00000000000 --- a/reactos/drivers/network/tcpip/recmutex/recmutex.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _ROSRTL_RECMUTEX_H -#define _ROSRTL_RECMUTEX_H - -typedef struct _RECURSIVE_MUTEX { - /* Lock. */ - FAST_MUTEX Mutex; - /* Number of times this object was locked */ - SIZE_T LockCount; - /* CurrentThread */ - PVOID CurrentThread; - /* Notification event which signals that another thread can take over */ - KEVENT StateLockedEvent; -} RECURSIVE_MUTEX, *PRECURSIVE_MUTEX; - -extern VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ); -extern VOID RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ); -extern VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ); - -#define ASSERT_LOCKED(x) - -#endif/*_ROSRTL_RECMUTEX_H*/ diff --git a/reactos/drivers/network/tcpip/tcpip.rbuild b/reactos/drivers/network/tcpip/tcpip.rbuild index 2a9f91cc52e..4dd14d3cbdf 100644 --- a/reactos/drivers/network/tcpip/tcpip.rbuild +++ b/reactos/drivers/network/tcpip/tcpip.rbuild @@ -21,9 +21,6 @@ lan.c - - recmutex.c - ainfo.c buffer.c diff --git a/reactos/drivers/network/tcpip/tcpip/dispatch.c b/reactos/drivers/network/tcpip/tcpip/dispatch.c index 182330928af..49de2fd9090 100644 --- a/reactos/drivers/network/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/network/tcpip/tcpip/dispatch.c @@ -210,9 +210,8 @@ VOID NTAPI DispCancelListenRequest( TCPRemoveIRP(Connection, Irp); - TCPAbortListenForSocket( - Connection->AddressFile->Listener, - Connection ); + TCPAbortListenForSocket(Connection->AddressFile->Listener, + Connection); IoReleaseCancelSpinLock(Irp->CancelIrql); @@ -1044,7 +1043,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters; Status = STATUS_SUCCESS; - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); /* Set the event handler. if an event handler is associated with a specific event, it's flag (RegisteredXxxHandler) is TRUE. @@ -1165,7 +1164,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Status = STATUS_INVALID_PARAMETER; } - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; } diff --git a/reactos/drivers/network/tcpip/tcpip/fileobjs.c b/reactos/drivers/network/tcpip/tcpip/fileobjs.c index 85808f9c0bf..dec7a0c9576 100644 --- a/reactos/drivers/network/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/network/tcpip/tcpip/fileobjs.c @@ -295,9 +295,6 @@ NTSTATUS FileOpenAddress( /* Initialize spin lock that protects the address file object */ KeInitializeSpinLock(&AddrFile->Lock); - /* Set valid flag so the address can be used */ - AF_SET_VALID(AddrFile); - /* Return address file object */ Request->Handle.AddressHandle = AddrFile; @@ -328,7 +325,7 @@ NTSTATUS FileCloseAddress( KIRQL OldIrql; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; PDATAGRAM_SEND_REQUEST SendRequest; - PLIST_ENTRY CurrentEntry, NextEntry; + PLIST_ENTRY CurrentEntry; AddrFile = Request->Handle.AddressHandle; @@ -339,8 +336,6 @@ NTSTATUS FileCloseAddress( RemoveEntryList(&AddrFile->ListEntry); TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - /* FIXME: Kill TCP connections on this address file object */ /* Return pending requests with error */ @@ -348,43 +343,27 @@ NTSTATUS FileCloseAddress( TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile)); /* Go through pending receive request list and cancel them all */ - CurrentEntry = AddrFile->ReceiveQueue.Flink; - while (CurrentEntry != &AddrFile->ReceiveQueue) { - NextEntry = CurrentEntry->Flink; + while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); - /* Abort the request and free its resources */ - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0); - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - CurrentEntry = NextEntry; + /* exFreePool(ReceiveRequest); FIXME: WTF? */ } TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile)); /* Go through pending send request list and cancel them all */ - CurrentEntry = AddrFile->TransmitQueue.Flink; - while (CurrentEntry != &AddrFile->TransmitQueue) { - NextEntry = CurrentEntry->Flink; - SendRequest = CONTAINING_RECORD(CurrentEntry, - DATAGRAM_SEND_REQUEST, ListEntry); - /* Abort the request and free its resources */ - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { + SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry); (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0); exFreePool(SendRequest); - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - CurrentEntry = NextEntry; } - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - /* Protocol specific handling */ switch (AddrFile->Protocol) { case IPPROTO_TCP: TCPFreePort( AddrFile->Port ); - if( AddrFile->Listener ) { - TCPClose( AddrFile->Listener ); - exFreePool( AddrFile->Listener ); - } + if( AddrFile->Listener ) + TCPClose( AddrFile->Listener ); break; case IPPROTO_UDP: @@ -433,48 +412,11 @@ NTSTATUS FileOpenConnection( /* Return connection endpoint file object */ Request->Handle.ConnectionContext = Connection; - /* Add connection endpoint to global list */ - ExInterlockedInsertTailList( - &ConnectionEndpointListHead, - &Connection->ListEntry, - &ConnectionEndpointListLock); - TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); return STATUS_SUCCESS; } - -/* - * FUNCTION: Find a connection by examining the context field. This - * is needed in some situations where a FIN reply is needed after a - * socket is formally broken. - * ARGUMENTS: - * Request = Pointer to TDI request structure for this request - * RETURNS: - * Status of operation - */ -PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) { - PLIST_ENTRY Entry; - KIRQL OldIrql; - PCONNECTION_ENDPOINT Connection = NULL; - - TcpipAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql ); - - for( Entry = ConnectionEndpointListHead.Flink; - Entry != &ConnectionEndpointListHead; - Entry = Entry->Flink ) { - Connection = - CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry ); - if( Connection->SocketContext == Context ) break; - else Connection = NULL; - } - - TcpipReleaseSpinLock( &ConnectionEndpointListLock, OldIrql ); - - return Connection; -} - /* * FUNCTION: Closes an connection file object * ARGUMENTS: @@ -486,20 +428,13 @@ NTSTATUS FileCloseConnection( PTDI_REQUEST Request) { PCONNECTION_ENDPOINT Connection; - KIRQL OldIrql; TI_DbgPrint(MID_TRACE, ("Called.\n")); Connection = Request->Handle.ConnectionContext; - TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - RemoveEntryList(&Connection->ListEntry); - TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - TCPClose( Connection ); - TCPFreeConnectionEndpoint(Connection); - TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); return STATUS_SUCCESS; diff --git a/reactos/drivers/network/tcpip/tcpip/lock.c b/reactos/drivers/network/tcpip/tcpip/lock.c index 3f9d823c857..9a6cdc95fa3 100644 --- a/reactos/drivers/network/tcpip/tcpip/lock.c +++ b/reactos/drivers/network/tcpip/tcpip/lock.c @@ -44,16 +44,3 @@ VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) { ExReleaseFastMutex( Mutex ); } -VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { - RecursiveMutexInit( RecMutex ); -} - -VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) { - //TI_DbgPrint(DEBUG_LOCK,("Locking\n")); - RecursiveMutexEnter( RecMutex ); -} - -VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { - //TI_DbgPrint(DEBUG_LOCK,("Unlocking\n")); - RecursiveMutexLeave( RecMutex ); -} diff --git a/reactos/drivers/network/tcpip/tcpip/mocklock.c b/reactos/drivers/network/tcpip/tcpip/mocklock.c index 0042ef8b803..0aa957c4035 100644 --- a/reactos/drivers/network/tcpip/tcpip/mocklock.c +++ b/reactos/drivers/network/tcpip/tcpip/mocklock.c @@ -45,11 +45,3 @@ VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ) { VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) { } -VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { -} - -VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) { -} - -VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { -} diff --git a/reactos/lib/drivers/ip/transport/datagram/datagram.c b/reactos/lib/drivers/ip/transport/datagram/datagram.c index 70660605950..fafea75f84a 100644 --- a/reactos/lib/drivers/ip/transport/datagram/datagram.c +++ b/reactos/lib/drivers/ip/transport/datagram/datagram.c @@ -79,7 +79,7 @@ VOID DGDeliverData( TI_DbgPrint(MAX_TRACE, ("Called.\n")); - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); if (AddrFile->Protocol == IPPROTO_UDP) { @@ -136,7 +136,7 @@ VOID DGDeliverData( &SrcAddress->Address.IPv4Address, sizeof(SrcAddress->Address.IPv4Address) ); - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); /* Complete the receive request */ if (Current->BufferSize < DataSize) @@ -144,11 +144,11 @@ VOID DGDeliverData( else Current->Complete(Current->Context, STATUS_SUCCESS, DataSize); - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); } } - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); } else if (AddrFile->RegisteredReceiveDatagramHandler) { @@ -157,8 +157,6 @@ VOID DGDeliverData( ReceiveHandler = AddrFile->ReceiveDatagramHandler; HandlerContext = AddrFile->ReceiveDatagramHandlerContext; - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - if (SrcAddress->Type == IP_ADDRESS_V4) { AddressLength = sizeof(IPv4_RAW_ADDRESS); @@ -170,6 +168,8 @@ VOID DGDeliverData( SourceAddress = SrcAddress->Address.IPv6Address; } + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + Status = (*ReceiveHandler)(HandlerContext, AddressLength, SourceAddress, @@ -184,7 +184,7 @@ VOID DGDeliverData( } else { - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n")); } @@ -228,76 +228,67 @@ NTSTATUS DGReceiveDatagram( * This is the high level interface for receiving DG datagrams */ { - KIRQL OldIrql; NTSTATUS Status; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; + KIRQL OldIrql; TI_DbgPrint(MAX_TRACE, ("Called.\n")); - TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); - if (AF_IS_VALID(AddrFile)) + ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST)); + if (ReceiveRequest) { - ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST)); - if (ReceiveRequest) + /* Initialize a receive request */ + + /* Extract the remote address filter from the request (if any) */ + if ((ConnInfo->RemoteAddressLength != 0) && + (ConnInfo->RemoteAddress)) { - /* Initialize a receive request */ - - /* Extract the remote address filter from the request (if any) */ - if ((ConnInfo->RemoteAddressLength != 0) && - (ConnInfo->RemoteAddress)) + Status = AddrGetAddress(ConnInfo->RemoteAddress, + &ReceiveRequest->RemoteAddress, + &ReceiveRequest->RemotePort); + if (!NT_SUCCESS(Status)) { - Status = AddrGetAddress(ConnInfo->RemoteAddress, - &ReceiveRequest->RemoteAddress, - &ReceiveRequest->RemotePort); - if (!NT_SUCCESS(Status)) - { - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - exFreePool(ReceiveRequest); - return Status; - } + exFreePool(ReceiveRequest); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + return Status; } - else - { - ReceiveRequest->RemotePort = 0; - AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0); - } - - IoMarkIrpPending(Irp); - - ReceiveRequest->ReturnInfo = ReturnInfo; - ReceiveRequest->Buffer = BufferData; - ReceiveRequest->BufferSize = ReceiveLength; - ReceiveRequest->UserComplete = Complete; - ReceiveRequest->UserContext = Context; - ReceiveRequest->Complete = - (PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete; - ReceiveRequest->Context = ReceiveRequest; - ReceiveRequest->AddressFile = AddrFile; - ReceiveRequest->Irp = Irp; - - /* Queue receive request */ - InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry); - AF_SET_PENDING(AddrFile, AFF_RECEIVE); - - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - - TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); - - return STATUS_PENDING; - } + } else { - Status = STATUS_INSUFFICIENT_RESOURCES; + ReceiveRequest->RemotePort = 0; + AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0); } + + IoMarkIrpPending(Irp); + + ReceiveRequest->ReturnInfo = ReturnInfo; + ReceiveRequest->Buffer = BufferData; + ReceiveRequest->BufferSize = ReceiveLength; + ReceiveRequest->UserComplete = Complete; + ReceiveRequest->UserContext = Context; + ReceiveRequest->Complete = + (PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete; + ReceiveRequest->Context = ReceiveRequest; + ReceiveRequest->AddressFile = AddrFile; + ReceiveRequest->Irp = Irp; + + /* Queue receive request */ + InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry); + + TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); + + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + + return STATUS_PENDING; } else { - Status = STATUS_INVALID_ADDRESS; + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + Status = STATUS_INSUFFICIENT_RESOURCES; } - TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status)); return Status; diff --git a/reactos/lib/drivers/ip/transport/rawip/rawip.c b/reactos/lib/drivers/ip/transport/rawip/rawip.c index f7b9b6dbec9..328337cdb38 100644 --- a/reactos/lib/drivers/ip/transport/rawip/rawip.c +++ b/reactos/lib/drivers/ip/transport/rawip/rawip.c @@ -195,6 +195,9 @@ NTSTATUS RawIPSendDatagram( USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; + KIRQL OldIrql; + + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -209,13 +212,17 @@ NTSTATUS RawIPSendDatagram( break; default: + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_UNSUCCESSFUL; } TI_DbgPrint(MID_TRACE,("About to get route to destination\n")); if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) + { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_NETWORK_UNREACHABLE; + } LocalAddress = AddrFile->Address; if (AddrIsUnspecified(&LocalAddress)) @@ -237,18 +244,24 @@ NTSTATUS RawIPSendDatagram( DataSize ); if( !NT_SUCCESS(Status) ) + { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; + } TI_DbgPrint(MID_TRACE,("About to send datagram\n")); if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL ))) { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } TI_DbgPrint(MID_TRACE,("Leaving\n")); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + return STATUS_SUCCESS; } diff --git a/reactos/lib/drivers/ip/transport/tcp/accept.c b/reactos/lib/drivers/ip/transport/tcp/accept.c index f44c0c918ec..b99c03b203c 100644 --- a/reactos/lib/drivers/ip/transport/tcp/accept.c +++ b/reactos/lib/drivers/ip/transport/tcp/accept.c @@ -10,6 +10,7 @@ #include "precomp.h" +/* Listener->Lock MUST be acquired */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection, PTDI_REQUEST_KERNEL Request ) { @@ -26,18 +27,15 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, WhoIsConnecting = (PTDI_CONNECTION_INFORMATION) Request->ReturnConnectionInformation; - TcpipRecursiveMutexEnter(&TCPLock); - Status = TCPTranslateError ( OskitTCPAccept( Listener->SocketContext, &Connection->SocketContext, + Connection, &OutAddr, sizeof(OutAddr), &OutAddrLen, Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) ); - TcpipRecursiveMutexLeave(&TCPLock); - TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status)); if( NT_SUCCESS(Status) && Status != STATUS_PENDING ) { @@ -71,11 +69,14 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { NTSTATUS Status = STATUS_SUCCESS; SOCKADDR_IN AddressToBind; + KIRQL OldIrql; ASSERT(Connection); ASSERT_KM_POINTER(Connection->SocketContext); ASSERT_KM_POINTER(Connection->AddressFile); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + TI_DbgPrint(DEBUG_TCP,("TCPListen started\n")); TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", @@ -89,8 +90,6 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port)); - TcpipRecursiveMutexEnter( &TCPLock ); - Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext, &AddressToBind, sizeof(AddressToBind) ) ); @@ -98,7 +97,7 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { if (NT_SUCCESS(Status)) Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) ); - TcpipRecursiveMutexLeave( &TCPLock ); + KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status)); @@ -137,12 +136,17 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request, { NTSTATUS Status; PTDI_BUCKET Bucket; + KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n")); + KeAcquireSpinLock(&Listener->Lock, &OldIrql); + Status = TCPServiceListeningSocket( Listener, Connection, (PTDI_REQUEST_KERNEL)Request ); + KeReleaseSpinLock(&Listener->Lock, OldIrql); + if( Status == STATUS_PENDING ) { Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); @@ -150,8 +154,8 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request, Bucket->AssociatedEndpoint = Connection; Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; - IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, &Listener->Lock ); + ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, + &Listener->Lock ); } else Status = STATUS_NO_MEMORY; } diff --git a/reactos/lib/drivers/ip/transport/tcp/event.c b/reactos/lib/drivers/ip/transport/tcp/event.c index ba9e867457b..a4b2275b511 100644 --- a/reactos/lib/drivers/ip/transport/tcp/event.c +++ b/reactos/lib/drivers/ip/transport/tcp/event.c @@ -15,56 +15,30 @@ int TCPSocketState(void *ClientData, void *WhichConnection, OSK_UINT NewState ) { PCONNECTION_ENDPOINT Connection = WhichConnection; - ULONG OldState; - KIRQL OldIrql; - ASSERT_LOCKED(&TCPLock); - - TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n", + TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n", + Connection, NewState & SEL_CONNECT ? 'C' : 'c', NewState & SEL_READ ? 'R' : 'r', NewState & SEL_FIN ? 'F' : 'f', - NewState & SEL_ACCEPT ? 'A' : 'a')); + NewState & SEL_ACCEPT ? 'A' : 'a', + NewState & SEL_WRITE ? 'W' : 'w')); + + if (!Connection) + { + return 0; + } + + KeAcquireSpinLockAtDpcLevel(&Connection->Lock); TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n", NewState, Connection, - Connection ? Connection->SignalState ^ NewState : + Connection->SignalState ^ NewState, NewState)); - if( !Connection ) { - TI_DbgPrint(DEBUG_TCP,("Socket closing.\n")); - Connection = FileFindConnectionByContext( WhichSocket ); - if( !Connection ) - return 0; - else - TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection)); - } - - OldState = Connection->SignalState; - Connection->SignalState |= NewState; - TcpipRecursiveMutexLeave(&TCPLock); - - /* We must not be locked when handling signalled connections - * because a completion could trigger another IOCTL which - * would cause a deadlock - */ - NewState = HandleSignalledConnection(Connection); - - TcpipRecursiveMutexEnter(&TCPLock); - - KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); - if ((NewState == 0 || NewState == SEL_FIN) && - (OldState != 0 && OldState != SEL_FIN)) - { - RemoveEntryList(&Connection->SignalList); - } - else if (NewState != 0 && NewState != SEL_FIN) - { - InsertTailList(&SignalledConnectionsList, &Connection->SignalList); - } - KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); + KeReleaseSpinLockFromDpcLevel(&Connection->Lock); return 0; } @@ -86,8 +60,6 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { IP_ADDRESS RemoteAddress, LocalAddress; PIPv4_HEADER Header; - ASSERT_LOCKED(&TCPLock); - if( *data == 0x45 ) { /* IPv4 */ Header = (PIPv4_HEADER)data; LocalAddress.Type = IP_ADDRESS_V4; @@ -181,8 +153,6 @@ void *TCPMalloc( void *ClientData, void *v; ULONG Signature; - ASSERT_LOCKED(&TCPLock); - #if 0 != MEM_PROFILE static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0; static OSK_UINT ArrayUsed = 0, AllocationCount = 0; @@ -258,8 +228,6 @@ void TCPFree( void *ClientData, void *data, OSK_PCHAR File, OSK_UINT Line ) { ULONG Signature; - ASSERT_LOCKED(&TCPLock); - UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') ); data = (void *)((char *) data - sizeof(ULONG)); Signature = *((ULONG *) data); diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index a9907abf810..c978bebf298 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -15,12 +15,12 @@ LONG TCP_IPIdentification = 0; static BOOLEAN TCPInitialized = FALSE; static NPAGED_LOOKASIDE_LIST TCPSegmentList; -LIST_ENTRY SignalledConnectionsList; -KSPIN_LOCK SignalledConnectionsLock; -RECURSIVE_MUTEX TCPLock; PORT_SET TCPPorts; -ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { +static VOID DrainSignals() { + PCONNECTION_ENDPOINT Connection; + PLIST_ENTRY CurrentEntry, NextEntry; + KIRQL OldIrql; NTSTATUS Status = STATUS_SUCCESS; PTCP_COMPLETION_ROUTINE Complete; PTDI_BUCKET Bucket; @@ -28,279 +28,290 @@ ULONG HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { PIRP Irp; PMDL Mdl; - TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", - Connection, Connection->SocketContext)); - - if( Connection->SignalState & SEL_FIN ) { - TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - - Connection->SignalState &= ~SEL_READ; - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, - &Connection->Lock )) != NULL) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - - exFreePool(Bucket); - } - - Connection->SignalState &= ~SEL_WRITE; - while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, - &Connection->Lock )) != NULL) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - - exFreePool(Bucket); - } - - Connection->SignalState &= ~SEL_ACCEPT; - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, - &Connection->Lock )) != NULL) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - /* We have to notify oskittcp of the abortion */ - TCPAbortListenForSocket(Connection->AddressFile->Listener, - Connection); - - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - - exFreePool(Bucket); - } - - Connection->SignalState &= ~SEL_CONNECT; - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, - &Connection->Lock )) != NULL) - { - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - - exFreePool(Bucket); - } - } - - /* Things that can happen when we try the initial connection */ - if( Connection->SignalState & SEL_CONNECT ) { - Connection->SignalState &= ~SEL_CONNECT; - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, - &Connection->Lock )) != NULL ) { - - TI_DbgPrint(DEBUG_TCP, ("Connect Event\n")); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - TI_DbgPrint(DEBUG_TCP, - ("Completing Request %x\n", Bucket->Request.RequestContext)); - - Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); - - /* Frees the bucket allocated in TCPConnect */ - exFreePool( Bucket ); - } - } - - if( Connection->SignalState & SEL_ACCEPT ) { - /* Handle readable on a listening socket -- - * TODO: Implement filtering - */ - - TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", - Connection, - IsListEmpty(&Connection->ListenRequest) ? - "empty" : "nonempty")); - - Connection->SignalState &= ~SEL_ACCEPT; - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, - &Connection->Lock )) != NULL ) { - PIO_STACK_LOCATION IrpSp; - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Irp = Bucket->Request.RequestContext; - IrpSp = IoGetCurrentIrpStackLocation( Irp ); - - TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); - Status = TCPServiceListeningSocket - ( Connection->AddressFile->Listener, - Bucket->AssociatedEndpoint, - (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); - - TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); - - if( Status == STATUS_PENDING ) { - Connection->SignalState |= SEL_ACCEPT; - ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock ); - break; - } else { - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); - } - } - } - - /* Things that happen after we're connected */ - if( Connection->SignalState & SEL_READ ) { - TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", - IsListEmpty(&Connection->ReceiveRequest) ? - "empty" : "nonempty")); - - Connection->SignalState &= ~SEL_READ; - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, - &Connection->Lock )) != NULL ) { - OSK_UINT RecvLen = 0, Received = 0; - PVOID RecvBuffer = 0; - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; - - TI_DbgPrint(DEBUG_TCP, - ("Getting the user buffer from %x\n", Mdl)); - - NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); - - TI_DbgPrint(DEBUG_TCP, - ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); - - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint - (DEBUG_TCP, - ("Connection->SocketContext: %x\n", - Connection->SocketContext)); - TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); - - Status = TCPTranslateError - ( OskitTCPRecv( Connection->SocketContext, - RecvBuffer, - RecvLen, - &Received, - 0 ) ); - - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); - - if( Status == STATUS_SUCCESS ) { - TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", - Received, Status)); - - Complete( Bucket->Request.RequestContext, - STATUS_SUCCESS, Received ); - exFreePool( Bucket ); - } else if( Status == STATUS_PENDING ) { - ExInterlockedInsertHeadList - ( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); - Connection->SignalState |= SEL_READ; - break; - } else { - TI_DbgPrint(DEBUG_TCP, - ("Completing Receive request: %x %x\n", - Bucket->Request, Status)); - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); - } - } - } - if( Connection->SignalState & SEL_WRITE ) { - TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", - IsListEmpty(&Connection->SendRequest) ? - "empty" : "nonempty")); - - Connection->SignalState &= ~SEL_WRITE; - while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, - &Connection->Lock )) != NULL ) { - OSK_UINT SendLen = 0, Sent = 0; - PVOID SendBuffer = 0; - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; - - TI_DbgPrint(DEBUG_TCP, - ("Getting the user buffer from %x\n", Mdl)); - - NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); - - TI_DbgPrint(DEBUG_TCP, - ("Writing %d bytes to %x\n", SendLen, SendBuffer)); - - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint - (DEBUG_TCP, - ("Connection->SocketContext: %x\n", - Connection->SocketContext)); - - Status = TCPTranslateError - ( OskitTCPSend( Connection->SocketContext, - SendBuffer, - SendLen, - &Sent, - 0 ) ); - - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); - - if( Status == STATUS_SUCCESS ) { - TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n", - Sent, Status)); - - Complete( Bucket->Request.RequestContext, - STATUS_SUCCESS, Sent ); - exFreePool( Bucket ); - } else if( Status == STATUS_PENDING ) { - ExInterlockedInsertHeadList - ( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); - Connection->SignalState |= SEL_WRITE; - break; - } else { - TI_DbgPrint(DEBUG_TCP, - ("Completing Send request: %x %x\n", - Bucket->Request, Status)); - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); - } - } - } - - return Connection->SignalState; -} - -static VOID DrainSignals() { - PCONNECTION_ENDPOINT Connection; - PLIST_ENTRY CurrentEntry, NextEntry; - ULONG NewState; - KIRQL OldIrql; - - KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); - CurrentEntry = SignalledConnectionsList.Flink; - while (CurrentEntry != &SignalledConnectionsList) + KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + CurrentEntry = ConnectionEndpointListHead.Flink; + while (CurrentEntry != &ConnectionEndpointListHead) { NextEntry = CurrentEntry->Flink; + KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); + Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, - SignalList ); + ListEntry ); - KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); - NewState = HandleSignalledConnection(Connection); - KeAcquireSpinLock(&SignalledConnectionsLock, &OldIrql); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); - if (NewState == SEL_FIN || NewState == 0) - { - RemoveEntryList(CurrentEntry); + TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", + Connection, Connection->SocketContext)); + + if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) { + KeReleaseSpinLock(&Connection->Lock, OldIrql); + TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); + + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + + exFreePool(Bucket); + } + + while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + + exFreePool(Bucket); + } + + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + + exFreePool(Bucket); + } + + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + + exFreePool(Bucket); + } + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); } - CurrentEntry = NextEntry; + /* Things that can happen when we try the initial connection */ + if( Connection->SignalState & SEL_CONNECT ) { + KeReleaseSpinLock(&Connection->Lock, OldIrql); + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, + &Connection->Lock )) != NULL ) { + + TI_DbgPrint(DEBUG_TCP, ("Connect Event\n")); + + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + TI_DbgPrint(DEBUG_TCP, + ("Completing Request %x\n", Bucket->Request.RequestContext)); + + Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); + + /* Frees the bucket allocated in TCPConnect */ + exFreePool( Bucket ); + } + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + + if( Connection->SignalState & SEL_ACCEPT ) { + /* Handle readable on a listening socket -- + * TODO: Implement filtering + */ + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", + Connection, + IsListEmpty(&Connection->ListenRequest) ? + "empty" : "nonempty")); + + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, + &Connection->Lock )) != NULL ) { + PIO_STACK_LOCATION IrpSp; + + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Irp = Bucket->Request.RequestContext; + IrpSp = IoGetCurrentIrpStackLocation( Irp ); + + TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + Status = TCPServiceListeningSocket + ( Connection->AddressFile->Listener, + Bucket->AssociatedEndpoint, + (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); + + if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, + &Connection->Lock ); + break; + } else { + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + + /* Things that happen after we're connected */ + if( Connection->SignalState & SEL_READ && + Connection->SignalState & SEL_CONNECT ) { + TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", + IsListEmpty(&Connection->ReceiveRequest) ? + "empty" : "nonempty")); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, + &Connection->Lock )) != NULL ) { + OSK_UINT RecvLen = 0, Received = 0; + PVOID RecvBuffer = 0; + + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Irp = Bucket->Request.RequestContext; + Mdl = Irp->MdlAddress; + + TI_DbgPrint(DEBUG_TCP, + ("Getting the user buffer from %x\n", Mdl)); + + NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); + + TI_DbgPrint(DEBUG_TCP, + ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); + + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint + (DEBUG_TCP, + ("Connection->SocketContext: %x\n", + Connection->SocketContext)); + TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + Status = TCPTranslateError + ( OskitTCPRecv( Connection->SocketContext, + RecvBuffer, + RecvLen, + &Received, + 0 ) ); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); + + if( Status == STATUS_SUCCESS ) { + TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", + Received, Status)); + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Received ); + exFreePool( Bucket ); + } else if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry, + &Connection->Lock ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Receive request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + if( Connection->SignalState & SEL_WRITE && + Connection->SignalState & SEL_CONNECT ) { + TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", + IsListEmpty(&Connection->SendRequest) ? + "empty" : "nonempty")); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, + &Connection->Lock )) != NULL ) { + OSK_UINT SendLen = 0, Sent = 0; + PVOID SendBuffer = 0; + + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Irp = Bucket->Request.RequestContext; + Mdl = Irp->MdlAddress; + + TI_DbgPrint(DEBUG_TCP, + ("Getting the user buffer from %x\n", Mdl)); + + NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); + + TI_DbgPrint(DEBUG_TCP, + ("Writing %d bytes to %x\n", SendLen, SendBuffer)); + + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint + (DEBUG_TCP, + ("Connection->SocketContext: %x\n", + Connection->SocketContext)); + + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + Status = TCPTranslateError + ( OskitTCPSend( Connection->SocketContext, + SendBuffer, + SendLen, + &Sent, + 0 ) ); + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); + + if( Status == STATUS_SUCCESS ) { + TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n", + Sent, Status)); + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Sent ); + exFreePool( Bucket ); + } else if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList( &Connection->SendRequest, &Bucket->Entry, + &Connection->Lock ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Send request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + } + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + + if (!Connection->SocketContext) + { + TCPFreeConnectionEndpoint(Connection); + } + + CurrentEntry = NextEntry; + + KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); } - KeReleaseSpinLock(&SignalledConnectionsLock, OldIrql); + + KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); } PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { @@ -314,7 +325,7 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT)); /* Initialize spin lock that protects the connection endpoint file object */ - TcpipInitializeSpinLock(&Connection->Lock); + KeInitializeSpinLock(&Connection->Lock); InitializeListHead(&Connection->ConnectRequest); InitializeListHead(&Connection->ListenRequest); InitializeListHead(&Connection->ReceiveRequest); @@ -323,19 +334,32 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { /* Save client context pointer */ Connection->ClientContext = ClientContext; + /* Add connection endpoint to global list */ + ExInterlockedInsertTailList(&ConnectionEndpointListHead, + &Connection->ListEntry, + &ConnectionEndpointListLock); + return Connection; } VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) { + KIRQL OldIrql; + TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n")); + + TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + RemoveEntryList(&Connection->ListEntry); + TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); + exFreePool( Connection ); } NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ) { NTSTATUS Status; + KIRQL OldIrql; - TcpipRecursiveMutexEnter(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, " "Proto %d\n", @@ -352,7 +376,7 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", Connection->SocketContext)); - TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql); return Status; } @@ -370,13 +394,9 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) IPPacket->TotalSize, IPPacket->HeaderSize)); - TcpipRecursiveMutexEnter( &TCPLock ); - OskitTCPReceiveDatagram( IPPacket->Header, IPPacket->TotalSize, IPPacket->HeaderSize ); - - TcpipRecursiveMutexLeave( &TCPLock ); } /* event.c */ @@ -447,10 +467,7 @@ TimerThread(PVOID Context) PsTerminateSystemThread(Status); } - TcpipRecursiveMutexEnter( &TCPLock ); TimerOskitTCP( Next == NextFast, Next == NextSlow ); - TcpipRecursiveMutexLeave( &TCPLock ); - if (Next == NextSlow) { DrainSignals(); } @@ -483,9 +500,6 @@ NTSTATUS TCPStartup(VOID) { NTSTATUS Status; - TcpipRecursiveMutexInit( &TCPLock ); - KeInitializeSpinLock( &SignalledConnectionsLock ); - InitializeListHead( &SignalledConnectionsList ); Status = TCPMemStartup(); if ( ! NT_SUCCESS(Status) ) { return Status; @@ -497,10 +511,8 @@ NTSTATUS TCPStartup(VOID) return Status; } - TcpipRecursiveMutexEnter(&TCPLock); RegisterOskitTCPEventHandlers( &EventHandlers ); InitOskitTCP(); - TcpipRecursiveMutexLeave(&TCPLock); /* Register this protocol with IP layer */ IPRegisterProtocol(IPPROTO_TCP, TCPReceive); @@ -545,9 +557,7 @@ NTSTATUS TCPShutdown(VOID) TCPInitialized = FALSE; - TcpipRecursiveMutexEnter(&TCPLock); DeinitOskitTCP(); - TcpipRecursiveMutexLeave(&TCPLock); PortsShutdown( &TCPPorts ); @@ -597,6 +607,7 @@ NTSTATUS TCPConnect USHORT RemotePort; PTDI_BUCKET Bucket; PNEIGHBOR_CACHE_ENTRY NCE; + KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n")); @@ -625,7 +636,7 @@ NTSTATUS TCPConnect AddressToBind = AddressToConnect; AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address; - TcpipRecursiveMutexEnter(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); Status = TCPTranslateError ( OskitTCPBind( Connection->SocketContext, @@ -640,26 +651,29 @@ NTSTATUS TCPConnect Status = TCPTranslateError ( OskitTCPConnect( Connection->SocketContext, - Connection, &AddressToConnect, sizeof(AddressToConnect) ) ); + KeReleaseSpinLock(&Connection->Lock, OldIrql); + if (Status == STATUS_PENDING) { Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); - if( !Bucket ) return STATUS_NO_MEMORY; + if( !Bucket ) + { + return STATUS_NO_MEMORY; + } Bucket->Request.RequestNotifyObject = (PVOID)Complete; Bucket->Request.RequestContext = Context; - - IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, + &Connection->Lock ); } + } else { + KeReleaseSpinLock(&Connection->Lock, OldIrql); } - TcpipRecursiveMutexLeave(&TCPLock); - return Status; } @@ -671,12 +685,11 @@ NTSTATUS TCPDisconnect PTCP_COMPLETION_ROUTINE Complete, PVOID Context ) { NTSTATUS Status = STATUS_INVALID_PARAMETER; - - ASSERT_LOCKED(&TCPLock); + KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("started\n")); - TcpipRecursiveMutexEnter(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); if (Flags & TDI_DISCONNECT_RELEASE) Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext)); @@ -684,7 +697,7 @@ NTSTATUS TCPDisconnect if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD)); - TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status)); @@ -694,20 +707,20 @@ NTSTATUS TCPDisconnect NTSTATUS TCPClose ( PCONNECTION_ENDPOINT Connection ) { NTSTATUS Status; + KIRQL OldIrql; + PVOID Socket; TI_DbgPrint(DEBUG_TCP,("TCPClose started\n")); - /* Make our code remove all pending IRPs */ - Connection->SignalState |= SEL_FIN; - HandleSignalledConnection(Connection); - - TcpipRecursiveMutexEnter(&TCPLock); - - Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) ); - if (Status == STATUS_SUCCESS) - Connection->SocketContext = NULL; - - TcpipRecursiveMutexLeave(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + Socket = Connection->SocketContext; + Connection->SocketContext = NULL; + Status = TCPTranslateError( OskitTCPClose( Socket ) ); + if (!NT_SUCCESS(Status)) + { + Connection->SocketContext = Socket; + } + KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status)); @@ -726,17 +739,18 @@ NTSTATUS TCPReceiveData UINT DataLen, Received = 0; NTSTATUS Status; PTDI_BUCKET Bucket; + KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", ReceiveLength, Connection->SocketContext)); - ASSERT_KM_POINTER(Connection->SocketContext); - NdisQueryBuffer( Buffer, &DataBuffer, &DataLen ); TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); - TcpipRecursiveMutexEnter(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + ASSERT_KM_POINTER(Connection->SocketContext); Status = TCPTranslateError ( OskitTCPRecv @@ -746,7 +760,7 @@ NTSTATUS TCPReceiveData &Received, ReceiveFlags ) ); - TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received)); @@ -763,9 +777,8 @@ NTSTATUS TCPReceiveData Bucket->Request.RequestContext = Context; *BytesReceived = 0; - IoMarkIrpPending((PIRP)Context); - - ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, + &Connection->Lock ); TI_DbgPrint(DEBUG_TCP,("Queued read irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received)); @@ -788,8 +801,9 @@ NTSTATUS TCPSendData UINT Sent = 0; NTSTATUS Status; PTDI_BUCKET Bucket; + KIRQL OldIrql; - ASSERT_LOCKED(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", SendLength, Connection->SocketContext)); @@ -800,14 +814,12 @@ NTSTATUS TCPSendData TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n", Connection->SocketContext)); - TcpipRecursiveMutexEnter(&TCPLock); - Status = TCPTranslateError ( OskitTCPSend( Connection->SocketContext, (OSK_PCHAR)BufferData, SendLength, &Sent, 0 ) ); - TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent)); @@ -823,10 +835,9 @@ NTSTATUS TCPSendData Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; *BytesSent = 0; - - IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, + &Connection->Lock ); TI_DbgPrint(DEBUG_TCP,("Queued write irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent)); @@ -865,14 +876,15 @@ NTSTATUS TCPGetSockAddress OSK_UI16 LocalPort, RemotePort; PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address; NTSTATUS Status; + KIRQL OldIrql; - TcpipRecursiveMutexEnter(&TCPLock); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext, &LocalAddress, &LocalPort, &RemoteAddress, &RemotePort)); - TcpipRecursiveMutexLeave(&TCPLock); + KeReleaseSpinLock(&Connection->Lock, OldIrql); if (!NT_SUCCESS(Status)) return Status; diff --git a/reactos/lib/drivers/ip/transport/udp/udp.c b/reactos/lib/drivers/ip/transport/udp/udp.c index 46366e6833d..125e5101fc0 100644 --- a/reactos/lib/drivers/ip/transport/udp/udp.c +++ b/reactos/lib/drivers/ip/transport/udp/udp.c @@ -172,6 +172,9 @@ NTSTATUS UDPSendDatagram( USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; + KIRQL OldIrql; + + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -186,10 +189,12 @@ NTSTATUS UDPSendDatagram( break; default: + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_UNSUCCESSFUL; } if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_NETWORK_UNREACHABLE; } @@ -213,14 +218,20 @@ NTSTATUS UDPSendDatagram( DataSize ); if( !NT_SUCCESS(Status) ) + { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; + } if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ))) { + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + return STATUS_SUCCESS; } diff --git a/reactos/lib/drivers/oskittcp/include/oskittcp.h b/reactos/lib/drivers/oskittcp/include/oskittcp.h index b5242fe03a9..b8c008e2172 100644 --- a/reactos/lib/drivers/oskittcp/include/oskittcp.h +++ b/reactos/lib/drivers/oskittcp/include/oskittcp.h @@ -123,7 +123,7 @@ extern int OskitTCPSend( void *socket, OSK_UINT *OutLen, OSK_UINT Flags ); -extern int OskitTCPConnect( void *socket, void *connection, +extern int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ); extern int OskitTCPClose( void *socket ); @@ -131,7 +131,7 @@ extern int OskitTCPBind( void *socket, void *nam, OSK_UINT namelen ); extern int OskitTCPAccept( void *socket, void **new_socket, - void *addr_out, + void *context, void *addr_out, OSK_UINT addr_len, OSK_UINT *out_addr_len, OSK_UINT finish_accept ); @@ -187,4 +187,27 @@ void fbsd_free( void *data, char *file, unsigned line, ... ); #define FREAD 0x0001 #define FWRITE 0x0002 +/* Don't define this unless your are insane or aicom */ +//#define LOCK_SPAM + +#ifdef LOCK_SPAM +#define OSKLock() if (!KeTryToAcquireSpinLockAtDpcLevel(&OSKLock)) \ + { \ + DbgPrint("OSKLock WAIT (%s)\n", __FUNCTION__); \ + KeAcquireSpinLockAtDpcLevel(&OSKLock); \ + } \ + DbgPrint("OSKLock >>>> (%s)\n", __FUNCTION__) + +#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock); \ + DbgPrint("OSKLock <<<< (%s)\n", __FUNCTION__) +#else +#define OSKLock() KeAcquireSpinLockAtDpcLevel(&OSKLock) +#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock) +#endif + +#define OSKLockAndRaise(x) KeRaiseIrql(DISPATCH_LEVEL, x); \ + OSKLock() +#define OSKUnlockAndLower(x) OSKUnlock(); \ + KeLowerIrql(x) + #endif/*OSKITTCP_H*/ diff --git a/reactos/lib/drivers/oskittcp/oskittcp/interface.c b/reactos/lib/drivers/oskittcp/oskittcp/interface.c index 5aea3ddd517..ef6f521cd58 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/interface.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/interface.c @@ -23,6 +23,8 @@ OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 }; //OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA; OSK_UINT OskitDebugTraceLevel = 0; +KSPIN_LOCK OSKLock; + /* SPL */ unsigned cpl; unsigned net_imask; @@ -45,6 +47,7 @@ void fbsd_free( void *data, char *file, unsigned line, ... ) { void InitOskitTCP() { OS_DbgPrint(OSK_MID_TRACE,("Init Called\n")); + KeInitializeSpinLock(&OSKLock); OS_DbgPrint(OSK_MID_TRACE,("MB Init\n")); mbinit(); OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n")); @@ -66,12 +69,19 @@ void DeinitOskitTCP() { } void TimerOskitTCP( int FastTimer, int SlowTimer ) { + KIRQL OldIrql; + + /* This function is a special case in which we cannot use OSKLock/OSKUnlock + * because we don't enter with the connection lock held */ + + OSKLockAndRaise(&OldIrql); if ( SlowTimer ) { tcp_slowtimo(); } if ( FastTimer ) { tcp_fasttimo(); } + OSKUnlockAndLower(OldIrql); } void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) { @@ -115,12 +125,16 @@ int OskitTCPSocket( void *context, int proto ) { struct socket *so; + + OSKLock(); int error = socreate(domain, &so, type, proto); if( !error ) { so->so_connection = context; so->so_state |= SS_NBIO; *aso = so; } + OSKUnlock(); + return error; } @@ -153,8 +167,11 @@ int OskitTCPRecv( void *connection, OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len)); + OSKLock(); error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */, &tcp_flags ); + OSKUnlock(); + *OutLen = Len - uio.uio_resid; return error; @@ -182,14 +199,15 @@ int OskitTCPBind( void *socket, addr.sa_family = addr.sa_len; addr.sa_len = sizeof(struct sockaddr); + OSKLock(); error = sobind(so, &sabuf); + OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return (error); } -int OskitTCPConnect( void *socket, void *connection, - void *nam, OSK_UINT namelen ) { +int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) { struct socket *so = socket; int error = EFAULT; struct mbuf sabuf; @@ -197,8 +215,7 @@ int OskitTCPConnect( void *socket, void *connection, OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket)); - so->so_connection = connection; - + OSKLock(); if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { error = EALREADY; goto done; @@ -217,7 +234,9 @@ int OskitTCPConnect( void *socket, void *connection, error = soconnect(so, &sabuf); - if (error) + if (error == EINPROGRESS) + goto done; + else if (error) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { @@ -232,34 +251,49 @@ bad: error = EINTR; done: + OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return (error); } int OskitTCPDisconnect(void *socket) { + int error; + if (!socket) return OSK_ESHUTDOWN; - return sodisconnect(socket); + OSKLock(); + error = sodisconnect(socket); + OSKUnlock(); + + return error; } int OskitTCPShutdown( void *socket, int disconn_type ) { + int error; + if (!socket) return OSK_ESHUTDOWN; - return soshutdown( socket, disconn_type ); + OSKLock(); + error = soshutdown( socket, disconn_type ); + OSKUnlock(); + + return error; } int OskitTCPClose( void *socket ) { - struct socket *so = socket; + int error; if (!socket) return OSK_ESHUTDOWN; - so->so_connection = 0; - soclose( so ); - return 0; + OSKLock(); + error = soclose( socket ); + OSKUnlock(); + + return error; } int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, @@ -281,7 +315,10 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, uio.uio_rw = UIO_WRITE; uio.uio_procp = NULL; + OSKLock(); error = sosend( socket, NULL, &uio, NULL, NULL, 0 ); + OSKUnlock(); + *OutLen = Len - uio.uio_resid; return error; @@ -289,6 +326,7 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, int OskitTCPAccept( void *socket, void **new_socket, + void *context, void *AddrOut, OSK_UINT AddrLen, OSK_UINT *OutAddrLen, @@ -317,11 +355,12 @@ int OskitTCPAccept( void *socket, /* that's a copyin actually */ namelen = *OutAddrLen; + OSKLock(); + s = splnet(); #if 0 if ((head->so_options & SO_ACCEPTCONN) == 0) { - splx(s); OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n", head->so_options, SO_ACCEPTCONN)); error = EINVAL; @@ -333,39 +372,10 @@ int OskitTCPAccept( void *socket, head->so_q, head->so_state)); if ((head->so_state & SS_NBIO) && head->so_q == NULL) { - splx(s); error = EWOULDBLOCK; goto out; } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - while (head->so_q == NULL && head->so_error == 0) { - if (head->so_state & SS_CANTRCVMORE) { - head->so_error = ECONNABORTED; - break; - } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - error = tsleep((caddr_t)&head->so_timeo, PSOCK | PCATCH, - "accept", 0); - if (error) { - splx(s); - goto out; - } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - -#if 0 - if (head->so_error) { - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - error = head->so_error; - head->so_error = 0; - splx(s); - goto out; - } - OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); -#endif - /* * At this point we know that there is at least one connection * ready to be accepted. Remove it from the queue. @@ -384,19 +394,20 @@ int OskitTCPAccept( void *socket, head->so_q = so->so_q; head->so_qlen--; - *newso = so; - - /*so->so_state &= ~SS_COMP;*/ - mnam.m_data = (char *)&sa; mnam.m_len = sizeof(sa); - (void) soaccept(so, &mnam); + error = soaccept(so, &mnam); + if (error) + goto out; - so->so_state = SS_NBIO | SS_ISCONNECTED; + so->so_state |= SS_NBIO | SS_ISCONNECTED; so->so_q = so->so_q0 = NULL; so->so_qlen = 0; so->so_head = 0; + so->so_connection = context; + + *newso = so; OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); if (name) { @@ -406,9 +417,10 @@ int OskitTCPAccept( void *socket, *OutAddrLen = namelen; /* copyout actually */ } OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); - splx(s); } out: + splx(s); + OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error)); return (error); } @@ -421,10 +433,20 @@ out: void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, OSK_UINT IpHeaderLen ) { - struct mbuf *Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); + struct mbuf *Ip; struct ip *iph; + KIRQL OldIrql; - if( !Ip ) return; /* drop the segment */ + /* This function is a special case in which we cannot use OSKLock/OSKUnlock + * because we don't enter with the connection lock held */ + + OSKLockAndRaise(&OldIrql); + Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); + if( !Ip ) + { + OSKUnlockAndLower(OldIrql); + return; /* drop the segment */ + } //memcpy( Ip->m_data, Data, Len ); Ip->m_pkthdr.len = IpHeaderLen; @@ -439,6 +461,7 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, IpHeaderLen)); tcp_input(Ip, IpHeaderLen); + OSKUnlockAndLower(OldIrql); /* The buffer Ip is freed by tcp_input */ } @@ -450,6 +473,7 @@ int OskitTCPSetSockOpt(void *socket, int size) { struct mbuf *m; + int error; if (!socket) return OSK_ESHUTDOWN; @@ -457,16 +481,23 @@ int OskitTCPSetSockOpt(void *socket, if (size >= MLEN) return OSK_EINVAL; + OSKLock(); m = m_get(M_WAIT, MT_SOOPTS); if (!m) + { + OSKUnlock(); return OSK_ENOMEM; + } m->m_len = size; memcpy(m->m_data, buffer, size); /* m is freed by sosetopt */ - return sosetopt(socket, level, optname, m); + error = sosetopt(socket, level, optname, m); + OSKUnlock(); + + return error; } int OskitTCPGetSockOpt(void *socket, @@ -481,6 +512,7 @@ int OskitTCPGetSockOpt(void *socket, if (!socket) return OSK_ESHUTDOWN; + OSKLock(); error = sogetopt(socket, level, optname, &m); if (!error) { @@ -489,6 +521,7 @@ int OskitTCPGetSockOpt(void *socket, if (!buffer || oldsize < m->m_len) { m_freem(m); + OSKUnlock(); return OSK_EINVAL; } @@ -496,6 +529,7 @@ int OskitTCPGetSockOpt(void *socket, m_freem(m); } + OSKUnlock(); return error; } @@ -507,7 +541,11 @@ int OskitTCPListen( void *socket, int backlog ) { return OSK_ESHUTDOWN; OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket)); + + OSKLock(); error = solisten( socket, backlog ); + OSKUnlock(); + OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return error; @@ -524,11 +562,13 @@ int OskitTCPSetAddress( void *socket, if (!socket) return OSK_ESHUTDOWN; + OSKLock(); inp = (struct inpcb *)so->so_pcb; inp->inp_laddr.s_addr = LocalAddress; inp->inp_lport = LocalPort; inp->inp_faddr.s_addr = RemoteAddress; inp->inp_fport = RemotePort; + OSKUnlock(); return 0; } @@ -544,11 +584,13 @@ int OskitTCPGetAddress( void *socket, if (!socket) return OSK_ESHUTDOWN; + OSKLock(); inp = (struct inpcb *)so->so_pcb; *LocalAddress = inp->inp_laddr.s_addr; *LocalPort = inp->inp_lport; *RemoteAddress = inp->inp_faddr.s_addr; *RemotePort = inp->inp_fport; + OSKUnlock(); return 0; } From 4d5c7b23b20e93e55a4a7cd66325f6a52c884f96 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 14 Nov 2009 18:48:07 +0000 Subject: [PATCH 050/140] - Fix build svn path=/trunk/; revision=44164 --- reactos/drivers/network/tcpip/include/precomp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/drivers/network/tcpip/include/precomp.h b/reactos/drivers/network/tcpip/include/precomp.h index ec563ac4b68..a7b2c885962 100644 --- a/reactos/drivers/network/tcpip/include/precomp.h +++ b/reactos/drivers/network/tcpip/include/precomp.h @@ -3,7 +3,6 @@ #include #include #include -#include <../recmutex/recmutex.h> #include #include #include From 27816093396dda3848672ed6cb792f05da9a0347 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 14 Nov 2009 18:52:33 +0000 Subject: [PATCH 051/140] - Fix build (try 2) svn path=/trunk/; revision=44165 --- reactos/drivers/network/tcpip/include/lock.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/reactos/drivers/network/tcpip/include/lock.h b/reactos/drivers/network/tcpip/include/lock.h index b7cad5d720d..31ed91a8495 100644 --- a/reactos/drivers/network/tcpip/include/lock.h +++ b/reactos/drivers/network/tcpip/include/lock.h @@ -12,8 +12,5 @@ extern VOID TcpipInterlockedInsertTailList( PLIST_ENTRY ListHead, PKSPIN_LOCK Lock ); extern VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ); extern VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ); -extern VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ); -extern VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ); -extern VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ); #endif/*_LOCK_H*/ From f0680faa1a5392df70aba4da04a88c8dcbce15b0 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 14 Nov 2009 19:03:37 +0000 Subject: [PATCH 052/140] - Fix build (try 3) - I have no idea how this built for me svn path=/trunk/; revision=44166 --- reactos/lib/drivers/ip/transport/tcp/if.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/reactos/lib/drivers/ip/transport/tcp/if.c b/reactos/lib/drivers/ip/transport/tcp/if.c index d9598aff798..0e5296425d1 100644 --- a/reactos/lib/drivers/ip/transport/tcp/if.c +++ b/reactos/lib/drivers/ip/transport/tcp/if.c @@ -37,8 +37,6 @@ POSK_IFADDR TCPGetInterfaceData( PIP_INTERFACE IF ) { struct sockaddr_in *dstaddr_in; ASSERT(ifaddr); - ASSERT_LOCKED(&TCPLock); - RtlZeroMemory(ifaddr, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in )); addr_in = (struct sockaddr_in *)&ifaddr[1]; @@ -81,8 +79,6 @@ POSK_IFADDR TCPFindInterface( void *ClientData, struct sockaddr_in *addr_in = (struct sockaddr_in *)ReqAddr; POSK_IFADDR InterfaceData; - ASSERT_LOCKED(&TCPLock); - TI_DbgPrint(DEBUG_TCPIF,("called for type %d\n", FindType)); if( !ReqAddr ) { From 94307ac7ec767537efe49db8596d04982d7c09e0 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 15 Nov 2009 19:08:27 +0000 Subject: [PATCH 053/140] - Implement reading user shell folders from registry See issue #4206 for more details. svn path=/trunk/; revision=44177 --- reactos/dll/win32/shell32/shellpath.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/reactos/dll/win32/shell32/shellpath.c b/reactos/dll/win32/shell32/shellpath.c index 5a39c8390b8..76fc17c3bf2 100644 --- a/reactos/dll/win32/shell32/shellpath.c +++ b/reactos/dll/win32/shell32/shellpath.c @@ -1011,7 +1011,9 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, */ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) { + DWORD dwSize; HRESULT hr; + HKEY hKey; WCHAR resourcePath[MAX_PATH]; LPCWSTR pDefaultPath = NULL; @@ -1022,6 +1024,18 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) if (!pszPath) return E_INVALIDARG; + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hKey) == ERROR_SUCCESS) + { + /* FIXME assume MAX_PATH size */ + dwSize = MAX_PATH * sizeof(WCHAR); + if (RegQueryValueExW(hKey, CSIDL_Data[folder].szValueName, NULL, NULL, (LPBYTE)pszPath, &dwSize) == ERROR_SUCCESS) + { + RegCloseKey(hKey); + return S_OK; + } + RegCloseKey(hKey); + } + if (CSIDL_Data[folder].szDefaultPath && IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath)) { From f3e43b25a85268d4b19701e5c5ffde96d12d87fb Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Sun, 15 Nov 2009 22:29:08 +0000 Subject: [PATCH 054/140] kjk_hyperion: "Gross hack. People with RosBE installed to a path with spaces can now compile again. Emergency over." svn path=/trunk/; revision=44182 --- reactos/tools/rbuild/backend/mingw/linkers/ld.mak | 8 +++++--- reactos/tools/rbuild/backend/mingw/mingw.cpp | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak index 812f30ec874..f90947d4aa9 100644 --- a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak +++ b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak @@ -5,7 +5,7 @@ LDFLAG_CONSOLE:=--subsystem=console LDFLAG_WINDOWS:=--subsystem=windows LDFLAG_NATIVE:=--subsystem=native -#(module, objs, deps, ldflags, output, def, libs, entry, base) +#(module, objs, deps, ldflags, output, def, libs, entry, base, extralibs) define RBUILD_LINK ifneq ($(6),) @@ -29,7 +29,7 @@ endif $(5): $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(7) $(3) $$(RSYM_TARGET) $$(PEFIXUP_TARGET) | ${call RBUILD_dir,$(5)} $$(ECHO_LD) - $${ld} --entry=$(8) --image-base=$(9) $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(7) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ + $${ld} --entry=$(8) --image-base=$(9) $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(10) $(7) $(10) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ ifneq ($(or $(6),$$(MODULETYPE$$($(1)_TYPE)_KMODE)),) $$(ECHO_PEFIXUP) $$(Q)$$(PEFIXUP_TARGET) $$@ $(if $(6),-exports) $$(if $$(MODULETYPE$($(1)_TYPE)_KMODE),-sections) @@ -67,4 +67,6 @@ endif endef #(module, def, deps, ldflags, libs, entry, base) -RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(5) $(value $(1)_LIBS) $(5),$(6),$(7)} +#~ RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(5) $(value $(1)_LIBS) $(5),$(6),$(7)} +#(module, def, deps, ldflags, libs, entry, base, extralibs) +RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(value $(1)_LIBS),$(6),$(7),$(5)} diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index 472e5960dac..aa4c3fec427 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -479,8 +479,8 @@ MingwBackend::GenerateGlobalVariables () const // Would be nice to have our own C++ runtime fputs ( "BUILTIN_CXXINCLUDES+= $(TARGET_CPPFLAGS)\n", fMakefile ); - fprintf ( fMakefile, "PROJECT_CCLIBS := $(shell ${TARGET_CC} -print-libgcc-file-name)\n" ); - fprintf ( fMakefile, "PROJECT_CXXLIBS := $(shell ${TARGET_CPP} -print-file-name=libstdc++.a) $(shell ${TARGET_CPP} -print-file-name=libgcc.a) $(shell ${TARGET_CPP} -print-file-name=libmingw32.a) $(shell ${TARGET_CPP} -print-file-name=libmingwex.a) $(shell ${TARGET_CPP} -print-file-name=libcoldname.a)\n" ); + fprintf ( fMakefile, "PROJECT_CCLIBS := \"$(shell ${TARGET_CC} -print-libgcc-file-name)\"\n" ); + fprintf ( fMakefile, "PROJECT_CXXLIBS := \"$(shell ${TARGET_CPP} -print-file-name=libstdc++.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libgcc.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libmingw32.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libmingwex.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libcoldname.a)\"\n" ); /* hack to get libgcc_eh.a, should check mingw version or something */ if (Environment::GetArch() == "amd64") From 5db2650780096dd92cb924239cecce3487e6811f Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 15 Nov 2009 22:45:31 +0000 Subject: [PATCH 055/140] sync dde with wine 1.1.33 svn path=/trunk/; revision=44183 --- reactos/dll/win32/user32/misc/dde.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/user32/misc/dde.c b/reactos/dll/win32/user32/misc/dde.c index 14cb58e7f89..9373d91f28f 100644 --- a/reactos/dll/win32/user32/misc/dde.c +++ b/reactos/dll/win32/user32/misc/dde.c @@ -368,6 +368,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, pInstance->nodeList = NULL; /* node will be added later */ pInstance->monitorFlags = afCmd & MF_MASK; pInstance->wStatus = 0; + pInstance->lastError = DMLERR_NO_ERROR; pInstance->servers = NULL; pInstance->convs[0] = NULL; pInstance->convs[1] = NULL; @@ -718,7 +719,7 @@ HDDEDATA WDML_InvokeCallback(WDML_INSTANCE* pInstance, UINT uType, UINT uFmt, H TRACE("invoking CB[%p] (%x %x %p %p %p %p %lx %lx)\n", pInstance->callback, uType, uFmt, hConv, hsz1, hsz2, hdata, dwData1, dwData2); - ret = pInstance->callback(uType, uFmt, hConv, hsz1, hsz2, hdata, dwData1, dwData2); + ret = pInstance->callback(uType, uFmt, hConv, hsz1, hsz2, hdata, dwData1, dwData2); TRACE("done => %p\n", ret); return ret; } From 86d5f9981c489a6807f07851833cf4e70d840bed Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 15 Nov 2009 22:58:08 +0000 Subject: [PATCH 056/140] sync crypt32 with wine 1.1.33 svn path=/trunk/; revision=44184 --- reactos/dll/win32/crypt32/base64.c | 240 +++- reactos/dll/win32/crypt32/cert.c | 309 ++++-- reactos/dll/win32/crypt32/chain.c | 1110 +++++++++++++++++-- reactos/dll/win32/crypt32/collectionstore.c | 74 +- reactos/dll/win32/crypt32/context.c | 80 +- reactos/dll/win32/crypt32/crl.c | 9 +- reactos/dll/win32/crypt32/crypt32.spec | 39 +- reactos/dll/win32/crypt32/crypt32_De.rc | 2 +- reactos/dll/win32/crypt32/crypt32_private.h | 21 +- reactos/dll/win32/crypt32/ctl.c | 17 +- reactos/dll/win32/crypt32/decode.c | 1014 ++++++++++++----- reactos/dll/win32/crypt32/encode.c | 222 +++- reactos/dll/win32/crypt32/filestore.c | 1 - reactos/dll/win32/crypt32/main.c | 5 +- reactos/dll/win32/crypt32/msg.c | 53 +- reactos/dll/win32/crypt32/object.c | 61 +- reactos/dll/win32/crypt32/oid.c | 15 +- reactos/dll/win32/crypt32/rootstore.c | 21 +- reactos/dll/win32/crypt32/serialize.c | 68 +- reactos/dll/win32/crypt32/store.c | 50 +- reactos/dll/win32/crypt32/str.c | 31 +- reactos/include/psdk/wincrypt.h | 12 + 22 files changed, 2824 insertions(+), 630 deletions(-) diff --git a/reactos/dll/win32/crypt32/base64.c b/reactos/dll/win32/crypt32/base64.c index 17e05d97530..4a6504a488e 100644 --- a/reactos/dll/win32/crypt32/base64.c +++ b/reactos/dll/win32/crypt32/base64.c @@ -60,6 +60,8 @@ static const char b64[] = typedef BOOL (*BinaryToStringAFunc)(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString); +typedef BOOL (*BinaryToStringWFunc)(const BYTE *pbBinary, + DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString); static BOOL EncodeBinaryToBinaryA(const BYTE *pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD *pcchString) @@ -97,7 +99,8 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); needed = bytes + pad_bytes + 1; - needed += (needed / 64 + 1) * strlen(sep); + if (sep) + needed += (needed / 64 + 1) * strlen(sep); if (needed > *out_len) { @@ -114,7 +117,7 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, i = 0; while (div > 0) { - if (i && i % 64 == 0) + if (sep && i && i % 64 == 0) { strcpy(ptr, sep); ptr += strlen(sep); @@ -160,7 +163,8 @@ static LONG encodeBase64A(const BYTE *in_buf, int in_len, LPCSTR sep, *ptr++ = '='; break; } - strcpy(ptr, sep); + if (sep) + strcpy(ptr, sep); return ERROR_SUCCESS; } @@ -170,14 +174,16 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, { static const char crlf[] = "\r\n", lf[] = "\n"; BOOL ret = TRUE; - LPCSTR header = NULL, trailer = NULL, sep = NULL; + LPCSTR header = NULL, trailer = NULL, sep; DWORD charsNeeded; if (dwFlags & CRYPT_STRING_NOCR) sep = lf; + else if (dwFlags & CRYPT_STRING_NOCRLF) + sep = NULL; else sep = crlf; - switch (dwFlags & 0x7fffffff) + switch (dwFlags & 0x0fffffff) { case CRYPT_STRING_BASE64: /* no header or footer */ @@ -198,7 +204,8 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, charsNeeded = 0; encodeBase64A(pbBinary, cbBinary, sep, NULL, &charsNeeded); - charsNeeded += strlen(sep); + if (sep) + charsNeeded += strlen(sep); if (header) charsNeeded += strlen(header) + strlen(sep); if (trailer) @@ -212,8 +219,11 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, { strcpy(ptr, header); ptr += strlen(ptr); - strcpy(ptr, sep); - ptr += strlen(sep); + if (sep) + { + strcpy(ptr, sep); + ptr += strlen(sep); + } } encodeBase64A(pbBinary, cbBinary, sep, ptr, &size); ptr += size - 1; @@ -221,8 +231,11 @@ static BOOL BinaryToBase64A(const BYTE *pbBinary, { strcpy(ptr, trailer); ptr += strlen(ptr); - strcpy(ptr, sep); - ptr += strlen(sep); + if (sep) + { + strcpy(ptr, sep); + ptr += strlen(sep); + } } *pcchString = charsNeeded - 1; } @@ -256,7 +269,7 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, return FALSE; } - switch (dwFlags & 0x7fffffff) + switch (dwFlags & 0x0fffffff) { case CRYPT_STRING_BINARY: encoder = EncodeBinaryToBinaryA; @@ -271,7 +284,210 @@ BOOL WINAPI CryptBinaryToStringA(const BYTE *pbBinary, case CRYPT_STRING_HEXASCII: case CRYPT_STRING_HEXADDR: case CRYPT_STRING_HEXASCIIADDR: - FIXME("Unimplemented type %d\n", dwFlags & 0x7fffffff); + FIXME("Unimplemented type %d\n", dwFlags & 0x0fffffff); + /* fall through */ + default: + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + return encoder(pbBinary, cbBinary, dwFlags, pszString, pcchString); +} + +static LONG encodeBase64W(const BYTE *in_buf, int in_len, LPCWSTR sep, + WCHAR* out_buf, DWORD *out_len) +{ + int div, i; + const BYTE *d = in_buf; + int bytes = (in_len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; + DWORD needed; + LPWSTR ptr; + + TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); + needed = bytes + pad_bytes + 1; + if (sep) + needed += (needed / 64 + 1) * strlenW(sep); + + if (needed > *out_len) + { + *out_len = needed; + return ERROR_INSUFFICIENT_BUFFER; + } + else + *out_len = needed; + + /* Three bytes of input give 4 chars of output */ + div = in_len / 3; + + ptr = out_buf; + i = 0; + while (div > 0) + { + if (sep && i && i % 64 == 0) + { + strcpyW(ptr, sep); + ptr += strlenW(sep); + } + /* first char is the first 6 bits of the first byte*/ + *ptr++ = b64[ ( d[0] >> 2) & 0x3f ]; + /* second char is the last 2 bits of the first byte and the first 4 + * bits of the second byte */ + *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)]; + /* third char is the last 4 bits of the second byte and the first 2 + * bits of the third byte */ + *ptr++ = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)]; + /* fourth char is the remaining 6 bits of the third byte */ + *ptr++ = b64[ d[2] & 0x3f]; + i += 4; + d += 3; + div--; + } + + switch(pad_bytes) + { + case 1: + /* first char is the first 6 bits of the first byte*/ + *ptr++ = b64[ ( d[0] >> 2) & 0x3f ]; + /* second char is the last 2 bits of the first byte and the first 4 + * bits of the second byte */ + *ptr++ = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)]; + /* third char is the last 4 bits of the second byte padded with + * two zeroes */ + *ptr++ = b64[ ((d[1] << 2) & 0x3c) ]; + /* fourth char is a = to indicate one byte of padding */ + *ptr++ = '='; + break; + case 2: + /* first char is the first 6 bits of the first byte*/ + *ptr++ = b64[ ( d[0] >> 2) & 0x3f ]; + /* second char is the last 2 bits of the first byte padded with + * four zeroes*/ + *ptr++ = b64[ ((d[0] << 4) & 0x30)]; + /* third char is = to indicate padding */ + *ptr++ = '='; + /* fourth char is = to indicate padding */ + *ptr++ = '='; + break; + } + if (sep) + strcpyW(ptr, sep); + + return ERROR_SUCCESS; +} + +static BOOL BinaryToBase64W(const BYTE *pbBinary, + DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString) +{ + static const WCHAR crlf[] = { '\r','\n',0 }, lf[] = { '\n',0 }; + BOOL ret = TRUE; + LPCWSTR header = NULL, trailer = NULL, sep; + DWORD charsNeeded; + + if (dwFlags & CRYPT_STRING_NOCR) + sep = lf; + else if (dwFlags & CRYPT_STRING_NOCRLF) + sep = NULL; + else + sep = crlf; + switch (dwFlags & 0x0fffffff) + { + case CRYPT_STRING_BASE64: + /* no header or footer */ + break; + case CRYPT_STRING_BASE64HEADER: + header = CERT_HEADER_W; + trailer = CERT_TRAILER_W; + break; + case CRYPT_STRING_BASE64REQUESTHEADER: + header = CERT_REQUEST_HEADER_W; + trailer = CERT_REQUEST_TRAILER_W; + break; + case CRYPT_STRING_BASE64X509CRLHEADER: + header = X509_HEADER_W; + trailer = X509_TRAILER_W; + break; + } + + charsNeeded = 0; + encodeBase64W(pbBinary, cbBinary, sep, NULL, &charsNeeded); + if (sep) + charsNeeded += strlenW(sep); + if (header) + charsNeeded += strlenW(header) + strlenW(sep); + if (trailer) + charsNeeded += strlenW(trailer) + strlenW(sep); + if (charsNeeded <= *pcchString) + { + LPWSTR ptr = pszString; + DWORD size = charsNeeded; + + if (header) + { + strcpyW(ptr, header); + ptr += strlenW(ptr); + if (sep) + { + strcpyW(ptr, sep); + ptr += strlenW(sep); + } + } + encodeBase64W(pbBinary, cbBinary, sep, ptr, &size); + ptr += size - 1; + if (trailer) + { + strcpyW(ptr, trailer); + ptr += strlenW(ptr); + if (sep) + { + strcpyW(ptr, sep); + ptr += strlenW(sep); + } + } + *pcchString = charsNeeded - 1; + } + else if (pszString) + { + *pcchString = charsNeeded; + SetLastError(ERROR_INSUFFICIENT_BUFFER); + ret = FALSE; + } + else + *pcchString = charsNeeded; + return ret; +} + +BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary, + DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString) +{ + BinaryToStringWFunc encoder = NULL; + + TRACE("(%p, %d, %08x, %p, %p)\n", pbBinary, cbBinary, dwFlags, pszString, + pcchString); + + if (!pbBinary) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (!pcchString) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + switch (dwFlags & 0x0fffffff) + { + case CRYPT_STRING_BASE64: + case CRYPT_STRING_BASE64HEADER: + case CRYPT_STRING_BASE64REQUESTHEADER: + case CRYPT_STRING_BASE64X509CRLHEADER: + encoder = BinaryToBase64W; + break; + case CRYPT_STRING_BINARY: + case CRYPT_STRING_HEX: + case CRYPT_STRING_HEXASCII: + case CRYPT_STRING_HEXADDR: + case CRYPT_STRING_HEXASCIIADDR: + FIXME("Unimplemented type %d\n", dwFlags & 0x0fffffff); /* fall through */ default: SetLastError(ERROR_INVALID_PARAMETER); diff --git a/reactos/dll/win32/crypt32/cert.c b/reactos/dll/win32/crypt32/cert.c index 1c0c74ecd14..4f3df326943 100644 --- a/reactos/dll/win32/crypt32/cert.c +++ b/reactos/dll/win32/crypt32/cert.c @@ -71,6 +71,53 @@ BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, return ret; } +BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName, + const BYTE *pbCertEncoded, DWORD cbCertEncoded) +{ + HCERTSTORE store; + BOOL ret = FALSE; + + TRACE("(%s, %p, %d)\n", debugstr_a(pszCertStoreName), pbCertEncoded, + cbCertEncoded); + + store = CertOpenSystemStoreA(0, pszCertStoreName); + if (store) + { + ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, + pbCertEncoded, cbCertEncoded, CERT_STORE_ADD_USE_EXISTING, NULL); + CertCloseStore(store, 0); + } + return ret; +} + +BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName, + const BYTE *pbCertEncoded, DWORD cbCertEncoded) +{ + HCERTSTORE store; + BOOL ret = FALSE; + + TRACE("(%s, %p, %d)\n", debugstr_w(pszCertStoreName), pbCertEncoded, + cbCertEncoded); + + store = CertOpenSystemStoreW(0, pszCertStoreName); + if (store) + { + ret = CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, + pbCertEncoded, cbCertEncoded, CERT_STORE_ADD_USE_EXISTING, NULL); + CertCloseStore(store, 0); + } + return ret; +} + +BOOL WINAPI CertAddCertificateLinkToStore(HCERTSTORE hCertStore, + PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, + PCCERT_CONTEXT *ppCertContext) +{ + FIXME("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, + ppCertContext); + return FALSE; +} + PCCERT_CONTEXT WINAPI CertCreateCertificateContext(DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded) { @@ -133,12 +180,14 @@ static void CertDataContext_Free(void *context) BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext) { + BOOL ret = TRUE; + TRACE("(%p)\n", pCertContext); if (pCertContext) - Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT), + ret = Context_Release((void *)pCertContext, sizeof(CERT_CONTEXT), CertDataContext_Free); - return TRUE; + return ret; } DWORD WINAPI CertEnumCertificateContextProperties(PCCERT_CONTEXT pCertContext, @@ -1120,12 +1169,6 @@ DWORD WINAPI CertGetPublicKeyLength(DWORD dwCertEncodingType, typedef BOOL (*CertCompareFunc)(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara); -static BOOL compare_cert_any(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, const void *pvPara) -{ - return TRUE; -} - static BOOL compare_cert_by_md5_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara) { @@ -1202,7 +1245,7 @@ static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext, /* Matching serial number and subject match.. */ ret = CertCompareCertificateName(pCertContext->dwCertEncodingType, - &pCertInfo->Issuer, &pCertContext->pCertInfo->Subject); + &pCertContext->pCertInfo->Subject, &pCertInfo->Issuer); if (ret) ret = CertCompareIntegerBlob(&pCertContext->pCertInfo->SerialNumber, &pCertInfo->SerialNumber); @@ -1213,7 +1256,7 @@ static BOOL compare_cert_by_subject_cert(PCCERT_CONTEXT pCertContext, &pCertInfo->SerialNumber); if (ret) ret = CertCompareCertificateName(pCertContext->dwCertEncodingType, - &pCertInfo->Issuer, &pCertContext->pCertInfo->Issuer); + &pCertContext->pCertInfo->Issuer, &pCertInfo->Issuer); } TRACE("returning %d\n", ret); return ret; @@ -1267,11 +1310,70 @@ static BOOL compare_cert_by_cert_id(PCCERT_CONTEXT pCertContext, DWORD dwType, return ret; } -static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType, +static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, const void *pvPara) { - BOOL ret = FALSE; - PCCERT_CONTEXT subject = pvPara; + PCCERT_CONTEXT toCompare = pvPara; + return CertCompareCertificate(pCertContext->dwCertEncodingType, + pCertContext->pCertInfo, toCompare->pCertInfo); +} + +static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, + DWORD dwFlags, const void *pvPara) +{ + const CRYPT_HASH_BLOB *hash = pvPara; + DWORD size = 0; + BOOL ret; + + ret = CertGetCertificateContextProperty(pCertContext, + CERT_SIGNATURE_HASH_PROP_ID, NULL, &size); + if (ret && size == hash->cbData) + { + LPBYTE buf = CryptMemAlloc(size); + + if (buf) + { + CertGetCertificateContextProperty(pCertContext, + CERT_SIGNATURE_HASH_PROP_ID, buf, &size); + ret = !memcmp(buf, hash->pbData, size); + CryptMemFree(buf); + } + } + else + ret = FALSE; + return ret; +} + +static inline PCCERT_CONTEXT cert_compare_certs_in_store(HCERTSTORE store, + PCCERT_CONTEXT prev, CertCompareFunc compare, DWORD dwType, DWORD dwFlags, + const void *pvPara) +{ + BOOL matches = FALSE; + PCCERT_CONTEXT ret; + + ret = prev; + do { + ret = CertEnumCertificatesInStore(store, ret); + if (ret) + matches = compare(ret, dwType, dwFlags, pvPara); + } while (ret != NULL && !matches); + return ret; +} + +typedef PCCERT_CONTEXT (*CertFindFunc)(HCERTSTORE store, DWORD dwType, + DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev); + +static PCCERT_CONTEXT find_cert_any(HCERTSTORE store, DWORD dwType, + DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev) +{ + return CertEnumCertificatesInStore(store, prev); +} + +static PCCERT_CONTEXT find_cert_by_issuer(HCERTSTORE store, DWORD dwType, + DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev) +{ + BOOL ret; + PCCERT_CONTEXT found = NULL, subject = pvPara; PCERT_EXTENSION ext; DWORD size; @@ -1295,18 +1397,17 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType, sizeof(CERT_NAME_BLOB)); memcpy(&id.u.IssuerSerialNumber.SerialNumber, &info->CertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); - ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags, - &id); } else if (info->KeyId.cbData) { id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); - ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags, - &id); } else ret = FALSE; + if (ret) + found = cert_compare_certs_in_store(store, prev, + compare_cert_by_cert_id, dwType, dwFlags, &id); LocalFree(info); } } @@ -1343,8 +1444,6 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType, memcpy(&id.u.IssuerSerialNumber.SerialNumber, &info->AuthorityCertSerialNumber, sizeof(CRYPT_INTEGER_BLOB)); - ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags, - &id); } else { @@ -1356,53 +1455,83 @@ static BOOL compare_cert_by_issuer(PCCERT_CONTEXT pCertContext, DWORD dwType, { id.dwIdChoice = CERT_ID_KEY_IDENTIFIER; memcpy(&id.u.KeyId, &info->KeyId, sizeof(CRYPT_HASH_BLOB)); - ret = compare_cert_by_cert_id(pCertContext, dwType, dwFlags, - &id); } else ret = FALSE; + if (ret) + found = cert_compare_certs_in_store(store, prev, + compare_cert_by_cert_id, dwType, dwFlags, &id); LocalFree(info); } } else - ret = compare_cert_by_name(pCertContext, - CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, dwFlags, - &subject->pCertInfo->Issuer); + found = cert_compare_certs_in_store(store, prev, + compare_cert_by_name, CERT_COMPARE_NAME | CERT_COMPARE_SUBJECT_CERT, + dwFlags, &subject->pCertInfo->Issuer); + return found; +} + +static BOOL compare_cert_by_name_str(PCCERT_CONTEXT pCertContext, + DWORD dwType, DWORD dwFlags, const void *pvPara) +{ + PCERT_NAME_BLOB name; + DWORD len; + BOOL ret = FALSE; + + if (dwType & CERT_INFO_SUBJECT_FLAG) + name = &pCertContext->pCertInfo->Subject; + else + name = &pCertContext->pCertInfo->Issuer; + len = CertNameToStrW(pCertContext->dwCertEncodingType, name, + CERT_SIMPLE_NAME_STR, NULL, 0); + if (len) + { + LPWSTR str = CryptMemAlloc(len * sizeof(WCHAR)); + + if (str) + { + LPWSTR ptr; + + CertNameToStrW(pCertContext->dwCertEncodingType, name, + CERT_SIMPLE_NAME_STR, str, len); + for (ptr = str; *ptr; ptr++) + *ptr = tolowerW(*ptr); + if (strstrW(str, pvPara)) + ret = TRUE; + CryptMemFree(str); + } + } return ret; } -static BOOL compare_existing_cert(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, const void *pvPara) +static PCCERT_CONTEXT find_cert_by_name_str(HCERTSTORE store, DWORD dwType, + DWORD dwFlags, const void *pvPara, PCCERT_CONTEXT prev) { - PCCERT_CONTEXT toCompare = pvPara; - return CertCompareCertificate(pCertContext->dwCertEncodingType, - pCertContext->pCertInfo, toCompare->pCertInfo); -} + PCCERT_CONTEXT found = NULL; -static BOOL compare_cert_by_signature_hash(PCCERT_CONTEXT pCertContext, DWORD dwType, - DWORD dwFlags, const void *pvPara) -{ - const CRYPT_HASH_BLOB *hash = pvPara; - DWORD size = 0; - BOOL ret; + TRACE("%s\n", debugstr_w(pvPara)); - ret = CertGetCertificateContextProperty(pCertContext, - CERT_SIGNATURE_HASH_PROP_ID, NULL, &size); - if (ret && size == hash->cbData) + if (pvPara) { - LPBYTE buf = CryptMemAlloc(size); + DWORD len = strlenW(pvPara); + LPWSTR str = CryptMemAlloc((len + 1) * sizeof(WCHAR)); - if (buf) + if (str) { - CertGetCertificateContextProperty(pCertContext, - CERT_SIGNATURE_HASH_PROP_ID, buf, &size); - ret = !memcmp(buf, hash->pbData, size); - CryptMemFree(buf); + LPCWSTR src; + LPWSTR dst; + + for (src = pvPara, dst = str; *src; src++, dst++) + *dst = tolowerW(*src); + *dst = 0; + found = cert_compare_certs_in_store(store, prev, + compare_cert_by_name_str, dwType, dwFlags, str); + CryptMemFree(str); } } else - ret = FALSE; - return ret; + found = find_cert_any(store, dwType, dwFlags, NULL, prev); + return found; } PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, @@ -1410,7 +1539,8 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext) { PCCERT_CONTEXT ret; - CertCompareFunc compare; + CertFindFunc find = NULL; + CertCompareFunc compare = NULL; TRACE("(%p, %08x, %08x, %08x, %p, %p)\n", hCertStore, dwCertEncodingType, dwFlags, dwType, pvPara, pPrevCertContext); @@ -1418,7 +1548,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, switch (dwType >> CERT_COMPARE_SHIFT) { case CERT_COMPARE_ANY: - compare = compare_cert_any; + find = find_cert_any; break; case CERT_COMPARE_MD5_HASH: compare = compare_cert_by_md5_hash; @@ -1432,6 +1562,9 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, case CERT_COMPARE_PUBLIC_KEY: compare = compare_cert_by_public_key; break; + case CERT_COMPARE_NAME_STR_W: + find = find_cert_by_name_str; + break; case CERT_COMPARE_SUBJECT_CERT: compare = compare_cert_by_subject_cert; break; @@ -1439,7 +1572,7 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, compare = compare_cert_by_cert_id; break; case CERT_COMPARE_ISSUER_OF: - compare = compare_cert_by_issuer; + find = find_cert_by_issuer; break; case CERT_COMPARE_EXISTING: compare = compare_existing_cert; @@ -1449,27 +1582,17 @@ PCCERT_CONTEXT WINAPI CertFindCertificateInStore(HCERTSTORE hCertStore, break; default: FIXME("find type %08x unimplemented\n", dwType); - compare = NULL; } - if (compare) - { - BOOL matches = FALSE; - - ret = pPrevCertContext; - do { - ret = CertEnumCertificatesInStore(hCertStore, ret); - if (ret) - matches = compare(ret, dwType, dwFlags, pvPara); - } while (ret != NULL && !matches); - if (!ret) - SetLastError(CRYPT_E_NOT_FOUND); - } + if (find) + ret = find(hCertStore, dwFlags, dwType, pvPara, pPrevCertContext); + else if (compare) + ret = cert_compare_certs_in_store(hCertStore, pPrevCertContext, + compare, dwType, dwFlags, pvPara); else - { - SetLastError(CRYPT_E_NOT_FOUND); ret = NULL; - } + if (!ret) + SetLastError(CRYPT_E_NOT_FOUND); TRACE("returning %p\n", ret); return ret; } @@ -1781,13 +1904,19 @@ BOOL WINAPI CryptHashPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, ALG_ID Algid, hCryptProv = CRYPT_GetDefaultProvider(); if (!Algid) Algid = CALG_MD5; + if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) + { + SetLastError(ERROR_FILE_NOT_FOUND); + return FALSE; + } if (ret) { BYTE *buf; DWORD size = 0; - ret = CryptEncodeObjectEx(dwCertEncodingType, X509_PUBLIC_KEY_INFO, - pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ret = CRYPT_AsnEncodePubKeyInfoNoNull(dwCertEncodingType, + X509_PUBLIC_KEY_INFO, pInfo, CRYPT_ENCODE_ALLOC_FLAG, NULL, + (LPBYTE)&buf, &size); if (ret) { ret = CryptCreateHash(hCryptProv, Algid, 0, 0, &hHash); @@ -2117,6 +2246,43 @@ BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv, return ret; } +BOOL WINAPI CertGetIntendedKeyUsage(DWORD dwCertEncodingType, + PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage) +{ + PCERT_EXTENSION ext; + BOOL ret = FALSE; + + TRACE("(%08x, %p, %p, %d)\n", dwCertEncodingType, pCertInfo, pbKeyUsage, + cbKeyUsage); + + ext = CertFindExtension(szOID_KEY_USAGE, pCertInfo->cExtension, + pCertInfo->rgExtension); + if (ext) + { + CRYPT_BIT_BLOB usage; + DWORD size = sizeof(usage); + + ret = CryptDecodeObjectEx(dwCertEncodingType, X509_BITS, + ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, + &usage, &size); + if (ret) + { + if (cbKeyUsage < usage.cbData) + ret = FALSE; + else + { + memcpy(pbKeyUsage, usage.pbData, usage.cbData); + if (cbKeyUsage > usage.cbData) + memset(pbKeyUsage + usage.cbData, 0, + cbKeyUsage - usage.cbData); + } + } + } + else + SetLastError(0); + return ret; +} + BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags, PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage) { @@ -2727,7 +2893,10 @@ static void CRYPT_MakeCertInfo(PCERT_INFO info, const CRYPT_DATA_BLOB *pSerialNu assert(pSubjectIssuerBlob); assert(pubKey); - info->dwVersion = CERT_V3; + if (pExtensions && pExtensions->cExtension) + info->dwVersion = CERT_V3; + else + info->dwVersion = CERT_V1; info->SerialNumber.cbData = pSerialNumber->cbData; info->SerialNumber.pbData = pSerialNumber->pbData; if (pSignatureAlgorithm) diff --git a/reactos/dll/win32/crypt32/chain.c b/reactos/dll/win32/crypt32/chain.c index fa9fdf0f34a..eb6d757ce7f 100644 --- a/reactos/dll/win32/crypt32/chain.c +++ b/reactos/dll/win32/crypt32/chain.c @@ -69,6 +69,24 @@ static inline void CRYPT_CloseStores(DWORD cStores, HCERTSTORE *stores) static const WCHAR rootW[] = { 'R','o','o','t',0 }; +/* Finds cert in store by comparing the cert's hashes. */ +static PCCERT_CONTEXT CRYPT_FindCertInStore(HCERTSTORE store, + PCCERT_CONTEXT cert) +{ + PCCERT_CONTEXT matching = NULL; + BYTE hash[20]; + DWORD size = sizeof(hash); + + if (CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, hash, &size)) + { + CRYPT_HASH_BLOB blob = { sizeof(hash), hash }; + + matching = CertFindCertificateInStore(store, cert->dwCertEncodingType, + 0, CERT_FIND_SHA1_HASH, &blob, NULL); + } + return matching; +} + static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store) { BOOL ret = TRUE; @@ -77,29 +95,15 @@ static BOOL CRYPT_CheckRestrictedRoot(HCERTSTORE store) { HCERTSTORE rootStore = CertOpenSystemStoreW(0, rootW); PCCERT_CONTEXT cert = NULL, check; - BYTE hash[20]; - DWORD size; do { cert = CertEnumCertificatesInStore(store, cert); if (cert) { - size = sizeof(hash); - - ret = CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, - hash, &size); - if (ret) - { - CRYPT_HASH_BLOB blob = { sizeof(hash), hash }; - - check = CertFindCertificateInStore(rootStore, - cert->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob, - NULL); - if (!check) - ret = FALSE; - else - CertFreeCertificateContext(check); - } + if (!(check = CRYPT_FindCertInStore(rootStore, cert))) + ret = FALSE; + else + CertFreeCertificateContext(check); } } while (ret && cert); if (cert) @@ -336,16 +340,9 @@ static void CRYPT_FreeSimpleChain(PCERT_SIMPLE_CHAIN chain) static void CRYPT_CheckTrustedStatus(HCERTSTORE hRoot, PCERT_CHAIN_ELEMENT rootElement) { - BYTE hash[20]; - DWORD size = sizeof(hash); - CRYPT_HASH_BLOB blob = { sizeof(hash), hash }; - PCCERT_CONTEXT trustedRoot; + PCCERT_CONTEXT trustedRoot = CRYPT_FindCertInStore(hRoot, + rootElement->pCertContext); - CertGetCertificateContextProperty(rootElement->pCertContext, - CERT_HASH_PROP_ID, hash, &size); - trustedRoot = CertFindCertificateInStore(hRoot, - rootElement->pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, - &blob, NULL); if (!trustedRoot) rootElement->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_UNTRUSTED_ROOT; @@ -418,11 +415,22 @@ static BOOL CRYPT_DecodeBasicConstraints(PCCERT_CONTEXT cert, } /* Checks element's basic constraints to see if it can act as a CA, with - * remainingCAs CAs left in this chain. A root certificate is assumed to be - * allowed to be a CA whether or not the basic constraints extension is present, - * whereas an intermediate CA cert is not. This matches the expected usage in - * RFC 3280: a conforming intermediate CA MUST contain the basic constraints - * extension. It also appears to match Microsoft's implementation. + * remainingCAs CAs left in this chain. In general, a cert must include the + * basic constraints extension, with the CA flag asserted, in order to be + * allowed to be a CA. A V1 or V2 cert, which has no extensions, is also + * allowed to be a CA if it's installed locally (in the engine's world store.) + * This matches the expected usage in RFC 5280, section 4.2.1.9: a conforming + * CA MUST include the basic constraints extension in all certificates that are + * used to validate digital signatures on certificates. It also matches + * section 6.1.4(k): "If a certificate is a v1 or v2 certificate, then the + * application MUST either verify that the certificate is a CA certificate + * through out-of-band means or reject the certificate." Rejecting the + * certificate prohibits a large number of commonly used certificates, so + * accepting locally installed ones is a compromise. + * Root certificates are also allowed to be CAs even without a basic + * constraints extension. This is implied by RFC 5280, section 6.1: the + * root of a certificate chain's only requirement is that it was used to issue + * the next certificate in the chain. * Updates chainConstraints with the element's constraints, if: * 1. chainConstraints doesn't have a path length constraint, or * 2. element's path length constraint is smaller than chainConstraints's @@ -431,16 +439,40 @@ static BOOL CRYPT_DecodeBasicConstraints(PCCERT_CONTEXT cert, * Returns TRUE if the element can be a CA, and the length of the remaining * chain is valid. */ -static BOOL CRYPT_CheckBasicConstraintsForCA(PCCERT_CONTEXT cert, - CERT_BASIC_CONSTRAINTS2_INFO *chainConstraints, DWORD remainingCAs, - BOOL isRoot, BOOL *pathLengthConstraintViolated) +static BOOL CRYPT_CheckBasicConstraintsForCA(PCertificateChainEngine engine, + PCCERT_CONTEXT cert, CERT_BASIC_CONSTRAINTS2_INFO *chainConstraints, + DWORD remainingCAs, BOOL isRoot, BOOL *pathLengthConstraintViolated) { - BOOL validBasicConstraints; + BOOL validBasicConstraints, implicitCA = FALSE; CERT_BASIC_CONSTRAINTS2_INFO constraints; - if ((validBasicConstraints = CRYPT_DecodeBasicConstraints(cert, - &constraints, isRoot))) + if (isRoot) + implicitCA = TRUE; + else if (cert->pCertInfo->dwVersion == CERT_V1 || + cert->pCertInfo->dwVersion == CERT_V2) { + BYTE hash[20]; + DWORD size = sizeof(hash); + + if (CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, + hash, &size)) + { + CRYPT_HASH_BLOB blob = { sizeof(hash), hash }; + PCCERT_CONTEXT localCert = CertFindCertificateInStore( + engine->hWorld, cert->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, + &blob, NULL); + + if (localCert) + { + CertFreeCertificateContext(localCert); + implicitCA = TRUE; + } + } + } + if ((validBasicConstraints = CRYPT_DecodeBasicConstraints(cert, + &constraints, implicitCA))) + { + chainConstraints->fCA = constraints.fCA; if (!constraints.fCA) { TRACE_(chain)("chain element %d can't be a CA\n", remainingCAs + 1); @@ -547,9 +579,13 @@ static BOOL ip_address_matches(const CRYPT_DATA_BLOB *constraint, TRACE("(%d, %p), (%d, %p)\n", constraint->cbData, constraint->pbData, name->cbData, name->pbData); - if (constraint->cbData != sizeof(DWORD) * 2) + /* RFC5280, section 4.2.1.10, iPAddress syntax: either 8 or 32 bytes, for + * IPv4 or IPv6 addresses, respectively. + */ + if (constraint->cbData != sizeof(DWORD) * 2 && constraint->cbData != 32) *trustErrorStatus |= CERT_TRUST_INVALID_NAME_CONSTRAINTS; - else if (name->cbData == sizeof(DWORD)) + else if (name->cbData == sizeof(DWORD) && + constraint->cbData == sizeof(DWORD) * 2) { DWORD subnet, mask, addr; @@ -561,6 +597,19 @@ static BOOL ip_address_matches(const CRYPT_DATA_BLOB *constraint, */ match = (subnet & mask) == (addr & mask); } + else if (name->cbData == 16 && constraint->cbData == 32) + { + const BYTE *subnet, *mask, *addr; + DWORD i; + + subnet = constraint->pbData; + mask = constraint->pbData + 16; + addr = name->pbData; + match = TRUE; + for (i = 0; match && i < 16; i++) + if ((subnet[i] & mask[i]) != (addr[i] & mask[i])) + match = FALSE; + } /* else: name is wrong size, no match */ return match; @@ -608,6 +657,18 @@ static void CRYPT_FindMatchingNameEntry(const CERT_ALT_NAME_ENTRY *constraint, *trustErrorStatus |= match ? errorIfFound : errorIfNotFound; } +static inline PCERT_EXTENSION get_subject_alt_name_ext(const CERT_INFO *cert) +{ + PCERT_EXTENSION ext; + + ext = CertFindExtension(szOID_SUBJECT_ALT_NAME2, + cert->cExtension, cert->rgExtension); + if (!ext) + ext = CertFindExtension(szOID_SUBJECT_ALT_NAME, + cert->cExtension, cert->rgExtension); + return ext; +} + static void CRYPT_CheckNameConstraints( const CERT_NAME_CONSTRAINTS_INFO *nameConstraints, const CERT_INFO *cert, DWORD *trustErrorStatus) @@ -615,10 +676,9 @@ static void CRYPT_CheckNameConstraints( /* If there aren't any existing constraints, don't bother checking */ if (nameConstraints->cPermittedSubtree || nameConstraints->cExcludedSubtree) { - CERT_EXTENSION *ext; + CERT_EXTENSION *ext = get_subject_alt_name_ext(cert); - if ((ext = CertFindExtension(szOID_SUBJECT_ALT_NAME, cert->cExtension, - cert->rgExtension))) + if (ext) { CERT_ALT_NAME_INFO *subjectName; DWORD size; @@ -638,15 +698,20 @@ static void CRYPT_CheckNameConstraints( for (i = 0; i < nameConstraints->cPermittedSubtree; i++) CRYPT_FindMatchingNameEntry( &nameConstraints->rgPermittedSubtree[i].Base, subjectName, - trustErrorStatus, - 0, CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT); + trustErrorStatus, 0, + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT); LocalFree(subjectName); } + else + *trustErrorStatus |= + CERT_TRUST_INVALID_EXTENSION | + CERT_TRUST_INVALID_NAME_CONSTRAINTS; } else { if (nameConstraints->cPermittedSubtree) *trustErrorStatus |= + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT; if (nameConstraints->cExcludedSubtree) *trustErrorStatus |= @@ -675,6 +740,40 @@ static CERT_NAME_CONSTRAINTS_INFO *CRYPT_GetNameConstraints(CERT_INFO *cert) return info; } +static BOOL CRYPT_IsValidNameConstraint(const CERT_NAME_CONSTRAINTS_INFO *info) +{ + DWORD i; + BOOL ret = TRUE; + + /* Check that none of the constraints specifies a minimum or a maximum. + * See RFC 5280, section 4.2.1.10: + * "Within this profile, the minimum and maximum fields are not used with + * any name forms, thus, the minimum MUST be zero, and maximum MUST be + * absent. However, if an application encounters a critical name + * constraints extension that specifies other values for minimum or + * maximum for a name form that appears in a subsequent certificate, the + * application MUST either process these fields or reject the + * certificate." + * Since it gives no guidance as to how to process these fields, we + * reject any name constraint that contains them. + */ + for (i = 0; ret && i < info->cPermittedSubtree; i++) + if (info->rgPermittedSubtree[i].dwMinimum || + info->rgPermittedSubtree[i].fMaximum) + { + TRACE_(chain)("found a minimum or maximum in permitted subtrees\n"); + ret = FALSE; + } + for (i = 0; ret && i < info->cExcludedSubtree; i++) + if (info->rgExcludedSubtree[i].dwMinimum || + info->rgExcludedSubtree[i].fMaximum) + { + TRACE_(chain)("found a minimum or maximum in excluded subtrees\n"); + ret = FALSE; + } + return ret; +} + static void CRYPT_CheckChainNameConstraints(PCERT_SIMPLE_CHAIN chain) { int i, j; @@ -698,21 +797,27 @@ static void CRYPT_CheckChainNameConstraints(PCERT_SIMPLE_CHAIN chain) if ((nameConstraints = CRYPT_GetNameConstraints( chain->rgpElement[i]->pCertContext->pCertInfo))) { - for (j = i - 1; j >= 0; j--) + if (!CRYPT_IsValidNameConstraint(nameConstraints)) + chain->rgpElement[i]->TrustStatus.dwErrorStatus |= + CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT; + else { - DWORD errorStatus = 0; - - /* According to RFC 3280, self-signed certs don't have name - * constraints checked unless they're the end cert. - */ - if (j == 0 || !CRYPT_IsCertificateSelfSigned( - chain->rgpElement[j]->pCertContext)) + for (j = i - 1; j >= 0; j--) { - CRYPT_CheckNameConstraints(nameConstraints, - chain->rgpElement[i]->pCertContext->pCertInfo, - &errorStatus); - chain->rgpElement[i]->TrustStatus.dwErrorStatus |= - errorStatus; + DWORD errorStatus = 0; + + /* According to RFC 3280, self-signed certs don't have name + * constraints checked unless they're the end cert. + */ + if (j == 0 || !CRYPT_IsCertificateSelfSigned( + chain->rgpElement[j]->pCertContext)) + { + CRYPT_CheckNameConstraints(nameConstraints, + chain->rgpElement[j]->pCertContext->pCertInfo, + &errorStatus); + chain->rgpElement[i]->TrustStatus.dwErrorStatus |= + errorStatus; + } } } LocalFree(nameConstraints); @@ -720,6 +825,80 @@ static void CRYPT_CheckChainNameConstraints(PCERT_SIMPLE_CHAIN chain) } } +static LPWSTR name_value_to_str(const CERT_NAME_BLOB *name) +{ + DWORD len = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0, name, + CERT_SIMPLE_NAME_STR, NULL, 0); + LPWSTR str = NULL; + + if (len) + { + str = CryptMemAlloc(len * sizeof(WCHAR)); + if (str) + cert_name_to_str_with_indent(X509_ASN_ENCODING, 0, name, + CERT_SIMPLE_NAME_STR, str, len); + } + return str; +} + +static void dump_alt_name_entry(const CERT_ALT_NAME_ENTRY *entry) +{ + LPWSTR str; + + switch (entry->dwAltNameChoice) + { + case CERT_ALT_NAME_OTHER_NAME: + TRACE_(chain)("CERT_ALT_NAME_OTHER_NAME, oid = %s\n", + debugstr_a(entry->u.pOtherName->pszObjId)); + break; + case CERT_ALT_NAME_RFC822_NAME: + TRACE_(chain)("CERT_ALT_NAME_RFC822_NAME: %s\n", + debugstr_w(entry->u.pwszRfc822Name)); + break; + case CERT_ALT_NAME_DNS_NAME: + TRACE_(chain)("CERT_ALT_NAME_DNS_NAME: %s\n", + debugstr_w(entry->u.pwszDNSName)); + break; + case CERT_ALT_NAME_DIRECTORY_NAME: + str = name_value_to_str(&entry->u.DirectoryName); + TRACE_(chain)("CERT_ALT_NAME_DIRECTORY_NAME: %s\n", debugstr_w(str)); + CryptMemFree(str); + break; + case CERT_ALT_NAME_URL: + TRACE_(chain)("CERT_ALT_NAME_URL: %s\n", debugstr_w(entry->u.pwszURL)); + break; + case CERT_ALT_NAME_IP_ADDRESS: + TRACE_(chain)("CERT_ALT_NAME_IP_ADDRESS: %d bytes\n", + entry->u.IPAddress.cbData); + break; + case CERT_ALT_NAME_REGISTERED_ID: + TRACE_(chain)("CERT_ALT_NAME_REGISTERED_ID: %s\n", + debugstr_a(entry->u.pszRegisteredID)); + break; + default: + TRACE_(chain)("dwAltNameChoice = %d\n", entry->dwAltNameChoice); + } +} + +static void dump_alt_name(LPCSTR type, const CERT_EXTENSION *ext) +{ + CERT_ALT_NAME_INFO *name; + DWORD size; + + TRACE_(chain)("%s:\n", type); + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ALTERNATE_NAME, + ext->Value.pbData, ext->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, &name, &size)) + { + DWORD i; + + TRACE_(chain)("%d alt name entries:\n", name->cAltEntry); + for (i = 0; i < name->cAltEntry; i++) + dump_alt_name_entry(&name->rgAltEntry[i]); + LocalFree(name); + } +} + static void dump_basic_constraints(const CERT_EXTENSION *ext) { CERT_BASIC_CONSTRAINTS_INFO *info; @@ -754,14 +933,161 @@ static void dump_basic_constraints2(const CERT_EXTENSION *ext) } } +static void dump_key_usage(const CERT_EXTENSION *ext) +{ + CRYPT_BIT_BLOB usage; + DWORD size = sizeof(usage); + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_BITS, ext->Value.pbData, + ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &usage, &size)) + { +#define trace_usage_bit(bits, bit) \ + if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit) + if (usage.cbData) + { + trace_usage_bit(usage.pbData[0], CERT_DIGITAL_SIGNATURE_KEY_USAGE); + trace_usage_bit(usage.pbData[0], CERT_NON_REPUDIATION_KEY_USAGE); + trace_usage_bit(usage.pbData[0], CERT_KEY_ENCIPHERMENT_KEY_USAGE); + trace_usage_bit(usage.pbData[0], CERT_DATA_ENCIPHERMENT_KEY_USAGE); + trace_usage_bit(usage.pbData[0], CERT_KEY_AGREEMENT_KEY_USAGE); + trace_usage_bit(usage.pbData[0], CERT_KEY_CERT_SIGN_KEY_USAGE); + trace_usage_bit(usage.pbData[0], CERT_CRL_SIGN_KEY_USAGE); + trace_usage_bit(usage.pbData[0], CERT_ENCIPHER_ONLY_KEY_USAGE); + } +#undef trace_usage_bit + if (usage.cbData > 1 && usage.pbData[1] & CERT_DECIPHER_ONLY_KEY_USAGE) + TRACE_(chain)("CERT_DECIPHER_ONLY_KEY_USAGE\n"); + } +} + +static void dump_general_subtree(const CERT_GENERAL_SUBTREE *subtree) +{ + dump_alt_name_entry(&subtree->Base); + TRACE_(chain)("dwMinimum = %d, fMaximum = %d, dwMaximum = %d\n", + subtree->dwMinimum, subtree->fMaximum, subtree->dwMaximum); +} + +static void dump_name_constraints(const CERT_EXTENSION *ext) +{ + CERT_NAME_CONSTRAINTS_INFO *nameConstraints; + DWORD size; + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME_CONSTRAINTS, + ext->Value.pbData, ext->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, &nameConstraints, + &size)) + { + DWORD i; + + TRACE_(chain)("%d permitted subtrees:\n", + nameConstraints->cPermittedSubtree); + for (i = 0; i < nameConstraints->cPermittedSubtree; i++) + dump_general_subtree(&nameConstraints->rgPermittedSubtree[i]); + TRACE_(chain)("%d excluded subtrees:\n", + nameConstraints->cExcludedSubtree); + for (i = 0; i < nameConstraints->cExcludedSubtree; i++) + dump_general_subtree(&nameConstraints->rgExcludedSubtree[i]); + LocalFree(nameConstraints); + } +} + +static void dump_cert_policies(const CERT_EXTENSION *ext) +{ + CERT_POLICIES_INFO *policies; + DWORD size; + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT_POLICIES, + ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, + &policies, &size)) + { + DWORD i, j; + + TRACE_(chain)("%d policies:\n", policies->cPolicyInfo); + for (i = 0; i < policies->cPolicyInfo; i++) + { + TRACE_(chain)("policy identifier: %s\n", + debugstr_a(policies->rgPolicyInfo[i].pszPolicyIdentifier)); + TRACE_(chain)("%d policy qualifiers:\n", + policies->rgPolicyInfo[i].cPolicyQualifier); + for (j = 0; j < policies->rgPolicyInfo[i].cPolicyQualifier; j++) + TRACE_(chain)("%s\n", debugstr_a( + policies->rgPolicyInfo[i].rgPolicyQualifier[j]. + pszPolicyQualifierId)); + } + LocalFree(policies); + } +} + +static void dump_enhanced_key_usage(const CERT_EXTENSION *ext) +{ + CERT_ENHKEY_USAGE *usage; + DWORD size; + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ENHANCED_KEY_USAGE, + ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, + &usage, &size)) + { + DWORD i; + + TRACE_(chain)("%d usages:\n", usage->cUsageIdentifier); + for (i = 0; i < usage->cUsageIdentifier; i++) + TRACE_(chain)("%s\n", usage->rgpszUsageIdentifier[i]); + LocalFree(usage); + } +} + +static void dump_netscape_cert_type(const CERT_EXTENSION *ext) +{ + CRYPT_BIT_BLOB usage; + DWORD size = sizeof(usage); + + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_BITS, ext->Value.pbData, + ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, &usage, &size)) + { +#define trace_cert_type_bit(bits, bit) \ + if ((bits) & (bit)) TRACE_(chain)("%s\n", #bit) + if (usage.cbData) + { + trace_cert_type_bit(usage.pbData[0], + NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE); + trace_cert_type_bit(usage.pbData[0], + NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE); + trace_cert_type_bit(usage.pbData[0], NETSCAPE_SMIME_CERT_TYPE); + trace_cert_type_bit(usage.pbData[0], NETSCAPE_SIGN_CERT_TYPE); + trace_cert_type_bit(usage.pbData[0], NETSCAPE_SSL_CA_CERT_TYPE); + trace_cert_type_bit(usage.pbData[0], NETSCAPE_SMIME_CA_CERT_TYPE); + trace_cert_type_bit(usage.pbData[0], NETSCAPE_SIGN_CA_CERT_TYPE); + } +#undef trace_cert_type_bit + } +} + static void dump_extension(const CERT_EXTENSION *ext) { TRACE_(chain)("%s (%scritical)\n", debugstr_a(ext->pszObjId), ext->fCritical ? "" : "not "); - if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS)) + if (!strcmp(ext->pszObjId, szOID_SUBJECT_ALT_NAME)) + dump_alt_name("subject alt name", ext); + else if (!strcmp(ext->pszObjId, szOID_ISSUER_ALT_NAME)) + dump_alt_name("issuer alt name", ext); + else if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS)) dump_basic_constraints(ext); + else if (!strcmp(ext->pszObjId, szOID_KEY_USAGE)) + dump_key_usage(ext); + else if (!strcmp(ext->pszObjId, szOID_SUBJECT_ALT_NAME2)) + dump_alt_name("subject alt name 2", ext); + else if (!strcmp(ext->pszObjId, szOID_ISSUER_ALT_NAME2)) + dump_alt_name("issuer alt name 2", ext); else if (!strcmp(ext->pszObjId, szOID_BASIC_CONSTRAINTS2)) dump_basic_constraints2(ext); + else if (!strcmp(ext->pszObjId, szOID_NAME_CONSTRAINTS)) + dump_name_constraints(ext); + else if (!strcmp(ext->pszObjId, szOID_CERT_POLICIES)) + dump_cert_policies(ext); + else if (!strcmp(ext->pszObjId, szOID_ENHANCED_KEY_USAGE)) + dump_enhanced_key_usage(ext); + else if (!strcmp(ext->pszObjId, szOID_NETSCAPE_CERT_TYPE)) + dump_netscape_cert_type(ext); } static LPCWSTR filetime_to_str(const FILETIME *time) @@ -785,7 +1111,7 @@ static void dump_element(PCCERT_CONTEXT cert) LPWSTR name = NULL; DWORD len, i; - TRACE_(chain)("%p\n", cert); + TRACE_(chain)("%p: version %d\n", cert, cert->pCertInfo->dwVersion); len = CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0); name = CryptMemAlloc(len * sizeof(WCHAR)); @@ -814,33 +1140,263 @@ static void dump_element(PCCERT_CONTEXT cert) dump_extension(&cert->pCertInfo->rgExtension[i]); } +static BOOL CRYPT_KeyUsageValid(PCertificateChainEngine engine, + PCCERT_CONTEXT cert, BOOL isRoot, BOOL isCA, DWORD index) +{ + PCERT_EXTENSION ext; + BOOL ret; + BYTE usageBits = 0; + + ext = CertFindExtension(szOID_KEY_USAGE, cert->pCertInfo->cExtension, + cert->pCertInfo->rgExtension); + if (ext) + { + CRYPT_BIT_BLOB usage; + DWORD size = sizeof(usage); + + ret = CryptDecodeObjectEx(cert->dwCertEncodingType, X509_BITS, + ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_NOCOPY_FLAG, NULL, + &usage, &size); + if (!ret) + return FALSE; + else if (usage.cbData > 2) + { + /* The key usage extension only defines 9 bits => no more than 2 + * bytes are needed to encode all known usages. + */ + return FALSE; + } + else + { + /* The only bit relevant to chain validation is the keyCertSign + * bit, which is always in the least significant byte of the + * key usage bits. + */ + usageBits = usage.pbData[usage.cbData - 1]; + } + } + if (isCA) + { + if (!ext) + { + /* MS appears to violate RFC 5280, section 4.2.1.3 (Key Usage) + * here. Quoting the RFC: + * "This [key usage] extension MUST appear in certificates that + * contain public keys that are used to validate digital signatures + * on other public key certificates or CRLs." + * MS appears to accept certs that do not contain key usage + * extensions as CA certs. V1 and V2 certificates did not have + * extensions, and many root certificates are V1 certificates, so + * perhaps this is prudent. On the other hand, MS also accepts V3 + * certs without key usage extensions. We are more restrictive: + * we accept locally installed V1 or V2 certs as CA certs. + * We also accept a lack of key usage extension on root certs, + * which is implied in RFC 5280, section 6.1: the trust anchor's + * only requirement is that it was used to issue the next + * certificate in the chain. + */ + if (isRoot) + ret = TRUE; + else if (cert->pCertInfo->dwVersion == CERT_V1 || + cert->pCertInfo->dwVersion == CERT_V2) + { + PCCERT_CONTEXT localCert = CRYPT_FindCertInStore( + engine->hWorld, cert); + + ret = localCert != NULL; + CertFreeCertificateContext(localCert); + } + else + ret = FALSE; + if (!ret) + WARN_(chain)("no key usage extension on a CA cert\n"); + } + else + { + if (!(usageBits & CERT_KEY_CERT_SIGN_KEY_USAGE)) + { + WARN_(chain)("keyCertSign not asserted on a CA cert\n"); + ret = FALSE; + } + else + ret = TRUE; + } + } + else + { + if (ext && (usageBits & CERT_KEY_CERT_SIGN_KEY_USAGE)) + { + WARN_(chain)("keyCertSign asserted on a non-CA cert\n"); + ret = FALSE; + } + else + ret = TRUE; + } + return ret; +} + +static BOOL CRYPT_ExtendedKeyUsageValidForCA(PCCERT_CONTEXT cert) +{ + PCERT_EXTENSION ext; + BOOL ret; + + /* RFC 5280, section 4.2.1.12: "In general, this extension will only + * appear in end entity certificates." And, "If a certificate contains + * both a key usage extension and an extended key usage extension, then + * both extensions MUST be processed independently and the certificate MUST + * only be used for a purpose consistent with both extensions." This seems + * to imply that it should be checked if present, and ignored if not. + * Unfortunately some CAs, e.g. the Thawte SGC CA, don't include the code + * signing extended key usage, whereas they do include the keyCertSign + * key usage. Thus, when checking for a CA, we only require the + * code signing extended key usage if the extended key usage is critical. + */ + ext = CertFindExtension(szOID_ENHANCED_KEY_USAGE, + cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension); + if (ext && ext->fCritical) + { + CERT_ENHKEY_USAGE *usage; + DWORD size; + + ret = CryptDecodeObjectEx(cert->dwCertEncodingType, + X509_ENHANCED_KEY_USAGE, ext->Value.pbData, ext->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG, NULL, &usage, &size); + if (ret) + { + DWORD i; + + /* Explicitly require the code signing extended key usage for a CA + * with an extended key usage extension. That is, don't assume + * a cert is allowed to be a CA if it specifies the + * anyExtendedKeyUsage usage oid. See again RFC 5280, section + * 4.2.1.12: "Applications that require the presence of a + * particular purpose MAY reject certificates that include the + * anyExtendedKeyUsage OID but not the particular OID expected for + * the application." + */ + ret = FALSE; + for (i = 0; !ret && i < usage->cUsageIdentifier; i++) + if (!strcmp(usage->rgpszUsageIdentifier[i], + szOID_PKIX_KP_CODE_SIGNING)) + ret = TRUE; + LocalFree(usage); + } + } + else + ret = TRUE; + return ret; +} + +static BOOL CRYPT_CriticalExtensionsSupported(PCCERT_CONTEXT cert) +{ + BOOL ret = TRUE; + DWORD i; + + for (i = 0; ret && i < cert->pCertInfo->cExtension; i++) + { + if (cert->pCertInfo->rgExtension[i].fCritical) + { + LPCSTR oid = cert->pCertInfo->rgExtension[i].pszObjId; + + if (!strcmp(oid, szOID_BASIC_CONSTRAINTS)) + ret = TRUE; + else if (!strcmp(oid, szOID_BASIC_CONSTRAINTS2)) + ret = TRUE; + else if (!strcmp(oid, szOID_NAME_CONSTRAINTS)) + ret = TRUE; + else if (!strcmp(oid, szOID_KEY_USAGE)) + ret = TRUE; + else if (!strcmp(oid, szOID_SUBJECT_ALT_NAME)) + ret = TRUE; + else if (!strcmp(oid, szOID_SUBJECT_ALT_NAME2)) + ret = TRUE; + else if (!strcmp(oid, szOID_ENHANCED_KEY_USAGE)) + ret = TRUE; + else + { + FIXME("unsupported critical extension %s\n", + debugstr_a(oid)); + ret = FALSE; + } + } + } + return ret; +} + +static BOOL CRYPT_IsCertVersionValid(PCCERT_CONTEXT cert) +{ + BOOL ret = TRUE; + + /* Checks whether the contents of the cert match the cert's version. */ + switch (cert->pCertInfo->dwVersion) + { + case CERT_V1: + /* A V1 cert may not contain unique identifiers. See RFC 5280, + * section 4.1.2.8: + * "These fields MUST only appear if the version is 2 or 3 (Section + * 4.1.2.1). These fields MUST NOT appear if the version is 1." + */ + if (cert->pCertInfo->IssuerUniqueId.cbData || + cert->pCertInfo->SubjectUniqueId.cbData) + ret = FALSE; + /* A V1 cert may not contain extensions. See RFC 5280, section 4.1.2.9: + * "This field MUST only appear if the version is 3 (Section 4.1.2.1)." + */ + if (cert->pCertInfo->cExtension) + ret = FALSE; + break; + case CERT_V2: + /* A V2 cert may not contain extensions. See RFC 5280, section 4.1.2.9: + * "This field MUST only appear if the version is 3 (Section 4.1.2.1)." + */ + if (cert->pCertInfo->cExtension) + ret = FALSE; + break; + case CERT_V3: + /* Do nothing, all fields are allowed for V3 certs */ + break; + default: + WARN_(chain)("invalid cert version %d\n", cert->pCertInfo->dwVersion); + ret = FALSE; + } + return ret; +} + static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine, PCERT_SIMPLE_CHAIN chain, LPFILETIME time) { PCERT_CHAIN_ELEMENT rootElement = chain->rgpElement[chain->cElement - 1]; int i; BOOL pathLengthConstraintViolated = FALSE; - CERT_BASIC_CONSTRAINTS2_INFO constraints = { TRUE, FALSE, 0 }; + CERT_BASIC_CONSTRAINTS2_INFO constraints = { FALSE, FALSE, 0 }; TRACE_(chain)("checking chain with %d elements for time %s\n", chain->cElement, debugstr_w(filetime_to_str(time))); for (i = chain->cElement - 1; i >= 0; i--) { + BOOL isRoot; + if (TRACE_ON(chain)) dump_element(chain->rgpElement[i]->pCertContext); + if (i == chain->cElement - 1) + isRoot = CRYPT_IsCertificateSelfSigned( + chain->rgpElement[i]->pCertContext); + else + isRoot = FALSE; + if (!CRYPT_IsCertVersionValid(chain->rgpElement[i]->pCertContext)) + { + /* MS appears to accept certs whose versions don't match their + * contents, so there isn't an appropriate error code. + */ + chain->rgpElement[i]->TrustStatus.dwErrorStatus |= + CERT_TRUST_INVALID_EXTENSION; + } if (CertVerifyTimeValidity(time, chain->rgpElement[i]->pCertContext->pCertInfo) != 0) chain->rgpElement[i]->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_NOT_TIME_VALID; if (i != 0) { - BOOL isRoot; - - if (i == chain->cElement - 1) - isRoot = CRYPT_IsCertificateSelfSigned( - chain->rgpElement[i]->pCertContext); - else - isRoot = FALSE; /* Check the signature of the cert this issued */ if (!CryptVerifyCertificateSignatureEx(0, X509_ASN_ENCODING, CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT, @@ -855,9 +1411,9 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine, if (pathLengthConstraintViolated) chain->rgpElement[i]->TrustStatus.dwErrorStatus |= CERT_TRUST_INVALID_BASIC_CONSTRAINTS; - else if (!CRYPT_CheckBasicConstraintsForCA( - chain->rgpElement[i]->pCertContext, &constraints, i - 1, - isRoot, &pathLengthConstraintViolated)) + else if (!CRYPT_CheckBasicConstraintsForCA(engine, + chain->rgpElement[i]->pCertContext, &constraints, i - 1, isRoot, + &pathLengthConstraintViolated)) chain->rgpElement[i]->TrustStatus.dwErrorStatus |= CERT_TRUST_INVALID_BASIC_CONSTRAINTS; else if (constraints.fPathLenConstraint && @@ -867,6 +1423,23 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine, constraints.dwPathLenConstraint--; } } + else + { + /* Check whether end cert has a basic constraints extension */ + if (!CRYPT_DecodeBasicConstraints( + chain->rgpElement[i]->pCertContext, &constraints, FALSE)) + chain->rgpElement[i]->TrustStatus.dwErrorStatus |= + CERT_TRUST_INVALID_BASIC_CONSTRAINTS; + } + if (!CRYPT_KeyUsageValid(engine, chain->rgpElement[i]->pCertContext, + isRoot, constraints.fCA, i)) + chain->rgpElement[i]->TrustStatus.dwErrorStatus |= + CERT_TRUST_IS_NOT_VALID_FOR_USAGE; + if (i != 0) + if (!CRYPT_ExtendedKeyUsageValidForCA( + chain->rgpElement[i]->pCertContext)) + chain->rgpElement[i]->TrustStatus.dwErrorStatus |= + CERT_TRUST_IS_NOT_VALID_FOR_USAGE; if (CRYPT_IsSimpleChainCyclic(chain)) { /* If the chain is cyclic, then the path length constraints @@ -877,7 +1450,11 @@ static void CRYPT_CheckSimpleChain(PCertificateChainEngine engine, CERT_TRUST_IS_PARTIAL_CHAIN | CERT_TRUST_INVALID_BASIC_CONSTRAINTS; } - /* FIXME: check valid usages */ + /* Check whether every critical extension is supported */ + if (!CRYPT_CriticalExtensionsSupported( + chain->rgpElement[i]->pCertContext)) + chain->rgpElement[i]->TrustStatus.dwErrorStatus |= + CERT_TRUST_INVALID_EXTENSION; CRYPT_CombineTrustStatus(&chain->TrustStatus, &chain->rgpElement[i]->TrustStatus); } @@ -1333,14 +1910,16 @@ static PCertificateChain CRYPT_BuildAlternateContextFromChain( return alternate; } -#define CHAIN_QUALITY_SIGNATURE_VALID 8 -#define CHAIN_QUALITY_TIME_VALID 4 -#define CHAIN_QUALITY_COMPLETE_CHAIN 2 -#define CHAIN_QUALITY_TRUSTED_ROOT 1 +#define CHAIN_QUALITY_SIGNATURE_VALID 0x16 +#define CHAIN_QUALITY_TIME_VALID 8 +#define CHAIN_QUALITY_COMPLETE_CHAIN 4 +#define CHAIN_QUALITY_BASIC_CONSTRAINTS 2 +#define CHAIN_QUALITY_TRUSTED_ROOT 1 #define CHAIN_QUALITY_HIGHEST \ CHAIN_QUALITY_SIGNATURE_VALID | CHAIN_QUALITY_TIME_VALID | \ - CHAIN_QUALITY_COMPLETE_CHAIN | CHAIN_QUALITY_TRUSTED_ROOT + CHAIN_QUALITY_COMPLETE_CHAIN | CHAIN_QUALITY_BASIC_CONSTRAINTS | \ + CHAIN_QUALITY_TRUSTED_ROOT #define IS_TRUST_ERROR_SET(TrustStatus, bits) \ (TrustStatus)->dwErrorStatus & (bits) @@ -1352,9 +1931,11 @@ static DWORD CRYPT_ChainQuality(const CertificateChain *chain) if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus, CERT_TRUST_IS_UNTRUSTED_ROOT)) quality &= ~CHAIN_QUALITY_TRUSTED_ROOT; + if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus, + CERT_TRUST_INVALID_BASIC_CONSTRAINTS)) + quality &= ~CHAIN_QUALITY_BASIC_CONSTRAINTS; if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus, CERT_TRUST_IS_PARTIAL_CHAIN)) - if (chain->context.TrustStatus.dwErrorStatus & CERT_TRUST_IS_PARTIAL_CHAIN) quality &= ~CHAIN_QUALITY_COMPLETE_CHAIN; if (IS_TRUST_ERROR_SET(&chain->context.TrustStatus, CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_NOT_TIME_NESTED)) @@ -1544,6 +2125,31 @@ static void CRYPT_VerifyChainRevocation(PCERT_CHAIN_CONTEXT chain, } } +static void dump_usage_match(LPCSTR name, const CERT_USAGE_MATCH *usageMatch) +{ + DWORD i; + + TRACE_(chain)("%s: %s\n", name, + usageMatch->dwType == USAGE_MATCH_TYPE_AND ? "AND" : "OR"); + for (i = 0; i < usageMatch->Usage.cUsageIdentifier; i++) + TRACE_(chain)("%s\n", usageMatch->Usage.rgpszUsageIdentifier[i]); +} + +static void dump_chain_para(const CERT_CHAIN_PARA *pChainPara) +{ + TRACE_(chain)("%d\n", pChainPara->cbSize); + if (pChainPara->cbSize >= sizeof(CERT_CHAIN_PARA_NO_EXTRA_FIELDS)) + dump_usage_match("RequestedUsage", &pChainPara->RequestedUsage); + if (pChainPara->cbSize >= sizeof(CERT_CHAIN_PARA)) + { + dump_usage_match("RequestedIssuancePolicy", + &pChainPara->RequestedIssuancePolicy); + TRACE_(chain)("%d\n", pChainPara->dwUrlRetrievalTimeout); + TRACE_(chain)("%d\n", pChainPara->fCheckRevocationFreshnessTime); + TRACE_(chain)("%d\n", pChainPara->dwRevocationFreshnessTime); + } +} + BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, PCCERT_CONTEXT pCertContext, LPFILETIME pTime, HCERTSTORE hAdditionalStore, PCERT_CHAIN_PARA pChainPara, DWORD dwFlags, LPVOID pvReserved, @@ -1570,6 +2176,8 @@ BOOL WINAPI CertGetCertificateChain(HCERTCHAINENGINE hChainEngine, if (!hChainEngine) hChainEngine = CRYPT_GetDefaultChainEngine(); + if (TRACE_ON(chain)) + dump_chain_para(pChainPara); /* FIXME: what about HCCE_LOCAL_MACHINE? */ ret = CRYPT_BuildCandidateChainFromCert(hChainEngine, pCertContext, pTime, hAdditionalStore, &chain); @@ -1746,6 +2354,348 @@ static BOOL WINAPI verify_basic_constraints_policy(LPCSTR szPolicyOID, return TRUE; } +static BOOL match_dns_to_subject_alt_name(PCERT_EXTENSION ext, + LPCWSTR server_name) +{ + BOOL matches = FALSE; + CERT_ALT_NAME_INFO *subjectName; + DWORD size; + + TRACE_(chain)("%s\n", debugstr_w(server_name)); + /* This could be spoofed by the embedded NULL vulnerability, since the + * returned CERT_ALT_NAME_INFO doesn't have a way to indicate the + * encoded length of a name. Fortunately CryptDecodeObjectEx fails if + * the encoded form of the name contains a NULL. + */ + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ALTERNATE_NAME, + ext->Value.pbData, ext->Value.cbData, + CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, + &subjectName, &size)) + { + DWORD i; + + /* RFC 5280 states that multiple instances of each name type may exist, + * in section 4.2.1.6: + * "Multiple name forms, and multiple instances of each name form, + * MAY be included." + * It doesn't specify the behavior in such cases, but common usage is + * to accept a certificate if any name matches. + */ + for (i = 0; !matches && i < subjectName->cAltEntry; i++) + { + if (subjectName->rgAltEntry[i].dwAltNameChoice == + CERT_ALT_NAME_DNS_NAME) + { + TRACE_(chain)("dNSName: %s\n", debugstr_w( + subjectName->rgAltEntry[i].u.pwszDNSName)); + if (!strcmpiW(server_name, + subjectName->rgAltEntry[i].u.pwszDNSName)) + matches = TRUE; + } + } + LocalFree(subjectName); + } + return matches; +} + +static BOOL find_matching_domain_component(CERT_NAME_INFO *name, + LPCWSTR component) +{ + BOOL matches = FALSE; + DWORD i, j; + + for (i = 0; !matches && i < name->cRDN; i++) + for (j = 0; j < name->rgRDN[i].cRDNAttr; j++) + if (!strcmp(szOID_DOMAIN_COMPONENT, + name->rgRDN[i].rgRDNAttr[j].pszObjId)) + { + PCERT_RDN_ATTR attr; + + attr = &name->rgRDN[i].rgRDNAttr[j]; + /* Compare with memicmpW rather than strcmpiW in order to avoid + * a match with a string with an embedded NULL. The component + * must match one domain component attribute's entire string + * value with a case-insensitive match. + */ + matches = !memicmpW(component, (LPWSTR)attr->Value.pbData, + attr->Value.cbData / sizeof(WCHAR)); + } + return matches; +} + +static BOOL match_domain_component(LPCWSTR allowed_component, DWORD allowed_len, + LPCWSTR server_component, DWORD server_len, BOOL allow_wildcards, + BOOL *see_wildcard) +{ + LPCWSTR allowed_ptr, server_ptr; + BOOL matches = TRUE; + + *see_wildcard = FALSE; + if (server_len < allowed_len) + { + WARN_(chain)("domain component %s too short for %s\n", + debugstr_wn(server_component, server_len), + debugstr_wn(allowed_component, allowed_len)); + /* A domain component can't contain a wildcard character, so a domain + * component shorter than the allowed string can't produce a match. + */ + return FALSE; + } + for (allowed_ptr = allowed_component, server_ptr = server_component; + matches && allowed_ptr - allowed_component < allowed_len; + allowed_ptr++, server_ptr++) + { + if (*allowed_ptr == '*') + { + if (allowed_ptr - allowed_component < allowed_len - 1) + { + WARN_(chain)("non-wildcard characters after wildcard not supported\n"); + matches = FALSE; + } + else if (!allow_wildcards) + { + WARN_(chain)("wildcard after non-wildcard component\n"); + matches = FALSE; + } + else + { + /* the preceding characters must have matched, so the rest of + * the component also matches. + */ + *see_wildcard = TRUE; + break; + } + } + matches = tolowerW(*allowed_ptr) == tolowerW(*server_ptr); + } + if (matches && server_ptr - server_component < server_len) + { + /* If there are unmatched characters in the server domain component, + * the server domain only matches if the allowed string ended in a '*'. + */ + matches = *allowed_ptr == '*'; + } + return matches; +} + +static BOOL match_common_name(LPCWSTR server_name, PCERT_RDN_ATTR nameAttr) +{ + LPCWSTR allowed = (LPCWSTR)nameAttr->Value.pbData; + LPCWSTR allowed_component = allowed; + DWORD allowed_len = nameAttr->Value.cbData / sizeof(WCHAR); + LPCWSTR server_component = server_name; + DWORD server_len = strlenW(server_name); + BOOL matches = TRUE, allow_wildcards = TRUE; + + TRACE_(chain)("CN = %s\n", debugstr_wn(allowed_component, allowed_len)); + + /* From RFC 2818 (HTTP over TLS), section 3.1: + * "Names may contain the wildcard character * which is considered to match + * any single domain name component or component fragment. E.g., + * *.a.com matches foo.a.com but not bar.foo.a.com. f*.com matches foo.com + * but not bar.com." + * + * And from RFC 2595 (Using TLS with IMAP, POP3 and ACAP), section 2.4: + * "A "*" wildcard character MAY be used as the left-most name component in + * the certificate. For example, *.example.com would match a.example.com, + * foo.example.com, etc. but would not match example.com." + * + * There are other protocols which use TLS, and none of them is + * authoritative. This accepts certificates in common usage, e.g. + * *.domain.com matches www.domain.com but not domain.com, and + * www*.domain.com matches www1.domain.com but not mail.domain.com. + */ + do { + LPCWSTR allowed_dot, server_dot; + + allowed_dot = memchrW(allowed_component, '.', + allowed_len - (allowed_component - allowed)); + server_dot = memchrW(server_component, '.', + server_len - (server_component - server_name)); + /* The number of components must match */ + if ((!allowed_dot && server_dot) || (allowed_dot && !server_dot)) + { + if (!allowed_dot) + WARN_(chain)("%s: too many components for CN=%s\n", + debugstr_w(server_name), debugstr_wn(allowed, allowed_len)); + else + WARN_(chain)("%s: not enough components for CN=%s\n", + debugstr_w(server_name), debugstr_wn(allowed, allowed_len)); + matches = FALSE; + } + else + { + LPCWSTR allowed_end, server_end; + BOOL has_wildcard; + + allowed_end = allowed_dot ? allowed_dot : allowed + allowed_len; + server_end = server_dot ? server_dot : server_name + server_len; + matches = match_domain_component(allowed_component, + allowed_end - allowed_component, server_component, + server_end - server_component, allow_wildcards, &has_wildcard); + /* Once a non-wildcard component is seen, no wildcard components + * may follow + */ + if (!has_wildcard) + allow_wildcards = FALSE; + if (matches) + { + allowed_component = allowed_dot ? allowed_dot + 1 : allowed_end; + server_component = server_dot ? server_dot + 1 : server_end; + } + } + } while (matches && allowed_component && + allowed_component - allowed < allowed_len && + server_component && server_component - server_name < server_len); + TRACE_(chain)("returning %d\n", matches); + return matches; +} + +static BOOL match_dns_to_subject_dn(PCCERT_CONTEXT cert, LPCWSTR server_name) +{ + BOOL matches = FALSE; + CERT_NAME_INFO *name; + DWORD size; + + TRACE_(chain)("%s\n", debugstr_w(server_name)); + if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_UNICODE_NAME, + cert->pCertInfo->Subject.pbData, cert->pCertInfo->Subject.cbData, + CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, + &name, &size)) + { + /* If the subject distinguished name contains any name components, + * make sure all of them are present. + */ + if (CertFindRDNAttr(szOID_DOMAIN_COMPONENT, name)) + { + LPCWSTR ptr = server_name; + + matches = TRUE; + do { + LPCWSTR dot = strchrW(ptr, '.'), end; + /* 254 is the maximum DNS label length, see RFC 1035 */ + WCHAR component[255]; + DWORD len; + + end = dot ? dot : ptr + strlenW(ptr); + len = end - ptr; + if (len >= sizeof(component) / sizeof(component[0])) + { + WARN_(chain)("domain component %s too long\n", + debugstr_wn(ptr, len)); + matches = FALSE; + } + else + { + memcpy(component, ptr, len * sizeof(WCHAR)); + component[len] = 0; + matches = find_matching_domain_component(name, component); + } + ptr = dot ? dot + 1 : end; + } while (matches && ptr && *ptr); + } + else + { + PCERT_RDN_ATTR attr; + + /* If the certificate isn't using a DN attribute in the name, make + * make sure the common name matches. + */ + if ((attr = CertFindRDNAttr(szOID_COMMON_NAME, name))) + matches = match_common_name(server_name, attr); + } + LocalFree(name); + } + return matches; +} + +static BOOL WINAPI verify_ssl_policy(LPCSTR szPolicyOID, + PCCERT_CHAIN_CONTEXT pChainContext, PCERT_CHAIN_POLICY_PARA pPolicyPara, + PCERT_CHAIN_POLICY_STATUS pPolicyStatus) +{ + pPolicyStatus->lChainIndex = pPolicyStatus->lElementIndex = -1; + if (pChainContext->TrustStatus.dwErrorStatus & + CERT_TRUST_IS_NOT_SIGNATURE_VALID) + { + pPolicyStatus->dwError = TRUST_E_CERT_SIGNATURE; + find_element_with_error(pChainContext, + CERT_TRUST_IS_NOT_SIGNATURE_VALID, &pPolicyStatus->lChainIndex, + &pPolicyStatus->lElementIndex); + } + else if (pChainContext->TrustStatus.dwErrorStatus & + CERT_TRUST_IS_UNTRUSTED_ROOT) + { + pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT; + find_element_with_error(pChainContext, + CERT_TRUST_IS_UNTRUSTED_ROOT, &pPolicyStatus->lChainIndex, + &pPolicyStatus->lElementIndex); + } + else if (pChainContext->TrustStatus.dwErrorStatus & CERT_TRUST_IS_CYCLIC) + { + pPolicyStatus->dwError = CERT_E_UNTRUSTEDROOT; + find_element_with_error(pChainContext, + CERT_TRUST_IS_CYCLIC, &pPolicyStatus->lChainIndex, + &pPolicyStatus->lElementIndex); + /* For a cyclic chain, which element is a cycle isn't meaningful */ + pPolicyStatus->lElementIndex = -1; + } + else if (pChainContext->TrustStatus.dwErrorStatus & + CERT_TRUST_IS_NOT_TIME_VALID) + { + pPolicyStatus->dwError = CERT_E_EXPIRED; + find_element_with_error(pChainContext, + CERT_TRUST_IS_NOT_TIME_VALID, &pPolicyStatus->lChainIndex, + &pPolicyStatus->lElementIndex); + } + else + pPolicyStatus->dwError = NO_ERROR; + /* We only need bother checking whether the name in the end certificate + * matches if the chain is otherwise okay. + */ + if (!pPolicyStatus->dwError && pPolicyPara && + pPolicyPara->cbSize >= sizeof(CERT_CHAIN_POLICY_PARA)) + { + HTTPSPolicyCallbackData *sslPara = pPolicyPara->pvExtraPolicyPara; + + if (sslPara && sslPara->u.cbSize >= sizeof(HTTPSPolicyCallbackData)) + { + if (sslPara->dwAuthType == AUTHTYPE_SERVER && + sslPara->pwszServerName) + { + PCCERT_CONTEXT cert; + PCERT_EXTENSION altNameExt; + BOOL matches; + + cert = pChainContext->rgpChain[0]->rgpElement[0]->pCertContext; + altNameExt = get_subject_alt_name_ext(cert->pCertInfo); + /* If the alternate name extension exists, the name it contains + * is bound to the certificate, so make sure the name matches + * it. Otherwise, look for the server name in the subject + * distinguished name. RFC5280, section 4.2.1.6: + * "Whenever such identities are to be bound into a + * certificate, the subject alternative name (or issuer + * alternative name) extension MUST be used; however, a DNS + * name MAY also be represented in the subject field using the + * domainComponent attribute." + */ + if (altNameExt) + matches = match_dns_to_subject_alt_name(altNameExt, + sslPara->pwszServerName); + else + matches = match_dns_to_subject_dn(cert, + sslPara->pwszServerName); + if (!matches) + { + pPolicyStatus->dwError = CERT_E_CN_NO_MATCH; + pPolicyStatus->lChainIndex = 0; + pPolicyStatus->lElementIndex = 0; + } + } + } + } + return TRUE; +} + static BYTE msPubKey1[] = { 0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xdf,0x08,0xba,0xe3,0x3f,0x6e, 0x64,0x9b,0xf5,0x89,0xaf,0x28,0x96,0x4a,0x07,0x8f,0x1b,0x2e,0x8b,0x3e,0x1d, @@ -1886,6 +2836,9 @@ BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, case LOWORD(CERT_CHAIN_POLICY_AUTHENTICODE): verifyPolicy = verify_authenticode_policy; break; + case LOWORD(CERT_CHAIN_POLICY_SSL): + verifyPolicy = verify_ssl_policy; + break; case LOWORD(CERT_CHAIN_POLICY_BASIC_CONSTRAINTS): verifyPolicy = verify_basic_constraints_policy; break; @@ -1909,5 +2862,6 @@ BOOL WINAPI CertVerifyCertificateChainPolicy(LPCSTR szPolicyOID, pPolicyStatus); if (hFunc) CryptFreeOIDFunctionAddress(hFunc, 0); + TRACE("returning %d (%08x)\n", ret, pPolicyStatus->dwError); return ret; } diff --git a/reactos/dll/win32/crypt32/collectionstore.c b/reactos/dll/win32/crypt32/collectionstore.c index 12eb7c3f7aa..35941dd7317 100644 --- a/reactos/dll/win32/crypt32/collectionstore.c +++ b/reactos/dll/win32/crypt32/collectionstore.c @@ -255,11 +255,19 @@ static BOOL CRYPT_CollectionDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext) { BOOL ret; + PCCERT_CONTEXT linked; TRACE("(%p, %p)\n", store, pCertContext); - ret = CertDeleteCertificateFromStore( - Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT))); + /* Deleting the linked context results in its ref count getting + * decreased, but the caller of this (CertDeleteCertificateFromStore) also + * decreases pCertContext's ref count, by calling + * CertFreeCertificateContext. Increase ref count of linked context to + * compensate. + */ + linked = Context_GetLinkedContext(pCertContext, sizeof(CERT_CONTEXT)); + CertDuplicateCertificateContext(linked); + ret = CertDeleteCertificateFromStore(linked); return ret; } @@ -333,11 +341,18 @@ static BOOL CRYPT_CollectionDeleteCRL(PWINECRYPT_CERTSTORE store, void *pCrlContext) { BOOL ret; + PCCRL_CONTEXT linked; TRACE("(%p, %p)\n", store, pCrlContext); - ret = CertDeleteCRLFromStore( - Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT))); + /* Deleting the linked context results in its ref count getting + * decreased, but the caller of this (CertDeleteCRLFromStore) also + * decreases pCrlContext's ref count, by calling CertFreeCRLContext. + * Increase ref count of linked context to compensate. + */ + linked = Context_GetLinkedContext(pCrlContext, sizeof(CRL_CONTEXT)); + CertDuplicateCRLContext(linked); + ret = CertDeleteCRLFromStore(linked); return ret; } @@ -411,11 +426,57 @@ static BOOL CRYPT_CollectionDeleteCTL(PWINECRYPT_CERTSTORE store, void *pCtlContext) { BOOL ret; + PCCTL_CONTEXT linked; TRACE("(%p, %p)\n", store, pCtlContext); - ret = CertDeleteCTLFromStore( - Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT))); + /* Deleting the linked context results in its ref count getting + * decreased, but the caller of this (CertDeleteCTLFromStore) also + * decreases pCtlContext's ref count, by calling CertFreeCTLContext. + * Increase ref count of linked context to compensate. + */ + linked = Context_GetLinkedContext(pCtlContext, sizeof(CTL_CONTEXT)); + CertDuplicateCTLContext(linked); + ret = CertDeleteCTLFromStore(linked); + return ret; +} + +static BOOL WINAPI CRYPT_CollectionControl(HCERTSTORE hCertStore, DWORD dwFlags, + DWORD dwCtrlType, void const *pvCtrlPara) +{ + BOOL ret; + PWINE_COLLECTIONSTORE store = hCertStore; + PWINE_STORE_LIST_ENTRY entry; + + TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, + pvCtrlPara); + + if (!store) + return TRUE; + if (store->hdr.dwMagic != WINE_CRYPTCERTSTORE_MAGIC) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + if (store->hdr.type != StoreTypeCollection) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + + ret = TRUE; + EnterCriticalSection(&store->cs); + LIST_FOR_EACH_ENTRY(entry, &store->stores, WINE_STORE_LIST_ENTRY, entry) + { + if (entry->store->control) + { + ret = entry->store->control(entry->store, dwFlags, dwCtrlType, + pvCtrlPara); + if (!ret) + break; + } + } + LeaveCriticalSection(&store->cs); return ret; } @@ -446,6 +507,7 @@ PWINECRYPT_CERTSTORE CRYPT_CollectionOpenStore(HCRYPTPROV hCryptProv, store->hdr.ctls.addContext = CRYPT_CollectionAddCTL; store->hdr.ctls.enumContext = CRYPT_CollectionEnumCTL; store->hdr.ctls.deleteContext = CRYPT_CollectionDeleteCTL; + store->hdr.control = CRYPT_CollectionControl; InitializeCriticalSection(&store->cs); store->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PWINE_COLLECTIONSTORE->cs"); list_init(&store->stores); diff --git a/reactos/dll/win32/crypt32/context.c b/reactos/dll/win32/crypt32/context.c index bb877995a1d..bf4ccf3cac1 100644 --- a/reactos/dll/win32/crypt32/context.c +++ b/reactos/dll/win32/crypt32/context.c @@ -24,7 +24,7 @@ #include "wine/list.h" #include "crypt32_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(crypt); +WINE_DEFAULT_DEBUG_CHANNEL(context); typedef enum _ContextType { ContextTypeData, @@ -94,7 +94,7 @@ void *Context_CreateLinkContext(unsigned int contextSize, void *linked, unsigned linkContext->type = ContextTypeLink; linkContext->linked = linkedBase; if (addRef) - InterlockedIncrement(&linkedBase->ref); + Context_AddRef(linked, contextSize); TRACE("%p's ref count is %d\n", context, linkContext->ref); } TRACE("returning %p\n", context); @@ -106,6 +106,37 @@ void Context_AddRef(void *context, size_t contextSize) PBASE_CONTEXT baseContext = BASE_CONTEXT_FROM_CONTEXT(context, contextSize); InterlockedIncrement(&baseContext->ref); + TRACE("%p's ref count is %d\n", context, baseContext->ref); + if (baseContext->type == ContextTypeLink) + { + void *linkedContext = Context_GetLinkedContext(context, contextSize); + PBASE_CONTEXT linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext, + contextSize); + + /* Add-ref the linked contexts too */ + while (linkedContext && linkedBase->type == ContextTypeLink) + { + InterlockedIncrement(&linkedBase->ref); + TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref); + linkedContext = Context_GetLinkedContext(linkedContext, + contextSize); + if (linkedContext) + linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext, + contextSize); + else + linkedBase = NULL; + } + if (linkedContext) + { + /* It's not a link context, so it wasn't add-ref'ed in the while + * loop, so add-ref it here. + */ + linkedBase = BASE_CONTEXT_FROM_CONTEXT(linkedContext, + contextSize); + InterlockedIncrement(&linkedBase->ref); + TRACE("%p's ref count is %d\n", linkedContext, linkedBase->ref); + } + } } void *Context_GetExtra(const void *context, size_t contextSize) @@ -135,35 +166,39 @@ PCONTEXT_PROPERTY_LIST Context_GetProperties(const void *context, size_t context ((PDATA_CONTEXT)ptr)->properties : NULL; } -void Context_Release(void *context, size_t contextSize, +BOOL Context_Release(void *context, size_t contextSize, ContextFreeFunc dataContextFree) { PBASE_CONTEXT base = BASE_CONTEXT_FROM_CONTEXT(context, contextSize); + BOOL ret = TRUE; + if (base->ref <= 0) + { + ERR("%p's ref count is %d\n", context, base->ref); + return FALSE; + } + if (base->type == ContextTypeLink) + { + /* The linked context is of the same type as this, so release + * it as well, using the same offset and data free function. + */ + ret = Context_Release(CONTEXT_FROM_BASE_CONTEXT( + ((PLINK_CONTEXT)base)->linked, contextSize), contextSize, + dataContextFree); + } if (InterlockedDecrement(&base->ref) == 0) { TRACE("freeing %p\n", context); - switch (base->type) + if (base->type == ContextTypeData) { - case ContextTypeData: ContextPropertyList_Free(((PDATA_CONTEXT)base)->properties); dataContextFree(context); - break; - case ContextTypeLink: - /* The linked context is of the same type as this, so release - * it as well, using the same offset and data free function. - */ - Context_Release(CONTEXT_FROM_BASE_CONTEXT( - ((PLINK_CONTEXT)base)->linked, contextSize), contextSize, - dataContextFree); - break; - default: - assert(0); } CryptMemFree(context); } else TRACE("%p's ref count is %d\n", context, base->ref); + return ret; } void Context_CopyProperties(const void *to, const void *from, @@ -278,14 +313,21 @@ void *ContextList_Enum(struct ContextList *list, void *pPrev) return ret; } -void ContextList_Delete(struct ContextList *list, void *context) +BOOL ContextList_Remove(struct ContextList *list, void *context) { struct list *entry = ContextList_ContextToEntry(list, context); + BOOL inList = FALSE; EnterCriticalSection(&list->cs); - list_remove(entry); + if (!list_empty(entry)) + { + list_remove(entry); + inList = TRUE; + } LeaveCriticalSection(&list->cs); - list->contextInterface->free(context); + if (inList) + list_init(entry); + return inList; } static void ContextList_Empty(struct ContextList *list) diff --git a/reactos/dll/win32/crypt32/crl.c b/reactos/dll/win32/crypt32/crl.c index 271e4e0c1b4..522aadf616e 100644 --- a/reactos/dll/win32/crypt32/crl.c +++ b/reactos/dll/win32/crypt32/crl.c @@ -228,7 +228,8 @@ PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore, PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext) { TRACE("(%p)\n", pCrlContext); - Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT)); + if (pCrlContext) + Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT)); return pCrlContext; } @@ -242,12 +243,14 @@ static void CrlDataContext_Free(void *context) BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext) { + BOOL ret = TRUE; + TRACE("(%p)\n", pCrlContext); if (pCrlContext) - Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT), + ret = Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT), CrlDataContext_Free); - return TRUE; + return ret; } DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext, diff --git a/reactos/dll/win32/crypt32/crypt32.spec b/reactos/dll/win32/crypt32/crypt32.spec index 534bee7319f..b096c090c11 100644 --- a/reactos/dll/win32/crypt32/crypt32.spec +++ b/reactos/dll/win32/crypt32/crypt32.spec @@ -1,11 +1,12 @@ -@ stdcall CertAddCRLContextToStore(long ptr long ptr) -@ stdcall CertAddCTLContextToStore(long ptr long ptr) -@ stdcall CertAddCertificateContextToStore(long ptr long ptr) -@ stdcall CertAddEncodedCRLToStore(long long ptr long long ptr) -@ stdcall CertAddEncodedCTLToStore(long long ptr long long ptr) -@ stdcall CertAddEncodedCertificateToStore(long long ptr long long ptr) -@ stub CertAddEncodedCertificateToSystemStoreA -@ stub CertAddEncodedCertificateToSystemStoreW +@ stdcall CertAddCRLContextToStore(ptr ptr long ptr) +@ stdcall CertAddCTLContextToStore(ptr ptr long ptr) +@ stdcall CertAddCertificateContextToStore(ptr ptr long ptr) +@ stdcall CertAddCertificateLinkToStore(ptr ptr long ptr) +@ stdcall CertAddEncodedCRLToStore(ptr long ptr long long ptr) +@ stdcall CertAddEncodedCTLToStore(ptr long ptr long long ptr) +@ stdcall CertAddEncodedCertificateToStore(ptr long ptr long long ptr) +@ stdcall CertAddEncodedCertificateToSystemStoreA(str ptr long) +@ stdcall CertAddEncodedCertificateToSystemStoreW(wstr ptr long) @ stdcall CertAddEnhancedKeyUsageIdentifier(ptr str) @ stdcall CertAddSerializedElementToStore(ptr ptr long long long long ptr ptr) @ stdcall CertAddStoreToCollection(ptr ptr long long) @@ -15,7 +16,7 @@ @ stdcall CertCompareCertificateName(long ptr ptr) @ stdcall CertCompareIntegerBlob(ptr ptr) @ stdcall CertComparePublicKeyInfo(long ptr ptr) -@ stdcall CertControlStore(long long long ptr) +@ stdcall CertControlStore(ptr long long ptr) @ stdcall CertCreateCRLContext(long ptr long) @ stdcall CertCreateCTLContext(long ptr long) @ stdcall CertCreateCertificateChainEngine(ptr ptr) @@ -35,13 +36,13 @@ @ stdcall CertEnumCTLContextProperties(ptr long) @ stdcall CertEnumCTLsInStore(ptr ptr) @ stdcall CertEnumCertificateContextProperties(ptr long) -@ stdcall CertEnumCertificatesInStore(long ptr) +@ stdcall CertEnumCertificatesInStore(ptr ptr) @ stdcall CertEnumPhysicalStore(ptr long ptr ptr) @ stdcall CertEnumSystemStore(long ptr ptr ptr) @ stdcall CertFindAttribute(str long ptr) -@ stdcall CertFindCRLInStore(long long long long ptr ptr) -@ stdcall CertFindCTLInStore(long long long long ptr ptr) -@ stdcall CertFindCertificateInStore(long long long long ptr ptr) +@ stdcall CertFindCRLInStore(ptr long long long ptr ptr) +@ stdcall CertFindCTLInStore(ptr long long long ptr ptr) +@ stdcall CertFindCertificateInStore(ptr long long long ptr ptr) @ stdcall CertFindCertificateInCRL(ptr ptr long ptr ptr) @ stdcall CertFindExtension(str long ptr) @ stdcall CertFindRDNAttr(str ptr) @@ -57,12 +58,12 @@ @ stdcall CertGetCertificateChain(ptr ptr ptr ptr ptr long ptr ptr) @ stdcall CertGetCertificateContextProperty(ptr long ptr ptr) @ stdcall CertGetEnhancedKeyUsage(ptr long ptr ptr) -@ stub CertGetIntendedKeyUsage -@ stdcall CertGetIssuerCertificateFromStore(long ptr ptr ptr) +@ stdcall CertGetIntendedKeyUsage(long ptr ptr long) +@ stdcall CertGetIssuerCertificateFromStore(ptr ptr ptr ptr) @ stdcall CertGetNameStringA(ptr long long ptr ptr long) @ stdcall CertGetNameStringW(ptr long long ptr ptr long) @ stdcall CertGetPublicKeyLength(long ptr) -@ stdcall CertGetStoreProperty(long long ptr ptr) +@ stdcall CertGetStoreProperty(ptr long ptr ptr) @ stdcall CertGetSubjectCertificateFromStore(ptr long ptr) @ stdcall CertGetValidUsages(long ptr ptr ptr ptr) @ stub CertIsRDNAttrsInCertificateName @@ -76,8 +77,8 @@ @ stdcall CertRDNValueToStrA(long ptr ptr long) @ stdcall CertRDNValueToStrW(long ptr ptr long) @ stdcall CertRemoveEnhancedKeyUsageIdentifier(ptr str) -@ stdcall CertRemoveStoreFromCollection(long long) -@ stdcall CertSaveStore(long long long long ptr long) +@ stdcall CertRemoveStoreFromCollection(ptr ptr) +@ stdcall CertSaveStore(ptr long long long ptr long) @ stdcall CertSerializeCRLStoreElement(ptr long ptr ptr) @ stdcall CertSerializeCTLStoreElement(ptr long ptr ptr) @ stdcall CertSerializeCertificateStoreElement(ptr long ptr ptr) @@ -98,7 +99,7 @@ @ stdcall CertVerifyValidityNesting(ptr ptr) @ stdcall CreateFileU(wstr long long ptr long long ptr) kernel32.CreateFileW @ stdcall CryptBinaryToStringA(ptr long long ptr ptr) -@ stub CryptBinaryToStringW # (ptr long long ptr ptr) +@ stdcall CryptBinaryToStringW(ptr long long ptr ptr) @ stdcall CryptStringToBinaryA(str long long ptr ptr ptr ptr) @ stdcall CryptStringToBinaryW (wstr long long ptr ptr ptr ptr) @ stdcall CryptAcquireContextU(ptr wstr wstr long long) advapi32.CryptAcquireContextW diff --git a/reactos/dll/win32/crypt32/crypt32_De.rc b/reactos/dll/win32/crypt32/crypt32_De.rc index aa3a4562c70..9c2c91e3714 100644 --- a/reactos/dll/win32/crypt32/crypt32_De.rc +++ b/reactos/dll/win32/crypt32/crypt32_De.rc @@ -41,7 +41,7 @@ STRINGTABLE DISCARDABLE IDS_ENHANCED_KEY_USAGE "Erweiterte SchlĂĽsselbenutzung" IDS_AUTHORITY_INFO_ACCESS "Autoritätsinformationszugriff" IDS_CERT_EXTENSIONS "Zertifikatserweiterung" - IDS_NEXT_UPDATE_LOCATION "Next Update Location" + IDS_NEXT_UPDATE_LOCATION "nächster Aktualisierungsort" IDS_YES_OR_NO_TRUST "Vertrauen oder nicht vertrauen" IDS_EMAIL_ADDRESS "E-Mail-Adresse" IDS_UNSTRUCTURED_NAME "Unstrukturierter Name" diff --git a/reactos/dll/win32/crypt32/crypt32_private.h b/reactos/dll/win32/crypt32/crypt32_private.h index 07c63825b58..cbdf5116f9c 100644 --- a/reactos/dll/win32/crypt32/crypt32_private.h +++ b/reactos/dll/win32/crypt32/crypt32_private.h @@ -113,6 +113,10 @@ BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, CRYPT_DIGESTED_DATA *digestedData, DWORD *pcbDigestedData); +BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded); + /* The following aren't defined in wincrypt.h, as they're "reserved" */ #define CERT_CERT_PROP_ID 32 #define CERT_CRL_PROP_ID 33 @@ -278,6 +282,12 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, */ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store); +/* Reads contexts serialized in the blob into the memory store. Returns FALSE + * if the file is not of the expected format. + */ +BOOL CRYPT_ReadSerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob, + HCERTSTORE store); + /* Fixes up the pointers in info, where info is assumed to be a * CRYPT_KEY_PROV_INFO, followed by its container name, provider name, and any * provider parameters, in a contiguous buffer, but where info's pointers are @@ -291,7 +301,7 @@ void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info); */ DWORD cert_name_to_str_with_indent(DWORD dwCertEncodingType, DWORD indent, - PCERT_NAME_BLOB pName, DWORD dwStrType, LPWSTR psz, DWORD csz); + const CERT_NAME_BLOB *pName, DWORD dwStrType, LPWSTR psz, DWORD csz); /** * Context functions @@ -336,8 +346,9 @@ typedef void (*ContextFreeFunc)(void *context); /* Decrements context's ref count. If context is a link context, releases its * linked context as well. * If a data context has its ref count reach 0, calls dataContextFree on it. + * Returns FALSE if the reference count is <= 0 when called. */ -void Context_Release(void *context, size_t contextSize, +BOOL Context_Release(void *context, size_t contextSize, ContextFreeFunc dataContextFree); /** @@ -377,7 +388,11 @@ void *ContextList_Add(struct ContextList *list, void *toLink, void *toReplace); void *ContextList_Enum(struct ContextList *list, void *pPrev); -void ContextList_Delete(struct ContextList *list, void *context); +/* Removes a context from the list. Returns TRUE if the context was removed, + * or FALSE if not. (The context may have been duplicated, so subsequent + * removes have no effect.) + */ +BOOL ContextList_Remove(struct ContextList *list, void *context); void ContextList_Free(struct ContextList *list); diff --git a/reactos/dll/win32/crypt32/ctl.c b/reactos/dll/win32/crypt32/ctl.c index 5a6d19b64fe..44b517aeff3 100644 --- a/reactos/dll/win32/crypt32/ctl.c +++ b/reactos/dll/win32/crypt32/ctl.c @@ -309,10 +309,7 @@ BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext) if (!pCtlContext) ret = TRUE; else if (!pCtlContext->hCertStore) - { - ret = TRUE; - CertFreeCTLContext(pCtlContext); - } + ret = CertFreeCTLContext(pCtlContext); else { PWINECRYPT_CERTSTORE hcs = pCtlContext->hCertStore; @@ -321,7 +318,8 @@ BOOL WINAPI CertDeleteCTLFromStore(PCCTL_CONTEXT pCtlContext) ret = FALSE; else ret = hcs->ctls.deleteContext(hcs, (void *)pCtlContext); - CertFreeCTLContext(pCtlContext); + if (ret) + ret = CertFreeCTLContext(pCtlContext); } return ret; } @@ -455,7 +453,8 @@ end: PCCTL_CONTEXT WINAPI CertDuplicateCTLContext(PCCTL_CONTEXT pCtlContext) { TRACE("(%p)\n", pCtlContext); - Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT)); + if (pCtlContext) + Context_AddRef((void *)pCtlContext, sizeof(CTL_CONTEXT)); return pCtlContext; } @@ -471,12 +470,14 @@ static void CTLDataContext_Free(void *context) BOOL WINAPI CertFreeCTLContext(PCCTL_CONTEXT pCTLContext) { + BOOL ret = TRUE; + TRACE("(%p)\n", pCTLContext); if (pCTLContext) - Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT), + ret = Context_Release((void *)pCTLContext, sizeof(CTL_CONTEXT), CTLDataContext_Free); - return TRUE; + return ret; } DWORD WINAPI CertEnumCTLContextProperties(PCCTL_CONTEXT pCTLContext, diff --git a/reactos/dll/win32/crypt32/decode.c b/reactos/dll/win32/crypt32/decode.c index 7a33e6afa5e..a16d89f8802 100644 --- a/reactos/dll/win32/crypt32/decode.c +++ b/reactos/dll/win32/crypt32/decode.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008 Juan Lang + * Copyright 2005-2009 Juan Lang * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -58,12 +58,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(cryptasn); WINE_DECLARE_DEBUG_CHANNEL(crypt); -struct GenericArray -{ - DWORD cItems; - BYTE *rgItems; -}; - typedef BOOL (WINAPI *CryptDecodeObjectFunc)(DWORD, LPCSTR, const BYTE *, DWORD, DWORD, void *, DWORD *); typedef BOOL (WINAPI *CryptDecodeObjectExFunc)(DWORD, LPCSTR, const BYTE *, @@ -81,12 +75,10 @@ static BOOL CRYPT_AsnDecodeChoiceOfTimeInternal(const BYTE *pbEncoded, static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); -/* Like CRYPT_AsnDecodeExtensions, except assumes rgExtension is set ahead of - * time, doesn't do memory allocation, and doesn't do exception handling. +/* Assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set ahead of time. */ -static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded, - DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, - DWORD *pcbDecoded); +static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, + DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); /* Assumes algo->Parameters.pbData is set ahead of time. */ static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); @@ -113,7 +105,7 @@ static BOOL CRYPT_AsnDecodeIntegerInternal(const BYTE *pbEncoded, static BOOL CRYPT_AsnDecodeUnsignedIntegerInternal(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); -static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded, +static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded); @@ -303,6 +295,10 @@ struct AsnDecodeSequenceItem DWORD size; }; +#define FINALMEMBERSIZE(s, member) (sizeof(s) - offsetof(s, member)) +#define MEMBERSIZE(s, member, nextmember) \ + (offsetof(s, nextmember) - offsetof(s, member)) + /* Decodes the items in a sequence, where the items are described in items, * the encoded data are in pbEncoded with length cbEncoded. Decodes into * pvStructInfo. nextData is a pointer to the memory location at which the @@ -361,8 +357,13 @@ static BOOL CRYPT_AsnDecodeSequenceItems(struct AsnDecodeSequenceItem items[], : NULL, &items[i].size, &itemDecoded); if (ret) { - /* Account for alignment padding */ - items[i].size = ALIGN_DWORD_PTR(items[i].size); + if (items[i].size < items[i].minSize) + items[i].size = items[i].minSize; + else if (items[i].size > items[i].minSize) + { + /* Account for alignment padding */ + items[i].size = ALIGN_DWORD_PTR(items[i].size); + } TRACE("item %d size: %d\n", i, items[i].size); if (nextData && items[i].hasPointer && items[i].size > items[i].minSize) @@ -563,6 +564,19 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], * The expected tag of the entire encoded array (usually a variant * of ASN_SETOF or ASN_SEQUENCEOF.) If tag is 0, decodeFunc is called * regardless of the tag seen. + * countOffset: + * The offset within the outer structure at which the count exists. + * For example, a structure such as CRYPT_ATTRIBUTES has countOffset == 0, + * while CRYPT_ATTRIBUTE has countOffset == + * offsetof(CRYPT_ATTRIBUTE, cValue). + * arrayOffset: + * The offset within the outer structure at which the array pointer exists. + * For example, CRYPT_ATTRIBUTES has arrayOffset == + * offsetof(CRYPT_ATTRIBUTES, rgAttr). + * minArraySize: + * The minimum size of the decoded array. On WIN32, this is always 8: + * sizeof(DWORD) + sizeof(void *). On WIN64, it can be larger due to + * alignment. * decodeFunc: * used to decode each item in the array * itemSize: @@ -575,6 +589,9 @@ static BOOL CRYPT_AsnDecodeSequence(struct AsnDecodeSequenceItem items[], struct AsnArrayDescriptor { BYTE tag; + DWORD countOffset; + DWORD arrayOffset; + DWORD minArraySize; InternalDecodeFunc decodeFunc; DWORD itemSize; BOOL hasPointer; @@ -587,35 +604,37 @@ struct AsnArrayItemSize DWORD size; }; -/* Decodes an array of like types into a struct GenericArray. - * The layout and decoding of the array are described by a struct +/* Decodes an array of like types into a structure described by a struct * AsnArrayDescriptor. */ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo, - DWORD *pcbDecoded, void *startingPointer) + DWORD *pcbDecoded) { BOOL ret = TRUE; - TRACE("%p, %p, %d, %08x, %p, %p, %d, %p\n", arrayDesc, pbEncoded, - cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo, - startingPointer); + TRACE("%p, %p, %d, %p, %d\n", arrayDesc, pbEncoded, + cbEncoded, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); - if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag) + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + ret = FALSE; + } + else if (!arrayDesc->tag || pbEncoded[0] == arrayDesc->tag) { DWORD dataLen; if ((ret = CRYPT_GetLengthIndefinite(pbEncoded, cbEncoded, &dataLen))) { - DWORD bytesNeeded, cItems = 0, decoded; + DWORD bytesNeeded = arrayDesc->minArraySize, cItems = 0, decoded; BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); /* There can be arbitrarily many items, but there is often only one. */ struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize; decoded = 1 + lenBytes; - bytesNeeded = sizeof(struct GenericArray); if (dataLen) { const BYTE *ptr; @@ -694,25 +713,30 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, *pcbDecoded = decoded; if (!pvStructInfo) *pcbStructInfo = bytesNeeded; - else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded))) + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, + pvStructInfo, pcbStructInfo, bytesNeeded))) { - DWORD i; + DWORD i, *pcItems; BYTE *nextData; const BYTE *ptr; - struct GenericArray *array; + void *rgItems; if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) - pvStructInfo = *(BYTE **)pvStructInfo; - array = pvStructInfo; - array->cItems = cItems; - if (startingPointer) - array->rgItems = startingPointer; + pvStructInfo = *(void **)pvStructInfo; + pcItems = pvStructInfo; + *pcItems = cItems; + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + { + rgItems = (BYTE *)pvStructInfo + + arrayDesc->minArraySize; + *(void **)((BYTE *)pcItems - + arrayDesc->countOffset + arrayDesc->arrayOffset) = + rgItems; + } else - array->rgItems = (BYTE *)array + - sizeof(struct GenericArray); - nextData = array->rgItems + - array->cItems * arrayDesc->itemSize; + rgItems = *(void **)((BYTE *)pcItems - + arrayDesc->countOffset + arrayDesc->arrayOffset); + nextData = (BYTE *)rgItems + cItems * arrayDesc->itemSize; for (i = 0, ptr = pbEncoded + 1 + lenBytes; ret && i < cItems && ptr - pbEncoded - 1 - lenBytes < dataLen; i++) @@ -720,12 +744,12 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, DWORD itemDecoded; if (arrayDesc->hasPointer) - *(BYTE **)(array->rgItems + i * arrayDesc->itemSize + *(BYTE **)((BYTE *)rgItems + i * arrayDesc->itemSize + arrayDesc->pointerOffset) = nextData; ret = arrayDesc->decodeFunc(ptr, itemSizes[i].encodedLen, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, - array->rgItems + i * arrayDesc->itemSize, + (BYTE *)rgItems + i * arrayDesc->itemSize, &itemSizes[i].size, &itemDecoded); if (ret) { @@ -733,8 +757,6 @@ static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc, ptr += itemDecoded; } } - if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG)) - CRYPT_FreeSpace(pDecodePara, pvStructInfo); } } if (itemSizes != &itemSize) @@ -915,6 +937,25 @@ static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded, return ret; } +static BOOL CRYPT_AsnDecodeCertExtensionsInternal(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret = TRUE; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_INFO, cExtension), offsetof(CERT_INFO, rgExtension), + FINALMEMBERSIZE(CERT_INFO, cExtension), + CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, + offsetof(CERT_EXTENSION, pszObjId) }; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) @@ -926,7 +967,7 @@ static BOOL CRYPT_AsnDecodeCertExtensions(const BYTE *pbEncoded, { BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); - ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded + 1 + lenBytes, + ret = CRYPT_AsnDecodeCertExtensionsInternal(pbEncoded + 1 + lenBytes, dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); if (ret && pcbDecoded) *pcbDecoded = 1 + lenBytes + dataLen; @@ -961,15 +1002,15 @@ static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType, CRYPT_AsnDecodePubKeyInfoInternal, sizeof(CERT_PUBLIC_KEY_INFO), FALSE, TRUE, offsetof(CERT_INFO, SubjectPublicKeyInfo.Algorithm.Parameters.pbData), 0 }, - { ASN_BITSTRING, offsetof(CERT_INFO, IssuerUniqueId), + { ASN_CONTEXT | 1, offsetof(CERT_INFO, IssuerUniqueId), CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CERT_INFO, IssuerUniqueId.pbData), 0 }, - { ASN_BITSTRING, offsetof(CERT_INFO, SubjectUniqueId), + { ASN_CONTEXT | 2, offsetof(CERT_INFO, SubjectUniqueId), CRYPT_AsnDecodeBitsInternal, sizeof(CRYPT_BIT_BLOB), TRUE, TRUE, offsetof(CERT_INFO, SubjectUniqueId.pbData), 0 }, { ASN_CONTEXT | ASN_CONSTRUCTOR | 3, offsetof(CERT_INFO, cExtension), - CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE, - offsetof(CERT_INFO, rgExtension), 0 }, + CRYPT_AsnDecodeCertExtensions, FINALMEMBERSIZE(CERT_INFO, cExtension), + TRUE, TRUE, offsetof(CERT_INFO, rgExtension), 0 }, }; TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, @@ -1051,6 +1092,25 @@ static BOOL WINAPI CRYPT_AsnDecodeCert(DWORD dwCertEncodingType, return ret; } +static BOOL CRYPT_AsnDecodeCRLEntryExtensions(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret = TRUE; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CRL_ENTRY, cExtension), offsetof(CRL_ENTRY, rgExtension), + FINALMEMBERSIZE(CRL_ENTRY, cExtension), + CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, + offsetof(CERT_EXTENSION, pszObjId) }; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { @@ -1062,7 +1122,8 @@ static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded, { 0, offsetof(CRL_ENTRY, RevocationDate), CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 }, { ASN_SEQUENCEOF, offsetof(CRL_ENTRY, cExtension), - CRYPT_AsnDecodeExtensionsInternal, sizeof(CERT_EXTENSIONS), TRUE, TRUE, + CRYPT_AsnDecodeCRLEntryExtensions, + FINALMEMBERSIZE(CRL_ENTRY, cExtension), TRUE, TRUE, offsetof(CRL_ENTRY, rgExtension), 0 }, }; PCRL_ENTRY entry = pvStructInfo; @@ -1082,28 +1143,66 @@ static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded, return ret; } -/* Warning: assumes pvStructInfo is a struct GenericArray whose rgItems has - * been set prior to calling. +/* Warning: assumes pvStructInfo points to the cCRLEntry member of a CRL_INFO + * whose rgCRLEntry member has been set prior to calling. */ static BOOL CRYPT_AsnDecodeCRLEntries(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { BOOL ret; struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CRL_INFO, cCRLEntry), offsetof(CRL_INFO, rgCRLEntry), + MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension), CRYPT_AsnDecodeCRLEntry, sizeof(CRL_ENTRY), TRUE, offsetof(CRL_ENTRY, SerialNumber.pbData) }; - struct GenericArray *entries = pvStructInfo; TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - entries ? entries->rgItems : NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } +static BOOL CRYPT_AsnDecodeCRLExtensionsInternal(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret = TRUE; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CRL_INFO, cExtension), offsetof(CRL_INFO, rgExtension), + FINALMEMBERSIZE(CRL_INFO, cExtension), + CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, + offsetof(CERT_EXTENSION, pszObjId) }; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + +static BOOL CRYPT_AsnDecodeCRLExtensions(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + DWORD dataLen; + + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) + { + BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); + + ret = CRYPT_AsnDecodeCRLExtensionsInternal(pbEncoded + 1 + lenBytes, + dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); + if (ret && pcbDecoded) + *pcbDecoded = 1 + lenBytes + dataLen; + } + return ret; +} + static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) @@ -1122,11 +1221,11 @@ static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType, { 0, offsetof(CRL_INFO, NextUpdate), CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), TRUE, FALSE, 0 }, { ASN_SEQUENCEOF, offsetof(CRL_INFO, cCRLEntry), - CRYPT_AsnDecodeCRLEntries, sizeof(struct GenericArray), TRUE, TRUE, - offsetof(CRL_INFO, rgCRLEntry), 0 }, + CRYPT_AsnDecodeCRLEntries, MEMBERSIZE(CRL_INFO, cCRLEntry, cExtension), + TRUE, TRUE, offsetof(CRL_INFO, rgCRLEntry), 0 }, { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CRL_INFO, cExtension), - CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE, - offsetof(CRL_INFO, rgExtension), 0 }, + CRYPT_AsnDecodeCRLExtensions, FINALMEMBERSIZE(CRL_INFO, cExtension), + TRUE, TRUE, offsetof(CRL_INFO, rgExtension), 0 }, }; BOOL ret = TRUE; @@ -1314,9 +1413,6 @@ static BOOL CRYPT_AsnDecodeOidInternal(const BYTE *pbEncoded, DWORD cbEncoded, return ret; } -/* Warning: assumes pvStructInfo is a CERT_EXTENSION whose pszObjId is set - * ahead of time! - */ static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { @@ -1348,53 +1444,26 @@ static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded, return ret; } -static BOOL CRYPT_AsnDecodeExtensionsInternal(const BYTE *pbEncoded, - DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, - DWORD *pcbDecoded) -{ - BOOL ret = TRUE; - struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, - CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, - offsetof(CERT_EXTENSION, pszObjId) }; - PCERT_EXTENSIONS exts = pvStructInfo; - - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, - pvStructInfo, *pcbStructInfo, pcbDecoded); - - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - exts ? exts->rgExtension : NULL); - return ret; -} - static BOOL WINAPI CRYPT_AsnDecodeExtensions(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) { BOOL ret = TRUE; + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); + __TRY { - ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded, - dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pcbStructInfo, NULL); - if (ret && pvStructInfo) - { - ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, - pcbStructInfo, *pcbStructInfo); - if (ret) - { - CERT_EXTENSIONS *exts; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_EXTENSIONS, cExtension), + offsetof(CERT_EXTENSIONS, rgExtension), + sizeof(CERT_EXTENSIONS), + CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, + offsetof(CERT_EXTENSION, pszObjId) }; - if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) - pvStructInfo = *(BYTE **)pvStructInfo; - exts = pvStructInfo; - exts->rgExtension = (CERT_EXTENSION *)((BYTE *)exts + - sizeof(CERT_EXTENSIONS)); - ret = CRYPT_AsnDecodeExtensionsInternal(pbEncoded, cbEncoded, - dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, - pcbStructInfo, NULL); - } - } + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); } __EXCEPT_PAGE_FAULT { @@ -1814,13 +1883,13 @@ static BOOL CRYPT_AsnDecodeRdn(const BYTE *pbEncoded, DWORD cbEncoded, { BOOL ret = TRUE; struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, + offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr), + sizeof(CERT_RDN), CRYPT_AsnDecodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE, offsetof(CERT_RDN_ATTR, pszObjId) }; - PCERT_RDN rdn = pvStructInfo; ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - rdn ? rdn->rgRDNAttr : NULL); + NULL, pvStructInfo, pcbStructInfo, pcbDecoded); return ret; } @@ -1833,11 +1902,34 @@ static BOOL WINAPI CRYPT_AsnDecodeName(DWORD dwCertEncodingType, __TRY { struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN), + sizeof(CERT_NAME_INFO), CRYPT_AsnDecodeRdn, sizeof(CERT_RDN), TRUE, offsetof(CERT_RDN, rgRDNAttr) }; + DWORD bytesNeeded; - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded, + NULL); + if (ret) + { + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, + pvStructInfo, pcbStructInfo, bytesNeeded))) + { + CERT_NAME_INFO *info; + + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + pvStructInfo = *(BYTE **)pvStructInfo; + info = pvStructInfo; + info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo + + sizeof(CERT_NAME_INFO)); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo, + &bytesNeeded, NULL); + } + } } __EXCEPT_PAGE_FAULT { @@ -1886,13 +1978,13 @@ static BOOL CRYPT_AsnDecodeUnicodeRdn(const BYTE *pbEncoded, DWORD cbEncoded, { BOOL ret = TRUE; struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, + offsetof(CERT_RDN, cRDNAttr), offsetof(CERT_RDN, rgRDNAttr), + sizeof(CERT_RDN), CRYPT_AsnDecodeUnicodeRdnAttr, sizeof(CERT_RDN_ATTR), TRUE, offsetof(CERT_RDN_ATTR, pszObjId) }; - PCERT_RDN rdn = pvStructInfo; ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - rdn ? rdn->rgRDNAttr : NULL); + NULL, pvStructInfo, pcbStructInfo, pcbDecoded); return ret; } @@ -1905,11 +1997,34 @@ static BOOL WINAPI CRYPT_AsnDecodeUnicodeName(DWORD dwCertEncodingType, __TRY { struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_NAME_INFO, cRDN), offsetof(CERT_NAME_INFO, rgRDN), + sizeof(CERT_NAME_INFO), CRYPT_AsnDecodeUnicodeRdn, sizeof(CERT_RDN), TRUE, offsetof(CERT_RDN, rgRDNAttr) }; + DWORD bytesNeeded; - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL, &bytesNeeded, + NULL); + if (ret) + { + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, + pvStructInfo, pcbStructInfo, bytesNeeded))) + { + CERT_NAME_INFO *info; + + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) + pvStructInfo = *(BYTE **)pvStructInfo; + info = pvStructInfo; + info->rgRDN = (CERT_RDN *)((BYTE *)pvStructInfo + + sizeof(CERT_NAME_INFO)); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, pvStructInfo, + &bytesNeeded, NULL); + } + } } __EXCEPT_PAGE_FAULT { @@ -2023,34 +2138,34 @@ static BOOL CRYPT_AsnDecodeCopyBytes(const BYTE *pbEncoded, return ret; } -static BOOL CRYPT_DecodeDERArray(const BYTE *pbEncoded, DWORD cbEncoded, - DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) -{ - BOOL ret; - struct AsnArrayDescriptor arrayDesc = { 0, CRYPT_AsnDecodeCopyBytes, - sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; - struct GenericArray *array = pvStructInfo; - - TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, - pvStructInfo, *pcbStructInfo, pcbDecoded); - - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - array ? array->rgItems : NULL); - return ret; -} - static BOOL CRYPT_AsnDecodeCTLUsage(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { BOOL ret; struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CTL_USAGE, cUsageIdentifier), + offsetof(CTL_USAGE, rgpszUsageIdentifier), + sizeof(CTL_USAGE), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 }; - CTL_USAGE *usage = pvStructInfo; ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - usage ? usage->rgpszUsageIdentifier : NULL); + NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + +static BOOL CRYPT_AsnDecodeCTLEntryAttributes(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + struct AsnArrayDescriptor arrayDesc = { 0, + offsetof(CTL_ENTRY, cAttribute), offsetof(CTL_ENTRY, rgAttribute), + FINALMEMBERSIZE(CTL_ENTRY, cAttribute), + CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE, + offsetof(CRYPT_ATTRIBUTE, pszObjId) }; + BOOL ret; + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); return ret; } @@ -2062,8 +2177,9 @@ static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded, CRYPT_AsnDecodeOctetsInternal, sizeof(CRYPT_DATA_BLOB), FALSE, TRUE, offsetof(CTL_ENTRY, SubjectIdentifier.pbData), 0 }, { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CTL_ENTRY, cAttribute), - CRYPT_AsnDecodePKCSAttributesInternal, sizeof(CRYPT_ATTRIBUTES), FALSE, - TRUE, offsetof(CTL_ENTRY, rgAttribute), 0 }, + CRYPT_AsnDecodeCTLEntryAttributes, + FINALMEMBERSIZE(CTL_ENTRY, cAttribute), FALSE, TRUE, + offsetof(CTL_ENTRY, rgAttribute), 0 }, }; BOOL ret = TRUE; CTL_ENTRY *entry = pvStructInfo; @@ -2082,16 +2198,54 @@ static BOOL CRYPT_AsnDecodeCTLEntries(const BYTE *pbEncoded, DWORD cbEncoded, { BOOL ret; struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CTL_INFO, cCTLEntry), offsetof(CTL_INFO, rgCTLEntry), + FINALMEMBERSIZE(CTL_INFO, cExtension), CRYPT_AsnDecodeCTLEntry, sizeof(CTL_ENTRY), TRUE, offsetof(CTL_ENTRY, SubjectIdentifier.pbData) }; - struct GenericArray *entries = pvStructInfo; TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - entries ? entries->rgItems : NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + +static BOOL CRYPT_AsnDecodeCTLExtensionsInternal(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret = TRUE; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CTL_INFO, cExtension), offsetof(CTL_INFO, rgExtension), + FINALMEMBERSIZE(CTL_INFO, cExtension), + CRYPT_AsnDecodeExtension, sizeof(CERT_EXTENSION), TRUE, + offsetof(CERT_EXTENSION, pszObjId) }; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + +static BOOL CRYPT_AsnDecodeCTLExtensions(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + DWORD dataLen; + + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) + { + BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); + + ret = CRYPT_AsnDecodeCTLExtensionsInternal(pbEncoded + 1 + lenBytes, + dataLen, dwFlags, pvStructInfo, pcbStructInfo, NULL); + if (ret && pcbDecoded) + *pcbDecoded = 1 + lenBytes + dataLen; + } return ret; } @@ -2128,16 +2282,14 @@ static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType, CRYPT_AsnDecodeAlgorithmId, sizeof(CRYPT_ALGORITHM_IDENTIFIER), FALSE, TRUE, offsetof(CTL_INFO, SubjectAlgorithm.pszObjId), 0 }, { ASN_SEQUENCEOF, offsetof(CTL_INFO, cCTLEntry), - CRYPT_AsnDecodeCTLEntries, sizeof(struct GenericArray), + CRYPT_AsnDecodeCTLEntries, + MEMBERSIZE(CTL_INFO, cCTLEntry, cExtension), TRUE, TRUE, offsetof(CTL_INFO, rgCTLEntry), 0 }, { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CTL_INFO, cExtension), - CRYPT_AsnDecodeCertExtensions, sizeof(CERT_EXTENSIONS), TRUE, TRUE, - offsetof(CTL_INFO, rgExtension), 0 }, + CRYPT_AsnDecodeCTLExtensions, FINALMEMBERSIZE(CTL_INFO, cExtension), + TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 }, }; - TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, - pDecodePara, pvStructInfo, *pcbStructInfo); - ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); @@ -2175,22 +2327,6 @@ static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded, return ret; } -static BOOL CRYPT_AsnDecodeSMIMECapabilitiesInternal(const BYTE *pbEncoded, - DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, - DWORD *pcbDecoded) -{ - struct AsnArrayDescriptor arrayDesc = { 0, - CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE, - offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) }; - PCRYPT_SMIME_CAPABILITIES capabilities = pvStructInfo; - BOOL ret; - - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - capabilities ? capabilities->rgCapability : NULL); - return ret; -} - static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) @@ -2202,34 +2338,15 @@ static BOOL WINAPI CRYPT_AsnDecodeSMIMECapabilities(DWORD dwCertEncodingType, __TRY { - DWORD bytesNeeded; + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CRYPT_SMIME_CAPABILITIES, cCapability), + offsetof(CRYPT_SMIME_CAPABILITIES, rgCapability), + sizeof(CRYPT_SMIME_CAPABILITIES), + CRYPT_AsnDecodeSMIMECapability, sizeof(CRYPT_SMIME_CAPABILITY), TRUE, + offsetof(CRYPT_SMIME_CAPABILITY, pszObjId) }; - if (!cbEncoded) - SetLastError(CRYPT_E_ASN1_EOD); - else if (pbEncoded[0] != ASN_SEQUENCEOF) - SetLastError(CRYPT_E_ASN1_CORRUPT); - else if ((ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded, - cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, - NULL))) - { - if (!pvStructInfo) - *pcbStructInfo = bytesNeeded; - else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, - pvStructInfo, pcbStructInfo, bytesNeeded))) - { - PCRYPT_SMIME_CAPABILITIES capabilities; - - if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) - pvStructInfo = *(BYTE **)pvStructInfo; - capabilities = pvStructInfo; - capabilities->rgCapability = - (PCRYPT_SMIME_CAPABILITY)((BYTE *)pvStructInfo + - sizeof(CRYPT_SMIME_CAPABILITIES)); - ret = CRYPT_AsnDecodeSMIMECapabilitiesInternal(pbEncoded, - cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, - &bytesNeeded, NULL); - } - } + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); } __EXCEPT_PAGE_FAULT { @@ -2290,21 +2407,22 @@ static BOOL CRYPT_AsnDecodeIA5String(const BYTE *pbEncoded, return ret; } -static BOOL CRYPT_AsnDecodeIntArray(const BYTE *pbEncoded, +static BOOL CRYPT_AsnDecodeNoticeNumbers(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), + offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers), + FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), CRYPT_AsnDecodeIntInternal, sizeof(int), FALSE, 0 }; - struct GenericArray *array = pvStructInfo; BOOL ret; TRACE("(%p, %d, %08x, %p, %d)\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbDecoded : 0); - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - array ? array->rgItems : NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); TRACE("returning %d\n", ret); return ret; } @@ -2319,7 +2437,8 @@ static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded, pszOrganization), CRYPT_AsnDecodeIA5String, sizeof(LPSTR), FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, pszOrganization), 0 }, { ASN_SEQUENCEOF, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, - cNoticeNumbers), CRYPT_AsnDecodeIntArray, sizeof(struct GenericArray), + cNoticeNumbers), CRYPT_AsnDecodeNoticeNumbers, + FINALMEMBERSIZE(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, cNoticeNumbers), FALSE, TRUE, offsetof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE, rgNoticeNumbers), 0 }, }; @@ -2576,6 +2695,25 @@ static BOOL WINAPI CRYPT_AsnDecodePolicyQualifierUserNotice( return ret; } +static BOOL CRYPT_AsnDecodePKCSAttributeValue(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + struct AsnArrayDescriptor arrayDesc = { 0, + offsetof(CRYPT_ATTRIBUTE, cValue), offsetof(CRYPT_ATTRIBUTE, rgValue), + FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), + CRYPT_AsnDecodeCopyBytes, + sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) @@ -2586,8 +2724,9 @@ static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded, CRYPT_AsnDecodeOidIgnoreTag, sizeof(LPSTR), FALSE, TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId), 0 }, { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_ATTRIBUTE, cValue), - CRYPT_DecodeDERArray, sizeof(struct GenericArray), FALSE, TRUE, - offsetof(CRYPT_ATTRIBUTE, rgValue), 0 }, + CRYPT_AsnDecodePKCSAttributeValue, + FINALMEMBERSIZE(CRYPT_ATTRIBUTE, cValue), FALSE, + TRUE, offsetof(CRYPT_ATTRIBUTE, rgValue), 0 }, }; PCRYPT_ATTRIBUTE attr = pvStructInfo; @@ -2650,14 +2789,14 @@ static BOOL CRYPT_AsnDecodePKCSAttributesInternal(const BYTE *pbEncoded, DWORD *pcbDecoded) { struct AsnArrayDescriptor arrayDesc = { 0, + offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr), + sizeof(CRYPT_ATTRIBUTES), CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) }; - PCRYPT_ATTRIBUTES attrs = pvStructInfo; BOOL ret; ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, attrs ? attrs->rgAttr : - NULL); + NULL, pvStructInfo, pcbStructInfo, pcbDecoded); return ret; } @@ -2672,33 +2811,14 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSAttributes(DWORD dwCertEncodingType, __TRY { - DWORD bytesNeeded; + struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, + offsetof(CRYPT_ATTRIBUTES, cAttr), offsetof(CRYPT_ATTRIBUTES, rgAttr), + sizeof(CRYPT_ATTRIBUTES), + CRYPT_AsnDecodePKCSAttributeInternal, sizeof(CRYPT_ATTRIBUTE), + TRUE, offsetof(CRYPT_ATTRIBUTE, pszObjId) }; - if (!cbEncoded) - SetLastError(CRYPT_E_ASN1_EOD); - else if (pbEncoded[0] != (ASN_CONSTRUCTOR | ASN_SETOF)) - SetLastError(CRYPT_E_ASN1_CORRUPT); - else if ((ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded, - cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, &bytesNeeded, - NULL))) - { - if (!pvStructInfo) - *pcbStructInfo = bytesNeeded; - else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, - pvStructInfo, pcbStructInfo, bytesNeeded))) - { - PCRYPT_ATTRIBUTES attrs; - - if (dwFlags & CRYPT_DECODE_ALLOC_FLAG) - pvStructInfo = *(BYTE **)pvStructInfo; - attrs = pvStructInfo; - attrs->rgAttr = (PCRYPT_ATTRIBUTE)((BYTE *)pvStructInfo + - sizeof(CRYPT_ATTRIBUTES)); - ret = CRYPT_AsnDecodePKCSAttributesInternal(pbEncoded, - cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, pvStructInfo, - &bytesNeeded, NULL); - } - } + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); } __EXCEPT_PAGE_FAULT { @@ -2870,7 +2990,13 @@ static BOOL CRYPT_AsnDecodeAltNameEntry(const BYTE *pbEncoded, DWORD cbEncoded, case 1: /* rfc822Name */ case 2: /* dNSName */ case 6: /* uniformResourceIdentifier */ - bytesNeeded += (dataLen + 1) * sizeof(WCHAR); + if (memchr(pbEncoded + 1 + lenBytes, 0, dataLen)) + { + SetLastError(CRYPT_E_ASN1_RULE); + ret = FALSE; + } + else + bytesNeeded += (dataLen + 1) * sizeof(WCHAR); break; case 4: /* directoryName */ case 7: /* iPAddress */ @@ -2964,20 +3090,19 @@ static BOOL CRYPT_AsnDecodeAltNameInternal(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { - BOOL ret = TRUE; + BOOL ret; struct AsnArrayDescriptor arrayDesc = { 0, + offsetof(CERT_ALT_NAME_INFO, cAltEntry), + offsetof(CERT_ALT_NAME_INFO, rgAltEntry), + sizeof(CERT_ALT_NAME_INFO), CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) }; - PCERT_ALT_NAME_INFO info = pvStructInfo; TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); - if (info) - TRACE("info->rgAltEntry is %p\n", info->rgAltEntry); ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - info ? info->rgAltEntry : NULL); + NULL, pvStructInfo, pcbStructInfo, pcbDecoded); return ret; } @@ -3121,11 +3246,14 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityInfoAccess(DWORD dwCertEncodingType, __TRY { struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_AUTHORITY_INFO_ACCESS, cAccDescr), + offsetof(CERT_AUTHORITY_INFO_ACCESS, rgAccDescr), + sizeof(CERT_AUTHORITY_INFO_ACCESS), CRYPT_AsnDecodeAccessDescription, sizeof(CERT_ACCESS_DESCRIPTION), TRUE, offsetof(CERT_ACCESS_DESCRIPTION, pszAccessMethod) }; - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); } __EXCEPT_PAGE_FAULT { @@ -3374,16 +3502,17 @@ static BOOL CRYPT_AsnDecodeSubtreeConstraints(const BYTE *pbEncoded, { BOOL ret; struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint), + offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), + FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint), CRYPT_AsnDecodeCopyBytes, sizeof(CERT_NAME_BLOB), TRUE, offsetof(CERT_NAME_BLOB, pbData) }; - struct GenericArray *entries = pvStructInfo; TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - entries ? entries->rgItems : NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -3405,7 +3534,8 @@ static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType, sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 }, { ASN_SEQUENCEOF, offsetof(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint), CRYPT_AsnDecodeSubtreeConstraints, - sizeof(struct GenericArray), TRUE, TRUE, + FINALMEMBERSIZE(CERT_BASIC_CONSTRAINTS_INFO, cSubtreesConstraint), + TRUE, TRUE, offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 }, }; @@ -3482,16 +3612,17 @@ static BOOL CRYPT_AsnDecodePolicyQualifiers(const BYTE *pbEncoded, { BOOL ret; struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_POLICY_INFO, cPolicyQualifier), + offsetof(CERT_POLICY_INFO, rgPolicyQualifier), + FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), CRYPT_AsnDecodePolicyQualifier, sizeof(CERT_POLICY_QUALIFIER_INFO), TRUE, offsetof(CERT_POLICY_QUALIFIER_INFO, pszPolicyQualifierId) }; - struct GenericArray *entries = pvStructInfo; TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - entries ? entries->rgItems : NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); TRACE("Returning %d (%08x)\n", ret, GetLastError()); return ret; } @@ -3504,7 +3635,8 @@ static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded, CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), FALSE, TRUE, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier), 0 }, { ASN_SEQUENCEOF, offsetof(CERT_POLICY_INFO, cPolicyQualifier), - CRYPT_AsnDecodePolicyQualifiers, sizeof(struct GenericArray), TRUE, + CRYPT_AsnDecodePolicyQualifiers, + FINALMEMBERSIZE(CERT_POLICY_INFO, cPolicyQualifier), TRUE, TRUE, offsetof(CERT_POLICY_INFO, rgPolicyQualifier), 0 }, }; CERT_POLICY_INFO *info = pvStructInfo; @@ -3531,11 +3663,200 @@ static BOOL WINAPI CRYPT_AsnDecodeCertPolicies(DWORD dwCertEncodingType, __TRY { struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_POLICIES_INFO, cPolicyInfo), + offsetof(CERT_POLICIES_INFO, rgPolicyInfo), + sizeof(CERT_POLICIES_INFO), CRYPT_AsnDecodeCertPolicy, sizeof(CERT_POLICY_INFO), TRUE, offsetof(CERT_POLICY_INFO, pszPolicyIdentifier) }; - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + } + __ENDTRY + return ret; +} + +static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + struct AsnDecodeSequenceItem items[] = { + { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING, + pszIssuerDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), + FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy), 0 }, + { ASN_OBJECTIDENTIFIER, offsetof(CERT_POLICY_MAPPING, + pszSubjectDomainPolicy), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), + FALSE, TRUE, offsetof(CERT_POLICY_MAPPING, pszSubjectDomainPolicy), 0 }, + }; + CERT_POLICY_MAPPING *mapping = pvStructInfo; + BOOL ret; + + TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); + + ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), + pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo, + pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL); + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeCertPolicyMappings(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, + PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret = FALSE; + + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); + + __TRY + { + struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_POLICY_MAPPINGS_INFO, cPolicyMapping), + offsetof(CERT_POLICY_MAPPINGS_INFO, rgPolicyMapping), + sizeof(CERT_POLICY_MAPPING), + CRYPT_AsnDecodeCertPolicyMapping, sizeof(CERT_POLICY_MAPPING), TRUE, + offsetof(CERT_POLICY_MAPPING, pszIssuerDomainPolicy) }; + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + } + __ENDTRY + return ret; +} + +static BOOL CRYPT_AsnDecodeRequireExplicit(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + DWORD skip, size = sizeof(skip); + + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + if (pbEncoded[0] != (ASN_CONTEXT | 0)) + { + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, + &skip, &size, pcbDecoded))) + { + DWORD bytesNeeded = MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, + fRequireExplicitPolicy, fInhibitPolicyMapping); + + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if (*pcbStructInfo < bytesNeeded) + { + *pcbStructInfo = bytesNeeded; + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + { + CERT_POLICY_CONSTRAINTS_INFO *info = + (CERT_POLICY_CONSTRAINTS_INFO *)((BYTE *)pvStructInfo - + offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy)); + + *pcbStructInfo = bytesNeeded; + /* The BOOL is implicit: if the integer is present, then it's + * TRUE. + */ + info->fRequireExplicitPolicy = TRUE; + info->dwRequireExplicitPolicySkipCerts = skip; + } + } + return ret; +} + +static BOOL CRYPT_AsnDecodeInhibitMapping(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + DWORD skip, size = sizeof(skip); + + if (!cbEncoded) + { + SetLastError(CRYPT_E_ASN1_EOD); + return FALSE; + } + if (pbEncoded[0] != (ASN_CONTEXT | 1)) + { + SetLastError(CRYPT_E_ASN1_BADTAG); + return FALSE; + } + if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, + &skip, &size, pcbDecoded))) + { + DWORD bytesNeeded = FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, + fInhibitPolicyMapping); + + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if (*pcbStructInfo < bytesNeeded) + { + *pcbStructInfo = bytesNeeded; + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + { + CERT_POLICY_CONSTRAINTS_INFO *info = + (CERT_POLICY_CONSTRAINTS_INFO *)((BYTE *)pvStructInfo - + offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping)); + + *pcbStructInfo = bytesNeeded; + /* The BOOL is implicit: if the integer is present, then it's + * TRUE. + */ + info->fInhibitPolicyMapping = TRUE; + info->dwInhibitPolicyMappingSkipCerts = skip; + } + } + return ret; +} + +static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints( + DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, + void *pvStructInfo, DWORD *pcbStructInfo) +{ + BOOL ret = FALSE; + + TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags, + pDecodePara, pvStructInfo, pvStructInfo ? *pcbStructInfo : 0); + + __TRY + { + struct AsnDecodeSequenceItem items[] = { + { ASN_CONTEXT | 0, + offsetof(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy), + CRYPT_AsnDecodeRequireExplicit, + MEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fRequireExplicitPolicy, + fInhibitPolicyMapping), TRUE, FALSE, 0, 0 }, + { ASN_CONTEXT | 1, + offsetof(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping), + CRYPT_AsnDecodeInhibitMapping, + FINALMEMBERSIZE(CERT_POLICY_CONSTRAINTS_INFO, fInhibitPolicyMapping), + TRUE, FALSE, 0, 0 }, + }; + + ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]), + pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, + pcbStructInfo, NULL, NULL); } __EXCEPT_PAGE_FAULT { @@ -3833,38 +4154,40 @@ static BOOL CRYPT_AsnDecodeIntInternal(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { BOOL ret; - BYTE buf[sizeof(CRYPT_INTEGER_BLOB) + sizeof(int)]; - CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf; - DWORD size = sizeof(buf); + DWORD dataLen; - blob->pbData = buf + sizeof(CRYPT_INTEGER_BLOB); - ret = CRYPT_AsnDecodeIntegerInternal(pbEncoded, cbEncoded, 0, buf, - &size, pcbDecoded); - if (ret) + if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) { - if (!pvStructInfo) + BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); + + if (pcbDecoded) + *pcbDecoded = 1 + lenBytes + dataLen; + if (dataLen > sizeof(int)) + { + SetLastError(CRYPT_E_ASN1_LARGE); + ret = FALSE; + } + else if (!pvStructInfo) *pcbStructInfo = sizeof(int); else if ((ret = CRYPT_DecodeCheckSpace(pcbStructInfo, sizeof(int)))) { int val, i; - if (blob->pbData[blob->cbData - 1] & 0x80) + if (dataLen && pbEncoded[1 + lenBytes] & 0x80) { /* initialize to a negative value to sign-extend */ val = -1; } else val = 0; - for (i = 0; i < blob->cbData; i++) + for (i = 0; i < dataLen; i++) { val <<= 8; - val |= blob->pbData[blob->cbData - i - 1]; + val |= pbEncoded[1 + lenBytes + i]; } memcpy(pvStructInfo, &val, sizeof(int)); } } - else if (GetLastError() == ERROR_MORE_DATA) - SetLastError(CRYPT_E_ASN1_LARGE); return ret; } @@ -4602,8 +4925,11 @@ static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded, if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen))) { struct AsnArrayDescriptor arrayDesc = { - ASN_CONTEXT | ASN_CONSTRUCTOR | 0, CRYPT_AsnDecodeAltNameEntry, - sizeof(CERT_ALT_NAME_ENTRY), TRUE, + ASN_CONTEXT | ASN_CONSTRUCTOR | 0, + offsetof(CRL_DIST_POINT_NAME, u.FullName.cAltEntry), + offsetof(CRL_DIST_POINT_NAME, u.FullName.rgAltEntry), + FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u), + CRYPT_AsnDecodeAltNameEntry, sizeof(CERT_ALT_NAME_ENTRY), TRUE, offsetof(CERT_ALT_NAME_ENTRY, u.pwszURL) }; BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]); DWORD nameLen; @@ -4612,13 +4938,9 @@ static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded, { ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, - 0, NULL, NULL, &nameLen, NULL, NULL); - /* The CERT_ALT_NAME_INFO's size is included by CRYPT_AsnDecodeArray - * as the sizeof(struct GenericArray), so don't include it in the - * total bytes needed. - */ + dwFlags, NULL, NULL, &nameLen, NULL); bytesNeeded = sizeof(CRL_DIST_POINT_NAME) + nameLen - - sizeof(CERT_ALT_NAME_INFO); + FINALMEMBERSIZE(CRL_DIST_POINT_NAME, u); } else bytesNeeded = sizeof(CRL_DIST_POINT_NAME); @@ -4642,8 +4964,8 @@ static BOOL CRYPT_AsnDecodeDistPointName(const BYTE *pbEncoded, name->dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME; ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded + 1 + lenBytes, cbEncoded - 1 - lenBytes, - 0, NULL, &name->u.FullName, &nameLen, NULL, - name->u.FullName.rgAltEntry); + dwFlags, NULL, &name->u.FullName.cAltEntry, &nameLen, + NULL); } else name->dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME; @@ -4694,11 +5016,14 @@ static BOOL WINAPI CRYPT_AsnDecodeCRLDistPoints(DWORD dwCertEncodingType, __TRY { struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CRL_DIST_POINTS_INFO, cDistPoint), + offsetof(CRL_DIST_POINTS_INFO, rgDistPoint), + sizeof(CRL_DIST_POINTS_INFO), CRYPT_AsnDecodeDistPoint, sizeof(CRL_DIST_POINT), TRUE, offsetof(CRL_DIST_POINT, DistPointName.u.FullName.rgAltEntry) }; - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); } __EXCEPT_PAGE_FAULT { @@ -4721,10 +5046,13 @@ static BOOL WINAPI CRYPT_AsnDecodeEnhancedKeyUsage(DWORD dwCertEncodingType, __TRY { struct AsnArrayDescriptor arrayDesc = { ASN_SEQUENCEOF, + offsetof(CERT_ENHKEY_USAGE, cUsageIdentifier), + offsetof(CERT_ENHKEY_USAGE, rgpszUsageIdentifier), + sizeof(CERT_ENHKEY_USAGE), CRYPT_AsnDecodeOidInternal, sizeof(LPSTR), TRUE, 0 }; - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, NULL); } __EXCEPT_PAGE_FAULT { @@ -4783,7 +5111,8 @@ static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { - BOOL ret = FALSE; + BOOL ret; + DWORD max, size = sizeof(max); TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); @@ -4798,12 +5127,32 @@ static BOOL CRYPT_AsnDecodeMaximum(const BYTE *pbEncoded, SetLastError(CRYPT_E_ASN1_BADTAG); return FALSE; } - /* The BOOL is implicit: if the integer is present, then it's TRUE */ - ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, - pvStructInfo ? (BYTE *)pvStructInfo + sizeof(BOOL) : NULL, pcbStructInfo, - pcbDecoded); - if (ret && pvStructInfo) - *(BOOL *)pvStructInfo = TRUE; + if ((ret = CRYPT_AsnDecodeIntInternal(pbEncoded, cbEncoded, dwFlags, + &max, &size, pcbDecoded))) + { + DWORD bytesNeeded = FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum); + + if (!pvStructInfo) + *pcbStructInfo = bytesNeeded; + else if (*pcbStructInfo < bytesNeeded) + { + *pcbStructInfo = bytesNeeded; + SetLastError(ERROR_MORE_DATA); + ret = FALSE; + } + else + { + CERT_GENERAL_SUBTREE *subtree = (CERT_GENERAL_SUBTREE *) + ((BYTE *)pvStructInfo - offsetof(CERT_GENERAL_SUBTREE, fMaximum)); + + *pcbStructInfo = bytesNeeded; + /* The BOOL is implicit: if the integer is present, then it's + * TRUE. + */ + subtree->fMaximum = TRUE; + subtree->dwMaximum = max; + } + } TRACE("returning %d\n", ret); return ret; } @@ -4820,8 +5169,8 @@ static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded, { ASN_CONTEXT | 0, offsetof(CERT_GENERAL_SUBTREE, dwMinimum), CRYPT_AsnDecodeIntInternal, sizeof(DWORD), TRUE, FALSE, 0, 0 }, { ASN_CONTEXT | 1, offsetof(CERT_GENERAL_SUBTREE, fMaximum), - CRYPT_AsnDecodeMaximum, sizeof(BOOL) + sizeof(DWORD), TRUE, FALSE, 0, - 0 }, + CRYPT_AsnDecodeMaximum, FINALMEMBERSIZE(CERT_GENERAL_SUBTREE, fMaximum), + TRUE, FALSE, 0, 0 }, }; CERT_GENERAL_SUBTREE *subtree = pvStructInfo; @@ -4842,25 +5191,46 @@ static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded, return ret; } -static BOOL CRYPT_AsnDecodeSubtreeArray(const BYTE *pbEncoded, +static BOOL CRYPT_AsnDecodePermittedSubtree(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) { BOOL ret = TRUE; struct AsnArrayDescriptor arrayDesc = { 0, + offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree), + offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), + MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree, + cExcludedSubtree), CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE, offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) }; - struct GenericArray *array = pvStructInfo; TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - array ? array->rgItems : NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); return ret; } +static BOOL CRYPT_AsnDecodeExcludedSubtree(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret = TRUE; + struct AsnArrayDescriptor arrayDesc = { 0, + offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), + offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), + FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), + CRYPT_AsnDecodeSubtree, sizeof(CERT_GENERAL_SUBTREE), TRUE, + offsetof(CERT_GENERAL_SUBTREE, Base.u.pwszURL) }; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, *pcbStructInfo, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, @@ -4876,11 +5246,15 @@ static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType, struct AsnDecodeSequenceItem items[] = { { ASN_CONTEXT | ASN_CONSTRUCTOR | 0, offsetof(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree), - CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE, + CRYPT_AsnDecodePermittedSubtree, + MEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cPermittedSubtree, + cExcludedSubtree), TRUE, TRUE, offsetof(CERT_NAME_CONSTRAINTS_INFO, rgPermittedSubtree), 0 }, { ASN_CONTEXT | ASN_CONSTRUCTOR | 1, offsetof(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), - CRYPT_AsnDecodeSubtreeArray, sizeof(struct GenericArray), TRUE, TRUE, + CRYPT_AsnDecodeExcludedSubtree, + FINALMEMBERSIZE(CERT_NAME_CONSTRAINTS_INFO, cExcludedSubtree), + TRUE, TRUE, offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 }, }; @@ -5008,6 +5382,46 @@ static BOOL WINAPI CRYPT_AsnDecodePKCSSignerInfo(DWORD dwCertEncodingType, return ret; } +static BOOL CRYPT_AsnDecodeCMSCertEncoded(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + struct AsnArrayDescriptor arrayDesc = { 0, + offsetof(CRYPT_SIGNED_INFO, cCertEncoded), + offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), + MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), + CRYPT_AsnDecodeCopyBytes, + sizeof(CRYPT_DER_BLOB), TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + +static BOOL CRYPT_AsnDecodeCMSCrlEncoded(const BYTE *pbEncoded, + DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, + DWORD *pcbDecoded) +{ + BOOL ret; + struct AsnArrayDescriptor arrayDesc = { 0, + offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), + offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), + MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), + CRYPT_AsnDecodeCopyBytes, sizeof(CRYPT_DER_BLOB), + TRUE, offsetof(CRYPT_DER_BLOB, pbData) }; + + TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, + pvStructInfo, pvStructInfo ? *pcbStructInfo : 0, pcbDecoded); + + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); + return ret; +} + static BOOL CRYPT_AsnDecodeCMSSignerId(const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, DWORD *pcbStructInfo, DWORD *pcbDecoded) @@ -5137,16 +5551,17 @@ static BOOL CRYPT_DecodeSignerArray(const BYTE *pbEncoded, DWORD cbEncoded, { BOOL ret; struct AsnArrayDescriptor arrayDesc = { ASN_CONSTRUCTOR | ASN_SETOF, + offsetof(CRYPT_SIGNED_INFO, cSignerInfo), + offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), + FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), CRYPT_AsnDecodeCMSSignerInfoInternal, sizeof(CMSG_CMS_SIGNER_INFO), TRUE, offsetof(CMSG_CMS_SIGNER_INFO, SignerId.u.KeyId.pbData) }; - struct GenericArray *array = pvStructInfo; TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags, pvStructInfo, *pcbStructInfo, pcbDecoded); - ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, dwFlags, - NULL, pvStructInfo, pcbStructInfo, pcbDecoded, - array ? array->rgItems : NULL); + ret = CRYPT_AsnDecodeArray(&arrayDesc, pbEncoded, cbEncoded, + dwFlags, NULL, pvStructInfo, pcbStructInfo, pcbDecoded); return ret; } @@ -5166,15 +5581,16 @@ BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded, CRYPT_AsnDecodePKCSContentInfoInternal, sizeof(CRYPT_CONTENT_INFO), FALSE, TRUE, offsetof(CRYPT_SIGNED_INFO, content.pszObjId), 0 }, { ASN_CONSTRUCTOR | ASN_CONTEXT | 0, - offsetof(CRYPT_SIGNED_INFO, cCertEncoded), - CRYPT_DecodeDERArray, sizeof(struct GenericArray), TRUE, TRUE, + offsetof(CRYPT_SIGNED_INFO, cCertEncoded), CRYPT_AsnDecodeCMSCertEncoded, + MEMBERSIZE(CRYPT_SIGNED_INFO, cCertEncoded, cCrlEncoded), TRUE, TRUE, offsetof(CRYPT_SIGNED_INFO, rgCertEncoded), 0 }, { ASN_CONSTRUCTOR | ASN_CONTEXT | 1, - offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_DecodeDERArray, - sizeof(struct GenericArray), TRUE, TRUE, + offsetof(CRYPT_SIGNED_INFO, cCrlEncoded), CRYPT_AsnDecodeCMSCrlEncoded, + MEMBERSIZE(CRYPT_SIGNED_INFO, cCrlEncoded, content), TRUE, TRUE, offsetof(CRYPT_SIGNED_INFO, rgCrlEncoded), 0 }, { ASN_CONSTRUCTOR | ASN_SETOF, offsetof(CRYPT_SIGNED_INFO, cSignerInfo), - CRYPT_DecodeSignerArray, sizeof(struct GenericArray), TRUE, TRUE, + CRYPT_DecodeSignerArray, + FINALMEMBERSIZE(CRYPT_SIGNED_INFO, cSignerInfo), TRUE, TRUE, offsetof(CRYPT_SIGNED_INFO, rgSignerInfo), 0 }, }; @@ -5312,6 +5728,12 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType, case LOWORD(X509_NAME_CONSTRAINTS): decodeFunc = CRYPT_AsnDecodeNameConstraints; break; + case LOWORD(X509_POLICY_MAPPINGS): + decodeFunc = CRYPT_AsnDecodeCertPolicyMappings; + break; + case LOWORD(X509_POLICY_CONSTRAINTS): + decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints; + break; case LOWORD(PKCS7_SIGNER_INFO): decodeFunc = CRYPT_AsnDecodePKCSSignerInfo; break; @@ -5328,6 +5750,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType, decodeFunc = CRYPT_AsnDecodeSMIMECapabilities; else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER)) decodeFunc = CRYPT_AsnDecodeAuthorityKeyId; + else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS)) + decodeFunc = CRYPT_AsnDecodeCertPolicyMappings; else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2)) decodeFunc = CRYPT_AsnDecodeAuthorityKeyId2; else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE)) @@ -5354,6 +5778,10 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType, decodeFunc = CRYPT_AsnDecodeCRLDistPoints; else if (!strcmp(lpszStructType, szOID_CERT_POLICIES)) decodeFunc = CRYPT_AsnDecodeCertPolicies; + else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS)) + decodeFunc = CRYPT_AsnDecodeCertPolicyMappings; + else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS)) + decodeFunc = CRYPT_AsnDecodeCertPolicyConstraints; else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE)) decodeFunc = CRYPT_AsnDecodeEnhancedKeyUsage; else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT)) diff --git a/reactos/dll/win32/crypt32/encode.c b/reactos/dll/win32/crypt32/encode.c index 258384c7318..4d137cebc2f 100644 --- a/reactos/dll/win32/crypt32/encode.c +++ b/reactos/dll/win32/crypt32/encode.c @@ -415,7 +415,7 @@ static BOOL WINAPI CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType, { const CERT_PUBLIC_KEY_INFO *info = pvStructInfo; struct AsnEncodeSequenceItem items[] = { - { &info->Algorithm, CRYPT_AsnEncodeAlgorithmId, 0 }, + { &info->Algorithm, CRYPT_AsnEncodeAlgorithmIdWithNullParams, 0 }, { &info->PublicKey, CRYPT_AsnEncodeBits, 0 }, }; @@ -464,6 +464,25 @@ static BOOL WINAPI CRYPT_AsnEncodeCert(DWORD dwCertEncodingType, return ret; } +BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret; + const CERT_PUBLIC_KEY_INFO *info = pvStructInfo; + struct AsnEncodeSequenceItem items[] = { + { &info->Algorithm, CRYPT_AsnEncodeAlgorithmId, 0 }, + { &info->PublicKey, CRYPT_AsnEncodeBits, 0 }, + }; + + TRACE("Encoding public key with OID %s\n", + debugstr_a(info->Algorithm.pszObjId)); + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded, + pcbEncoded); + return ret; +} + /* Like in Windows, this blithely ignores the validity of the passed-in * CERT_INFO, and just encodes it as-is. The resulting encoded data may not * decode properly, see CRYPT_AsnDecodeCertInfo. @@ -484,40 +503,40 @@ static BOOL WINAPI CRYPT_AsnEncodeCertInfo(DWORD dwCertEncodingType, { &info->Issuer, CRYPT_CopyEncodedBlob, 0 }, { &info->NotBefore, CRYPT_AsnEncodeValidity, 0 }, { &info->Subject, CRYPT_CopyEncodedBlob, 0 }, - { &info->SubjectPublicKeyInfo, CRYPT_AsnEncodePubKeyInfo, 0 }, + { &info->SubjectPublicKeyInfo, CRYPT_AsnEncodePubKeyInfoNoNull, 0 }, { 0 } }; - struct AsnConstructedItem constructed[3] = { { 0 } }; - DWORD cItem = 7, cConstructed = 0; + struct AsnConstructedItem constructed = { 0 }; + struct AsnEncodeTagSwappedItem swapped[2] = { { 0 } }; + DWORD cItem = 7, cSwapped = 0; if (info->IssuerUniqueId.cbData) { - constructed[cConstructed].tag = 1; - constructed[cConstructed].pvStructInfo = &info->IssuerUniqueId; - constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits; - items[cItem].pvStructInfo = &constructed[cConstructed]; - items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; - cConstructed++; + swapped[cSwapped].tag = ASN_CONTEXT | 1; + swapped[cSwapped].pvStructInfo = &info->IssuerUniqueId; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; cItem++; } if (info->SubjectUniqueId.cbData) { - constructed[cConstructed].tag = 2; - constructed[cConstructed].pvStructInfo = &info->SubjectUniqueId; - constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeBits; - items[cItem].pvStructInfo = &constructed[cConstructed]; - items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; - cConstructed++; + swapped[cSwapped].tag = ASN_CONTEXT | 2; + swapped[cSwapped].pvStructInfo = &info->SubjectUniqueId; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; cItem++; } if (info->cExtension) { - constructed[cConstructed].tag = 3; - constructed[cConstructed].pvStructInfo = &info->cExtension; - constructed[cConstructed].encodeFunc = CRYPT_AsnEncodeExtensions; - items[cItem].pvStructInfo = &constructed[cConstructed]; + constructed.tag = 3; + constructed.pvStructInfo = &info->cExtension; + constructed.encodeFunc = CRYPT_AsnEncodeExtensions; + items[cItem].pvStructInfo = &constructed; items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed; - cConstructed++; cItem++; } @@ -2800,13 +2819,10 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) { - DWORD cPolicyQualifier = *(DWORD *)pvStructInfo; - const CERT_POLICY_QUALIFIER_INFO *rgPolicyQualifier = - *(const CERT_POLICY_QUALIFIER_INFO **) - ((LPBYTE)pvStructInfo + sizeof(DWORD)); + const CERT_POLICY_INFO *info = pvStructInfo; BOOL ret; - if (!cPolicyQualifier) + if (!info->cPolicyQualifier) { *pcbEncoded = 0; ret = TRUE; @@ -2820,10 +2836,11 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType, DWORD bytesNeeded = 0, lenBytes, size, i; ret = TRUE; - for (i = 0; ret && i < cPolicyQualifier; i++) + for (i = 0; ret && i < info->cPolicyQualifier; i++) { - items[0].pvStructInfo = rgPolicyQualifier[i].pszPolicyQualifierId; - items[1].pvStructInfo = &rgPolicyQualifier[i].Qualifier; + items[0].pvStructInfo = + info->rgPolicyQualifier[i].pszPolicyQualifierId; + items[1].pvStructInfo = &info->rgPolicyQualifier[i].Qualifier; ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, sizeof(items) / sizeof(items[0]), dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &size); @@ -2847,12 +2864,12 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType, CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, &lenBytes); pbEncoded += lenBytes; - for (i = 0; ret && i < cPolicyQualifier; i++) + for (i = 0; ret && i < info->cPolicyQualifier; i++) { items[0].pvStructInfo = - rgPolicyQualifier[i].pszPolicyQualifierId; + info->rgPolicyQualifier[i].pszPolicyQualifierId; items[1].pvStructInfo = - &rgPolicyQualifier[i].Qualifier; + &info->rgPolicyQualifier[i].Qualifier; size = bytesNeeded; ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, sizeof(items) / sizeof(items[0]), @@ -2877,7 +2894,7 @@ static BOOL CRYPT_AsnEncodeCertPolicy(DWORD dwCertEncodingType, { struct AsnEncodeSequenceItem items[2] = { { info->pszPolicyIdentifier, CRYPT_AsnEncodeOid, 0 }, - { &info->cPolicyQualifier, CRYPT_AsnEncodeCertPolicyQualifiers, 0 }, + { info, CRYPT_AsnEncodeCertPolicyQualifiers, 0 }, }; BOOL ret; @@ -2952,6 +2969,132 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicies(DWORD dwCertEncodingType, return ret; } +static BOOL CRYPT_AsnEncodeCertPolicyMapping(DWORD dwCertEncodingType, + const CERT_POLICY_MAPPING *mapping, DWORD dwFlags, BYTE *pbEncoded, + DWORD *pcbEncoded) +{ + struct AsnEncodeSequenceItem items[] = { + { mapping->pszIssuerDomainPolicy, CRYPT_AsnEncodeOid, 0 }, + { mapping->pszSubjectDomainPolicy, CRYPT_AsnEncodeOid, 0 }, + }; + + if (!mapping->pszIssuerDomainPolicy || !mapping->pszSubjectDomainPolicy) + { + SetLastError(E_INVALIDARG); + return FALSE; + } + return CRYPT_AsnEncodeSequence(dwCertEncodingType, items, + sizeof(items) / sizeof(items[0]), dwFlags, NULL, pbEncoded, pcbEncoded); +} + +static BOOL WINAPI CRYPT_AsnEncodeCertPolicyMappings(DWORD dwCertEncodingType, + LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, + PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) +{ + BOOL ret = FALSE; + + __TRY + { + const CERT_POLICY_MAPPINGS_INFO *info = pvStructInfo; + DWORD bytesNeeded = 0, lenBytes, size, i; + + ret = TRUE; + for (i = 0; ret && i < info->cPolicyMapping; i++) + { + ret = CRYPT_AsnEncodeCertPolicyMapping(dwCertEncodingType, + &info->rgPolicyMapping[i], dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, + NULL, &size); + if (ret) + bytesNeeded += size; + } + CRYPT_EncodeLen(bytesNeeded, NULL, &lenBytes); + bytesNeeded += 1 + lenBytes; + if (ret) + { + if (!pbEncoded) + *pcbEncoded = bytesNeeded; + else + { + if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara, + pbEncoded, pcbEncoded, bytesNeeded))) + { + if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG) + pbEncoded = *(BYTE **)pbEncoded; + *pbEncoded++ = ASN_SEQUENCEOF; + CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded, + &lenBytes); + pbEncoded += lenBytes; + for (i = 0; ret && i < info->cPolicyMapping; i++) + { + size = bytesNeeded; + ret = CRYPT_AsnEncodeCertPolicyMapping( + dwCertEncodingType, &info->rgPolicyMapping[i], + dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, pbEncoded, &size); + if (ret) + { + pbEncoded += size; + bytesNeeded -= size; + } + } + } + } + } + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + } + __ENDTRY + return ret; +} + +static BOOL WINAPI CRYPT_AsnEncodeCertPolicyConstraints( + DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, + DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, + DWORD *pcbEncoded) +{ + BOOL ret = FALSE; + + __TRY + { + const CERT_POLICY_CONSTRAINTS_INFO *info = pvStructInfo; + struct AsnEncodeSequenceItem items[2]; + struct AsnEncodeTagSwappedItem swapped[2]; + DWORD cItem = 0, cSwapped = 0; + + if (info->fRequireExplicitPolicy) + { + swapped[cSwapped].tag = ASN_CONTEXT | 0; + swapped[cSwapped].pvStructInfo = + &info->dwRequireExplicitPolicySkipCerts; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInt; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + if (info->fInhibitPolicyMapping) + { + swapped[cSwapped].tag = ASN_CONTEXT | 1; + swapped[cSwapped].pvStructInfo = + &info->dwInhibitPolicyMappingSkipCerts; + swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeInt; + items[cItem].pvStructInfo = &swapped[cSwapped]; + items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag; + cSwapped++; + cItem++; + } + ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem, + dwFlags, NULL, pbEncoded, pcbEncoded); + } + __EXCEPT_PAGE_FAULT + { + SetLastError(STATUS_ACCESS_VIOLATION); + } + __ENDTRY + return ret; +} + static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType, LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded) @@ -4314,6 +4457,12 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, case LOWORD(X509_NAME_CONSTRAINTS): encodeFunc = CRYPT_AsnEncodeNameConstraints; break; + case LOWORD(X509_POLICY_MAPPINGS): + encodeFunc = CRYPT_AsnEncodeCertPolicyMappings; + break; + case LOWORD(X509_POLICY_CONSTRAINTS): + encodeFunc = CRYPT_AsnEncodeCertPolicyConstraints; + break; case LOWORD(PKCS7_SIGNER_INFO): encodeFunc = CRYPT_AsnEncodePKCSSignerInfo; break; @@ -4330,6 +4479,8 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, encodeFunc = CRYPT_AsnEncodeUtcTime; else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER)) encodeFunc = CRYPT_AsnEncodeAuthorityKeyId; + else if (!strcmp(lpszStructType, szOID_LEGACY_POLICY_MAPPINGS)) + encodeFunc = CRYPT_AsnEncodeCertPolicyMappings; else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2)) encodeFunc = CRYPT_AsnEncodeAuthorityKeyId2; else if (!strcmp(lpszStructType, szOID_CRL_REASON_CODE)) @@ -4356,6 +4507,10 @@ static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType, encodeFunc = CRYPT_AsnEncodeCRLDistPoints; else if (!strcmp(lpszStructType, szOID_CERT_POLICIES)) encodeFunc = CRYPT_AsnEncodeCertPolicies; + else if (!strcmp(lpszStructType, szOID_POLICY_MAPPINGS)) + encodeFunc = CRYPT_AsnEncodeCertPolicyMappings; + else if (!strcmp(lpszStructType, szOID_POLICY_CONSTRAINTS)) + encodeFunc = CRYPT_AsnEncodeCertPolicyConstraints; else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE)) encodeFunc = CRYPT_AsnEncodeEnhancedKeyUsage; else if (!strcmp(lpszStructType, szOID_ISSUING_DIST_POINT)) @@ -4567,6 +4722,7 @@ static BOOL WINAPI CRYPT_ExportRsaPublicKeyInfoEx(HCRYPTPROV_OR_NCRYPT_KEY_HANDL } else { + *pcbInfo = sizeNeeded; pInfo->Algorithm.pszObjId = (char *)pInfo + sizeof(CERT_PUBLIC_KEY_INFO); lstrcpyA(pInfo->Algorithm.pszObjId, diff --git a/reactos/dll/win32/crypt32/filestore.c b/reactos/dll/win32/crypt32/filestore.c index f27b3b7386a..52e575271b0 100644 --- a/reactos/dll/win32/crypt32/filestore.c +++ b/reactos/dll/win32/crypt32/filestore.c @@ -43,7 +43,6 @@ static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) if (store->dirty) CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0); - CertCloseStore(store->memStore, dwFlags); CloseHandle(store->file); CryptMemFree(store); } diff --git a/reactos/dll/win32/crypt32/main.c b/reactos/dll/win32/crypt32/main.c index d93163c1936..1a5972fe843 100644 --- a/reactos/dll/win32/crypt32/main.c +++ b/reactos/dll/win32/crypt32/main.c @@ -64,8 +64,9 @@ HCRYPTPROV CRYPT_GetDefaultProvider(void) { HCRYPTPROV prov; - CryptAcquireContextW(&prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT); + if (!CryptAcquireContextW(&prov, NULL, MS_ENHANCED_PROV_W, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) + return hDefProv; InterlockedCompareExchangePointer((PVOID *)&hDefProv, (PVOID)prov, NULL); if (hDefProv != prov) diff --git a/reactos/dll/win32/crypt32/msg.c b/reactos/dll/win32/crypt32/msg.c index 8a88b75eaed..825b6da96ff 100644 --- a/reactos/dll/win32/crypt32/msg.c +++ b/reactos/dll/win32/crypt32/msg.c @@ -719,27 +719,22 @@ static BOOL CRYPT_ConstructBlob(CRYPT_DATA_BLOB *out, const CRYPT_DATA_BLOB *in) return ret; } -typedef struct _BlobArray -{ - DWORD cBlobs; - PCRYPT_DATA_BLOB blobs; -} BlobArray; - -static BOOL CRYPT_ConstructBlobArray(BlobArray *out, const BlobArray *in) +static BOOL CRYPT_ConstructBlobArray(DWORD *outCBlobs, + PCRYPT_DATA_BLOB *outPBlobs, DWORD cBlobs, const PCRYPT_DATA_BLOB pBlobs) { BOOL ret = TRUE; - out->cBlobs = in->cBlobs; - if (out->cBlobs) + *outCBlobs = cBlobs; + if (cBlobs) { - out->blobs = CryptMemAlloc(out->cBlobs * sizeof(CRYPT_DATA_BLOB)); - if (out->blobs) + *outPBlobs = CryptMemAlloc(cBlobs * sizeof(CRYPT_DATA_BLOB)); + if (*outPBlobs) { DWORD i; - memset(out->blobs, 0, out->cBlobs * sizeof(CRYPT_DATA_BLOB)); - for (i = 0; ret && i < out->cBlobs; i++) - ret = CRYPT_ConstructBlob(&out->blobs[i], &in->blobs[i]); + memset(*outPBlobs, 0, cBlobs * sizeof(CRYPT_DATA_BLOB)); + for (i = 0; ret && i < cBlobs; i++) + ret = CRYPT_ConstructBlob(&(*outPBlobs)[i], &pBlobs[i]); } else ret = FALSE; @@ -747,13 +742,13 @@ static BOOL CRYPT_ConstructBlobArray(BlobArray *out, const BlobArray *in) return ret; } -static void CRYPT_FreeBlobArray(BlobArray *array) +static void CRYPT_FreeBlobArray(DWORD cBlobs, PCRYPT_DATA_BLOB blobs) { DWORD i; - for (i = 0; i < array->cBlobs; i++) - CryptMemFree(array->blobs[i].pbData); - CryptMemFree(array->blobs); + for (i = 0; i < cBlobs; i++) + CryptMemFree(blobs[i].pbData); + CryptMemFree(blobs); } static BOOL CRYPT_ConstructAttribute(CRYPT_ATTRIBUTE *out, @@ -765,8 +760,8 @@ static BOOL CRYPT_ConstructAttribute(CRYPT_ATTRIBUTE *out, if (out->pszObjId) { strcpy(out->pszObjId, in->pszObjId); - ret = CRYPT_ConstructBlobArray((BlobArray *)&out->cValue, - (const BlobArray *)&in->cValue); + ret = CRYPT_ConstructBlobArray(&out->cValue, &out->rgValue, + in->cValue, in->rgValue); } else ret = FALSE; @@ -1179,8 +1174,10 @@ static void CSignedEncodeMsg_Close(HCRYPTMSG hCryptMsg) CryptMemFree(msg->innerOID); CryptMemFree(msg->data.pbData); - CRYPT_FreeBlobArray((BlobArray *)&msg->msg_data.info->cCertEncoded); - CRYPT_FreeBlobArray((BlobArray *)&msg->msg_data.info->cCrlEncoded); + CRYPT_FreeBlobArray(msg->msg_data.info->cCertEncoded, + msg->msg_data.info->rgCertEncoded); + CRYPT_FreeBlobArray(msg->msg_data.info->cCrlEncoded, + msg->msg_data.info->rgCrlEncoded); for (i = 0; i < msg->msg_data.info->cSignerInfo; i++) CSignerInfo_Free(&msg->msg_data.info->rgSignerInfo[i]); CSignedMsgData_CloseHandles(&msg->msg_data); @@ -1435,13 +1432,13 @@ static HCRYPTMSG CSignedEncodeMsg_Open(DWORD dwFlags, } } if (ret) - ret = CRYPT_ConstructBlobArray( - (BlobArray *)&msg->msg_data.info->cCertEncoded, - (const BlobArray *)&info->cCertEncoded); + ret = CRYPT_ConstructBlobArray(&msg->msg_data.info->cCertEncoded, + &msg->msg_data.info->rgCertEncoded, info->cCertEncoded, + info->rgCertEncoded); if (ret) - ret = CRYPT_ConstructBlobArray( - (BlobArray *)&msg->msg_data.info->cCrlEncoded, - (const BlobArray *)&info->cCrlEncoded); + ret = CRYPT_ConstructBlobArray(&msg->msg_data.info->cCrlEncoded, + &msg->msg_data.info->rgCrlEncoded, info->cCrlEncoded, + info->rgCrlEncoded); if (!ret) { CSignedEncodeMsg_Close(msg); diff --git a/reactos/dll/win32/crypt32/object.c b/reactos/dll/win32/crypt32/object.c index f505b7d804d..3d18c505fb4 100644 --- a/reactos/dll/win32/crypt32/object.c +++ b/reactos/dll/win32/crypt32/object.c @@ -283,20 +283,13 @@ end: return ret; } -static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType, - const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, +static BOOL CRYPT_QuerySerializedStoreFromFile(LPCWSTR fileName, + DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg) { - LPCWSTR fileName = pvObject; HANDLE file; BOOL ret = FALSE; - if (dwObjectType != CERT_QUERY_OBJECT_FILE) - { - FIXME("unimplemented for non-file type %d\n", dwObjectType); - SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */ - return FALSE; - } TRACE("%s\n", debugstr_w(fileName)); file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); @@ -322,6 +315,50 @@ static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType, return ret; } +static BOOL CRYPT_QuerySerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob, + DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, + HCERTSTORE *phCertStore, HCRYPTMSG *phMsg) +{ + HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + BOOL ret; + + TRACE("(%d, %p)\n", blob->cbData, blob->pbData); + + ret = CRYPT_ReadSerializedStoreFromBlob(blob, store); + if (ret) + { + if (pdwMsgAndCertEncodingType) + *pdwMsgAndCertEncodingType = X509_ASN_ENCODING; + if (pdwContentType) + *pdwContentType = CERT_QUERY_CONTENT_SERIALIZED_STORE; + if (phCertStore) + *phCertStore = CertDuplicateStore(store); + } + CertCloseStore(store, 0); + TRACE("returning %d\n", ret); + return ret; +} + +static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType, + const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, + HCERTSTORE *phCertStore, HCRYPTMSG *phMsg) +{ + switch (dwObjectType) + { + case CERT_QUERY_OBJECT_FILE: + return CRYPT_QuerySerializedStoreFromFile(pvObject, + pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg); + case CERT_QUERY_OBJECT_BLOB: + return CRYPT_QuerySerializedStoreFromBlob(pvObject, + pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg); + default: + FIXME("unimplemented for type %d\n", dwObjectType); + SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */ + return FALSE; + } +} + static BOOL CRYPT_QuerySignedMessage(const CRYPT_DATA_BLOB *blob, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCRYPTMSG *phMsg) { @@ -562,11 +599,13 @@ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject, { if (pdwFormatType) *pdwFormatType = formatType; - if (phMsg) - *phMsg = msg; if (phCertStore) *phCertStore = CertOpenStore(CERT_STORE_PROV_MSG, encodingType, 0, 0, msg); + if (phMsg) + *phMsg = msg; + else + CryptMsgClose(msg); } if (blob == &fileBlob) CryptMemFree(blob->pbData); diff --git a/reactos/dll/win32/crypt32/oid.c b/reactos/dll/win32/crypt32/oid.c index ddc6efc7655..0a3889d183c 100644 --- a/reactos/dll/win32/crypt32/oid.c +++ b/reactos/dll/win32/crypt32/oid.c @@ -873,9 +873,18 @@ static BOOL CRYPT_RemoveStringFromMultiString(LPWSTR multi, LPCWSTR toRemove) { DWORD len = CRYPT_GetMultiStringCharacterLen(multi); - /* Copy remainder of string "left" */ - memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1, - (len - (spotToRemove - multi)) * sizeof(WCHAR)); + if (spotToRemove + lstrlenW(toRemove) + 2 >= multi + len) + { + /* Removing last string in list, terminate multi string directly */ + *spotToRemove = 0; + *(spotToRemove + 1) = 0; + } + else + { + /* Copy remainder of string "left" */ + memmove(spotToRemove, spotToRemove + lstrlenW(toRemove) + 1, + (len - (spotToRemove - multi)) * sizeof(WCHAR)); + } ret = TRUE; } else diff --git a/reactos/dll/win32/crypt32/rootstore.c b/reactos/dll/win32/crypt32/rootstore.c index bd6dfac450a..a55b281601c 100644 --- a/reactos/dll/win32/crypt32/rootstore.c +++ b/reactos/dll/win32/crypt32/rootstore.c @@ -261,9 +261,23 @@ static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) "chain creation failed"); else { - /* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */ - if (chain->TrustStatus.dwErrorStatus & - ~CERT_TRUST_IS_UNTRUSTED_ROOT) + DWORD allowedErrors = CERT_TRUST_IS_UNTRUSTED_ROOT | + CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_INVALID_BASIC_CONSTRAINTS | + CERT_TRUST_IS_NOT_TIME_VALID; + + /* The certificate chain verification only allows certain + * invalid CA certs if they're installed locally: CA + * certs missing the key usage extension, and CA certs + * missing the basic constraints extension. Of course + * there's a chicken and egg problem: we have to accept + * them here in order for them to be accepted later. + * Expired, locally installed certs are also allowed here, + * because we don't know (yet) what date will be checked + * for an item signed by one of these certs. + * Thus, accept certs with any of the allowed errors. + */ + if (chain->TrustStatus.dwErrorStatus & ~allowedErrors) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), trust_status_to_str(chain->TrustStatus.dwErrorStatus & ~CERT_TRUST_IS_UNTRUSTED_ROOT)); @@ -705,6 +719,7 @@ static void read_trusted_roots_from_known_locations(HCERTSTORE store) ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE); check_and_store_certs(from, store); } + CertCloseStore(from, 0); } static HCERTSTORE create_root_store(void) diff --git a/reactos/dll/win32/crypt32/serialize.c b/reactos/dll/win32/crypt32/serialize.c index 2cc6ffdb5a1..0c366bf4125 100644 --- a/reactos/dll/win32/crypt32/serialize.c +++ b/reactos/dll/win32/crypt32/serialize.c @@ -425,14 +425,18 @@ const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement, static const BYTE fileHeader[] = { 0, 0, 0, 0, 'C','E','R','T' }; -BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store) +typedef BOOL (*read_serialized_func)(void *handle, void *buffer, + DWORD bytesToRead, DWORD *bytesRead); + +static BOOL CRYPT_ReadSerializedStore(void *handle, + read_serialized_func read_func, HCERTSTORE store) { BYTE fileHeaderBuf[sizeof(fileHeader)]; DWORD read; BOOL ret; /* Failure reading is non-critical, we'll leave the store empty */ - ret = ReadFile(file, fileHeaderBuf, sizeof(fileHeaderBuf), &read, NULL); + ret = read_func(handle, fileHeaderBuf, sizeof(fileHeaderBuf), &read); if (ret) { if (!read) @@ -448,7 +452,7 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store) DWORD bufSize = 0; do { - ret = ReadFile(file, &propHdr, sizeof(propHdr), &read, NULL); + ret = read_func(handle, &propHdr, sizeof(propHdr), &read); if (ret && read == sizeof(propHdr)) { if (contextInterface && context && @@ -470,7 +474,7 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store) } if (buf) { - ret = ReadFile(file, buf, propHdr.cb, &read, NULL); + ret = read_func(handle, buf, propHdr.cb, &read); if (ret && read == propHdr.cb) { if (propHdr.propID == CERT_CERT_PROP_ID) @@ -495,8 +499,18 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store) CERT_STORE_ADD_NEW, &context); } else - ret = CRYPT_ReadContextProp(contextInterface, - context, &propHdr, buf, read); + { + if (!contextInterface) + { + WARN("prop id %d before a context id\n", + propHdr.propID); + ret = FALSE; + } + else + ret = CRYPT_ReadContextProp( + contextInterface, context, &propHdr, buf, + read); + } } } else @@ -519,6 +533,48 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store) return ret; } +static BOOL read_file_wrapper(void *handle, void *buffer, DWORD bytesToRead, + DWORD *bytesRead) +{ + return ReadFile(handle, buffer, bytesToRead, bytesRead, NULL); +} + +BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store) +{ + return CRYPT_ReadSerializedStore(file, read_file_wrapper, store); +} + +struct BlobReader +{ + const CRYPT_DATA_BLOB *blob; + DWORD current; +}; + +static BOOL read_blob_wrapper(void *handle, void *buffer, DWORD bytesToRead, + DWORD *bytesRead) +{ + struct BlobReader *reader = handle; + BOOL ret; + + if (reader->current < reader->blob->cbData) + { + *bytesRead = min(bytesToRead, reader->blob->cbData - reader->current); + memcpy(buffer, reader->blob->pbData + reader->current, *bytesRead); + ret = TRUE; + } + else + ret = FALSE; + return ret; +} + +BOOL CRYPT_ReadSerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob, + HCERTSTORE store) +{ + struct BlobReader reader = { blob, 0 }; + + return CRYPT_ReadSerializedStore(&reader, read_blob_wrapper, store); +} + static BOOL WINAPI CRYPT_SerializeCertNoHash(PCCERT_CONTEXT pCertContext, DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement) { diff --git a/reactos/dll/win32/crypt32/store.c b/reactos/dll/win32/crypt32/store.c index 8acc6f68b12..3a786b05cf4 100644 --- a/reactos/dll/win32/crypt32/store.c +++ b/reactos/dll/win32/crypt32/store.c @@ -184,9 +184,13 @@ static void *CRYPT_MemEnumCert(PWINECRYPT_CERTSTORE store, void *pPrev) static BOOL CRYPT_MemDeleteCert(PWINECRYPT_CERTSTORE store, void *pCertContext) { WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; + BOOL ret; - ContextList_Delete(ms->certs, pCertContext); - return TRUE; + if (ContextList_Remove(ms->certs, pCertContext)) + ret = CertFreeCertificateContext(pCertContext); + else + ret = TRUE; + return ret; } static BOOL CRYPT_MemAddCrl(PWINECRYPT_CERTSTORE store, void *crl, @@ -225,9 +229,13 @@ static void *CRYPT_MemEnumCrl(PWINECRYPT_CERTSTORE store, void *pPrev) static BOOL CRYPT_MemDeleteCrl(PWINECRYPT_CERTSTORE store, void *pCrlContext) { WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; + BOOL ret; - ContextList_Delete(ms->crls, pCrlContext); - return TRUE; + if (ContextList_Remove(ms->crls, pCrlContext)) + ret = CertFreeCRLContext(pCrlContext); + else + ret = TRUE; + return ret; } static BOOL CRYPT_MemAddCtl(PWINECRYPT_CERTSTORE store, void *ctl, @@ -266,9 +274,20 @@ static void *CRYPT_MemEnumCtl(PWINECRYPT_CERTSTORE store, void *pPrev) static BOOL CRYPT_MemDeleteCtl(PWINECRYPT_CERTSTORE store, void *pCtlContext) { WINE_MEMSTORE *ms = (WINE_MEMSTORE *)store; + BOOL ret; - ContextList_Delete(ms->ctls, pCtlContext); - return TRUE; + if (ContextList_Remove(ms->ctls, pCtlContext)) + ret = CertFreeCTLContext(pCtlContext); + else + ret = TRUE; + return ret; +} + +static BOOL WINAPI CRYPT_MemControl(HCERTSTORE hCertStore, DWORD dwFlags, + DWORD dwCtrlType, void const *pvCtrlPara) +{ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } static void WINAPI CRYPT_MemCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) @@ -314,7 +333,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MemOpenStore(HCRYPTPROV hCryptProv, store->hdr.ctls.addContext = CRYPT_MemAddCtl; store->hdr.ctls.enumContext = CRYPT_MemEnumCtl; store->hdr.ctls.deleteContext = CRYPT_MemDeleteCtl; - store->hdr.control = NULL; + store->hdr.control = CRYPT_MemControl; store->certs = ContextList_Create(pCertInterface, sizeof(CERT_CONTEXT)); store->crls = ContextList_Create(pCRLInterface, @@ -966,10 +985,7 @@ BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext) if (!pCertContext) ret = TRUE; else if (!pCertContext->hCertStore) - { - ret = TRUE; - CertFreeCertificateContext(pCertContext); - } + ret = CertFreeCertificateContext(pCertContext); else { PWINECRYPT_CERTSTORE hcs = pCertContext->hCertStore; @@ -979,7 +995,7 @@ BOOL WINAPI CertDeleteCertificateFromStore(PCCERT_CONTEXT pCertContext) else ret = hcs->certs.deleteContext(hcs, (void *)pCertContext); if (ret) - CertFreeCertificateContext(pCertContext); + ret = CertFreeCertificateContext(pCertContext); } return ret; } @@ -1105,10 +1121,7 @@ BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext) if (!pCrlContext) ret = TRUE; else if (!pCrlContext->hCertStore) - { - ret = TRUE; - CertFreeCRLContext(pCrlContext); - } + ret = CertFreeCRLContext(pCrlContext); else { PWINECRYPT_CERTSTORE hcs = pCrlContext->hCertStore; @@ -1117,7 +1130,8 @@ BOOL WINAPI CertDeleteCRLFromStore(PCCRL_CONTEXT pCrlContext) ret = FALSE; else ret = hcs->crls.deleteContext(hcs, (void *)pCrlContext); - CertFreeCRLContext(pCrlContext); + if (ret) + ret = CertFreeCRLContext(pCrlContext); } return ret; } @@ -1161,6 +1175,8 @@ BOOL WINAPI CertCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) if ( hcs->dwMagic != WINE_CRYPTCERTSTORE_MAGIC ) return FALSE; + if (hcs->ref <= 0) + ERR("%p's ref count is %d\n", hcs, hcs->ref); if (InterlockedDecrement(&hcs->ref) == 0) { TRACE("%p's ref count is 0, freeing\n", hcs); diff --git a/reactos/dll/win32/crypt32/str.c b/reactos/dll/win32/crypt32/str.c index b0a3d254a6a..758abc9c072 100644 --- a/reactos/dll/win32/crypt32/str.c +++ b/reactos/dll/win32/crypt32/str.c @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include + +#define NONAMELESSUNION + #include "windef.h" #include "winbase.h" #include "winnls.h" @@ -1017,11 +1020,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, if (entry) { if (!pszNameString) - ret = strlenW(entry->pwszRfc822Name) + 1; + ret = strlenW(entry->u.pwszRfc822Name) + 1; else if (cchNameString) { - ret = min(strlenW(entry->pwszRfc822Name), cchNameString - 1); - memcpy(pszNameString, entry->pwszRfc822Name, + ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1); + memcpy(pszNameString, entry->u.pwszRfc822Name, ret * sizeof(WCHAR)); pszNameString[ret++] = 0; } @@ -1045,7 +1048,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, if (entry) ret = CertNameToStrW(pCertContext->dwCertEncodingType, - &entry->DirectoryName, *(DWORD *)pvTypePara, pszNameString, + &entry->u.DirectoryName, *(DWORD *)pvTypePara, pszNameString, cchNameString); if (info) LocalFree(info); @@ -1062,7 +1065,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, if (entry) ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0, - &entry->DirectoryName, 0, pszNameString, cchNameString); + &entry->u.DirectoryName, 0, pszNameString, cchNameString); if (altInfo) LocalFree(altInfo); } @@ -1102,12 +1105,12 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, if (entry) { if (!pszNameString) - ret = strlenW(entry->pwszRfc822Name) + 1; + ret = strlenW(entry->u.pwszRfc822Name) + 1; else if (cchNameString) { - ret = min(strlenW(entry->pwszRfc822Name), + ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1); - memcpy(pszNameString, entry->pwszRfc822Name, + memcpy(pszNameString, entry->u.pwszRfc822Name, ret * sizeof(WCHAR)); pszNameString[ret++] = 0; } @@ -1139,11 +1142,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, if (entry) { if (!pszNameString) - ret = strlenW(entry->pwszDNSName) + 1; + ret = strlenW(entry->u.pwszDNSName) + 1; else if (cchNameString) { - ret = min(strlenW(entry->pwszDNSName), cchNameString - 1); - memcpy(pszNameString, entry->pwszDNSName, ret * sizeof(WCHAR)); + ret = min(strlenW(entry->u.pwszDNSName), cchNameString - 1); + memcpy(pszNameString, entry->u.pwszDNSName, ret * sizeof(WCHAR)); pszNameString[ret++] = 0; } } @@ -1163,11 +1166,11 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, if (entry) { if (!pszNameString) - ret = strlenW(entry->pwszURL) + 1; + ret = strlenW(entry->u.pwszURL) + 1; else if (cchNameString) { - ret = min(strlenW(entry->pwszURL), cchNameString - 1); - memcpy(pszNameString, entry->pwszURL, ret * sizeof(WCHAR)); + ret = min(strlenW(entry->u.pwszURL), cchNameString - 1); + memcpy(pszNameString, entry->u.pwszURL, ret * sizeof(WCHAR)); pszNameString[ret++] = 0; } } diff --git a/reactos/include/psdk/wincrypt.h b/reactos/include/psdk/wincrypt.h index ae74e9082b9..b98ef794ddc 100644 --- a/reactos/include/psdk/wincrypt.h +++ b/reactos/include/psdk/wincrypt.h @@ -2750,6 +2750,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA #define CRYPT_STRING_BASE64X509CRLHEADER 0x00000009 #define CRYPT_STRING_HEXADDR 0x0000000a #define CRYPT_STRING_HEXASCIIADDR 0x0000000b +#define CRYPT_STRING_NOCRLF 0x40000000 #define CRYPT_STRING_NOCR 0x80000000 /* OIDs */ @@ -2946,6 +2947,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA #define szOID_POLICY_CONSTRAINTS "2.5.29.36" #define szOID_ENHANCED_KEY_USAGE "2.5.29.37" #define szOID_FRESHEST_CRL "2.5.29.46" +#define szOID_INHIBIT_ANY_POLICY "2.5.29.54" #define szOID_DOMAIN_COMPONENT "0.9.2342.19200300.100.1.25" #define szOID_PKCS_12_FRIENDLY_NAME_ATTR "1.2.840.113549.1.9.20" #define szOID_PKCS_12_LOCAL_KEY_ID "1.2.840.113549.1.9.21" @@ -4053,6 +4055,13 @@ BOOL WINAPI CertAddEncodedCertificateToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCertEncoded, DWORD cbCertEncoded, DWORD dwAddDisposition, PCCERT_CONTEXT *ppCertContext); +BOOL WINAPI CertAddEncodedCertificateToSystemStoreA(LPCSTR pszCertStoreName, + const BYTE *pbCertEncoded, DWORD cbCertEncoded); +BOOL WINAPI CertAddEncodedCertificateToSystemStoreW(LPCWSTR pszCertStoreName, + const BYTE *pbCertEncoded, DWORD cbCertEncoded); +#define CertAddEncodedCertificateToSystemStore \ + WINELIB_NAME_AW(CertAddEncodedCertificateToSystemStore) + BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore, DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded, DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext); @@ -4139,6 +4148,9 @@ BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext, BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext, DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement); +BOOL WINAPI CertGetIntendedKeyUsage(DWORD dwCertEncodingType, + PCERT_INFO pCertInfo, BYTE *pbKeyUsage, DWORD cbKeyUsage); + BOOL WINAPI CertGetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, DWORD dwFlags, PCERT_ENHKEY_USAGE pUsage, DWORD *pcbUsage); BOOL WINAPI CertSetEnhancedKeyUsage(PCCERT_CONTEXT pCertContext, From 9cd4c81c17d6c2dfa0bd10f2be6a381958d5784c Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 15 Nov 2009 23:04:51 +0000 Subject: [PATCH 057/140] sync crypt32 winetest with wine 1.1.33 svn path=/trunk/; revision=44185 --- rostests/winetests/crypt32/cert.c | 112 +- rostests/winetests/crypt32/chain.c | 2712 +++++++++++++++++++--- rostests/winetests/crypt32/crl.c | 16 + rostests/winetests/crypt32/ctl.c | 16 + rostests/winetests/crypt32/encode.c | 558 ++++- rostests/winetests/crypt32/oid.c | 8 - rostests/winetests/crypt32/protectdata.c | 36 + rostests/winetests/crypt32/sip.c | 6 +- rostests/winetests/crypt32/store.c | 160 +- 9 files changed, 3251 insertions(+), 373 deletions(-) diff --git a/rostests/winetests/crypt32/cert.c b/rostests/winetests/crypt32/cert.c index 322fa2f92d9..e1c826254ac 100644 --- a/rostests/winetests/crypt32/cert.c +++ b/rostests/winetests/crypt32/cert.c @@ -1015,6 +1015,10 @@ static void testFindCert(void) CERT_INFO certInfo = { 0 }; CRYPT_HASH_BLOB blob; BYTE otherSerialNumber[] = { 2 }; + DWORD count; + static const WCHAR juan[] = { 'j','u','a','n',0 }; + static const WCHAR lang[] = { 'L','A','N','G',0 }; + static const WCHAR malcolm[] = { 'm','a','l','c','o','l','m',0 }; store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); @@ -1085,7 +1089,7 @@ static void testFindCert(void) * the issuer, not the subject */ context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, - CERT_FIND_SUBJECT_CERT, &certInfo.Subject, NULL); + CERT_FIND_SUBJECT_CERT, &certInfo, NULL); ok(context == NULL, "Expected no certificate\n"); certInfo.Subject.pbData = NULL; certInfo.Subject.cbData = 0; @@ -1098,7 +1102,7 @@ static void testFindCert(void) if (context) { context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, - CERT_FIND_SUBJECT_CERT, &certInfo.Subject, context); + CERT_FIND_SUBJECT_CERT, &certInfo, context); ok(context == NULL, "Expected one cert only\n"); } /* A non-matching serial number will not match. */ @@ -1135,6 +1139,41 @@ static void testFindCert(void) ok(context == NULL, "Expected one cert only\n"); } + /* Searching for NULL string matches any context. */ + count = 0; + context = NULL; + do { + context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, + CERT_FIND_ISSUER_STR, NULL, context); + if (context) + count++; + } while (context); + ok(count == 3, "expected 3 contexts\n"); + count = 0; + context = NULL; + do { + context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, + CERT_FIND_ISSUER_STR, juan, context); + if (context) + count++; + } while (context); + ok(count == 2, "expected 2 contexts\n"); + count = 0; + context = NULL; + do { + context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, + CERT_FIND_ISSUER_STR, lang, context); + if (context) + count++; + } while (context); + ok(count == 3, "expected 3 contexts\n"); + SetLastError(0xdeadbeef); + context = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, + CERT_FIND_ISSUER_STR, malcolm, NULL); + ok(!context, "expected no certs\n"); + ok(GetLastError() == CRYPT_E_NOT_FOUND, + "expected CRYPT_E_NOT_FOUND, got %08x\n", GetLastError()); + CertCloseStore(store, 0); /* Another subject cert search, using iTunes's certs */ @@ -1624,12 +1663,14 @@ static void testSignCert(HCRYPTPROV csp, const CRYPT_DATA_BLOB *toBeSigned, algoID.pszObjId = (LPSTR)sigOID; ret = CryptSignCertificate(0, 0, 0, toBeSigned->pbData, toBeSigned->cbData, &algoID, NULL, NULL, &size); - ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID), + ok(!ret && + (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_ALGID), "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", GetLastError()); ret = CryptSignCertificate(0, AT_SIGNATURE, 0, toBeSigned->pbData, toBeSigned->cbData, &algoID, NULL, NULL, &size); - ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID), + ok(!ret && + (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == NTE_BAD_ALGID), "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", GetLastError()); @@ -1851,7 +1892,10 @@ static void testSignAndEncodeCert(void) algID.pszObjId = oid_rsa_md5rsa; ret = CryptSignAndEncodeCertificate(0, 0, X509_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, &info, &algID, NULL, NULL, &size); - ok(!ret && (GetLastError() == ERROR_INVALID_PARAMETER || NTE_BAD_ALGID), + ok(!ret && + (GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == NTE_BAD_ALGID || + GetLastError() == OSS_BAD_PTR), /* Win9x */ "Expected ERROR_INVALID_PARAMETER or NTE_BAD_ALGID, got %08x\n", GetLastError()); algID.pszObjId = oid_rsa_md5; @@ -2021,6 +2065,54 @@ static void testCreateSelfSignCert(void) CRYPT_DELETEKEYSET); } +static void testIntendedKeyUsage(void) +{ + BOOL ret; + CERT_INFO info = { 0 }; + static char oid_key_usage[] = szOID_KEY_USAGE; + /* A couple "key usages". Really they're just encoded bits which aren't + * necessarily restricted to the defined key usage values. + */ + static BYTE usage1[] = { 0x03,0x03,0x00,0xff,0xff }; + static BYTE usage2[] = { 0x03,0x03,0x01,0xff,0xfe }; + static const BYTE expected_usage1[] = { 0xff,0xff,0x00,0x00 }; + static const BYTE expected_usage2[] = { 0xff,0xfe,0x00,0x00 }; + CERT_EXTENSION ext = { oid_key_usage, TRUE, { sizeof(usage1), usage1 } }; + BYTE usage_bytes[4]; + + if (0) + { + /* Crash */ + ret = CertGetIntendedKeyUsage(0, NULL, NULL, 0); + } + ret = CertGetIntendedKeyUsage(0, &info, NULL, 0); + ok(!ret, "expected failure\n"); + ret = CertGetIntendedKeyUsage(0, &info, usage_bytes, sizeof(usage_bytes)); + ok(!ret, "expected failure\n"); + ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, NULL, 0); + ok(!ret, "expected failure\n"); + ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes, + sizeof(usage_bytes)); + info.cExtension = 1; + info.rgExtension = &ext; + ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, NULL, 0); + ok(!ret, "expected failure\n"); + /* The unused bytes are filled with 0. */ + ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes, + sizeof(usage_bytes)); + ok(ret, "CertGetIntendedKeyUsage failed: %08x\n", GetLastError()); + ok(!memcmp(usage_bytes, expected_usage1, sizeof(expected_usage1)), + "unexpected value\n"); + /* The usage bytes are copied in big-endian order. */ + ext.Value.cbData = sizeof(usage2); + ext.Value.pbData = usage2; + ret = CertGetIntendedKeyUsage(X509_ASN_ENCODING, &info, usage_bytes, + sizeof(usage_bytes)); + ok(ret, "CertGetIntendedKeyUsage failed: %08x\n", GetLastError()); + ok(!memcmp(usage_bytes, expected_usage2, sizeof(expected_usage2)), + "unexpected value\n"); +} + static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING, szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA }; @@ -3138,7 +3230,8 @@ static void testGetPublicKeyLength(void) ret, GetLastError()); SetLastError(0xdeadbeef); ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); - ok(ret == 56, "Expected length 56, got %d\n", ret); + ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */, + "Expected length 56, got %d\n", ret); /* An RSA key with the DH OID */ info.Algorithm.pszObjId = oid_rsa_dh; SetLastError(0xdeadbeef); @@ -3152,12 +3245,14 @@ static void testGetPublicKeyLength(void) info.Algorithm.pszObjId = oid_rsa_rsa; SetLastError(0xdeadbeef); ret = CertGetPublicKeyLength(X509_ASN_ENCODING, &info); - ok(ret == 56, "Expected length 56, got %d\n", ret); + ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */, + "Expected length 56, got %d\n", ret); /* With the RSA OID and a message encoding */ info.Algorithm.pszObjId = oid_rsa_rsa; SetLastError(0xdeadbeef); ret = CertGetPublicKeyLength(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &info); - ok(ret == 56, "Expected length 56, got %d\n", ret); + ok(ret == 56 || broken(ret == 0 && GetLastError() == NTE_BAD_LEN) /* Win7 */, + "Expected length 56, got %d\n", ret); } START_TEST(cert) @@ -3175,6 +3270,7 @@ START_TEST(cert) testCertSigs(); testSignAndEncodeCert(); testCreateSelfSignCert(); + testIntendedKeyUsage(); testKeyUsage(); testGetValidUsages(); testCompareCertName(); diff --git a/rostests/winetests/crypt32/chain.c b/rostests/winetests/crypt32/chain.c index c880df95443..be3a0bddc3b 100644 --- a/rostests/winetests/crypt32/chain.c +++ b/rostests/winetests/crypt32/chain.c @@ -75,10 +75,8 @@ static void testCreateCertChainEngine(void) /* Crash ret = pCertCreateCertificateChainEngine(NULL, NULL); ret = pCertCreateCertificateChainEngine(NULL, &engine); - */ ret = pCertCreateCertificateChainEngine(&config, NULL); - ok(!ret && GetLastError() == E_INVALIDARG, - "Expected E_INVALIDARG, got %08x\n", GetLastError()); + */ ret = pCertCreateCertificateChainEngine(&config, &engine); ok(!ret && GetLastError() == E_INVALIDARG, "Expected E_INVALIDARG, got %08x\n", GetLastError()); @@ -126,142 +124,6 @@ static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 }; static const BYTE iTunesCert0[] = { -0x30,0x82,0x03,0xc4,0x30,0x82,0x03,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0x47,0xbf,0x19,0x95,0xdf,0x8d,0x52,0x46,0x43,0xf7,0xdb,0x6d,0x48,0x0d,0x31, -0xa4,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, -0x00,0x30,0x81,0x8b,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x5a,0x41,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x08,0x13,0x0c,0x57,0x65, -0x73,0x74,0x65,0x72,0x6e,0x20,0x43,0x61,0x70,0x65,0x31,0x14,0x30,0x12,0x06, -0x03,0x55,0x04,0x07,0x13,0x0b,0x44,0x75,0x72,0x62,0x61,0x6e,0x76,0x69,0x6c, -0x6c,0x65,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x54,0x68, -0x61,0x77,0x74,0x65,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14, -0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, -0x61,0x74,0x69,0x6f,0x6e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x03,0x13, -0x16,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x54,0x69,0x6d,0x65,0x73,0x74,0x61, -0x6d,0x70,0x69,0x6e,0x67,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x33,0x31, -0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x33,0x31, -0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x53,0x31,0x0b,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06, -0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c, -0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13, -0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69,0x6d,0x65,0x20, -0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72,0x76,0x69,0x63, -0x65,0x73,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86, -0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30, -0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa9,0xca,0xb2,0xa4,0xcc,0xcd,0x20, -0xaf,0x0a,0x7d,0x89,0xac,0x87,0x75,0xf0,0xb4,0x4e,0xf1,0xdf,0xc1,0x0f,0xbf, -0x67,0x61,0xbd,0xa3,0x64,0x1c,0xda,0xbb,0xf9,0xca,0x33,0xab,0x84,0x30,0x89, -0x58,0x7e,0x8c,0xdb,0x6b,0xdd,0x36,0x9e,0x0f,0xbf,0xd1,0xec,0x78,0xf2,0x77, -0xa6,0x7e,0x6f,0x3c,0xbf,0x93,0xaf,0x0d,0xba,0x68,0xf4,0x6c,0x94,0xca,0xbd, -0x52,0x2d,0xab,0x48,0x3d,0xf5,0xb6,0xd5,0x5d,0x5f,0x1b,0x02,0x9f,0xfa,0x2f, -0x6b,0x1e,0xa4,0xf7,0xa3,0x9a,0xa6,0x1a,0xc8,0x02,0xe1,0x7f,0x4c,0x52,0xe3, -0x0e,0x60,0xec,0x40,0x1c,0x7e,0xb9,0x0d,0xde,0x3f,0xc7,0xb4,0xdf,0x87,0xbd, -0x5f,0x7a,0x6a,0x31,0x2e,0x03,0x99,0x81,0x13,0xa8,0x47,0x20,0xce,0x31,0x73, -0x0d,0x57,0x2d,0xcd,0x78,0x34,0x33,0x95,0x12,0x99,0x12,0xb9,0xde,0x68,0x2f, -0xaa,0xe6,0xe3,0xc2,0x8a,0x8c,0x2a,0xc3,0x8b,0x21,0x87,0x66,0xbd,0x83,0x58, -0x57,0x6f,0x75,0xbf,0x3c,0xaa,0x26,0x87,0x5d,0xca,0x10,0x15,0x3c,0x9f,0x84, -0xea,0x54,0xc1,0x0a,0x6e,0xc4,0xfe,0xc5,0x4a,0xdd,0xb9,0x07,0x11,0x97,0x22, -0x7c,0xdb,0x3e,0x27,0xd1,0x1e,0x78,0xec,0x9f,0x31,0xc9,0xf1,0xe6,0x22,0x19, -0xdb,0xc4,0xb3,0x47,0x43,0x9a,0x1a,0x5f,0xa0,0x1e,0x90,0xe4,0x5e,0xf5,0xee, -0x7c,0xf1,0x7d,0xab,0x62,0x01,0x8f,0xf5,0x4d,0x0b,0xde,0xd0,0x22,0x56,0xa8, -0x95,0xcd,0xae,0x88,0x76,0xae,0xee,0xba,0x0d,0xf3,0xe4,0x4d,0xd9,0xa0,0xfb, -0x68,0xa0,0xae,0x14,0x3b,0xb3,0x87,0xc1,0xbb,0x02,0x03,0x01,0x00,0x01,0xa3, -0x81,0xdb,0x30,0x81,0xd8,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07, -0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05, -0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73, -0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30, -0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01, -0xff,0x02,0x01,0x00,0x30,0x41,0x06,0x03,0x55,0x1d,0x1f,0x04,0x3a,0x30,0x38, -0x30,0x36,0xa0,0x34,0xa0,0x32,0x86,0x30,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, -0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f, -0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x54,0x69,0x6d,0x65,0x73,0x74,0x61, -0x6d,0x70,0x69,0x6e,0x67,0x43,0x41,0x2e,0x63,0x72,0x6c,0x30,0x13,0x06,0x03, -0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07, -0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03, -0x02,0x01,0x06,0x30,0x24,0x06,0x03,0x55,0x1d,0x11,0x04,0x1d,0x30,0x1b,0xa4, -0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x13,0x0c,0x54, -0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35,0x33,0x30,0x0d,0x06,0x09, -0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00, -0x4a,0x6b,0xf9,0xea,0x58,0xc2,0x44,0x1c,0x31,0x89,0x79,0x99,0x2b,0x96,0xbf, -0x82,0xac,0x01,0xd6,0x1c,0x4c,0xcd,0xb0,0x8a,0x58,0x6e,0xdf,0x08,0x29,0xa3, -0x5e,0xc8,0xca,0x93,0x13,0xe7,0x04,0x52,0x0d,0xef,0x47,0x27,0x2f,0x00,0x38, -0xb0,0xe4,0xc9,0x93,0x4e,0x9a,0xd4,0x22,0x62,0x15,0xf7,0x3f,0x37,0x21,0x4f, -0x70,0x31,0x80,0xf1,0x8b,0x38,0x87,0xb3,0xe8,0xe8,0x97,0x00,0xfe,0xcf,0x55, -0x96,0x4e,0x24,0xd2,0xa9,0x27,0x4e,0x7a,0xae,0xb7,0x61,0x41,0xf3,0x2a,0xce, -0xe7,0xc9,0xd9,0x5e,0xdd,0xbb,0x2b,0x85,0x3e,0xb5,0x9d,0xb5,0xd9,0xe1,0x57, -0xff,0xbe,0xb4,0xc5,0x7e,0xf5,0xcf,0x0c,0x9e,0xf0,0x97,0xfe,0x2b,0xd3,0x3b, -0x52,0x1b,0x1b,0x38,0x27,0xf7,0x3f,0x4a }; -static const BYTE iTunesCert1[] = { -0x30,0x82,0x03,0xff,0x30,0x82,0x02,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0x0d,0xe9,0x2b,0xf0,0xd4,0xd8,0x29,0x88,0x18,0x32,0x05,0x09,0x5e,0x9a,0x76, -0x88,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, -0x00,0x30,0x53,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72, -0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2b,0x30,0x29, -0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e, -0x20,0x54,0x69,0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20, -0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d, -0x30,0x33,0x31,0x32,0x30,0x34,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d, -0x30,0x38,0x31,0x32,0x30,0x33,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x57, -0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, -0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69, -0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x2f,0x30,0x2d,0x06,0x03,0x55, -0x04,0x03,0x13,0x26,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x69, -0x6d,0x65,0x20,0x53,0x74,0x61,0x6d,0x70,0x69,0x6e,0x67,0x20,0x53,0x65,0x72, -0x76,0x69,0x63,0x65,0x73,0x20,0x53,0x69,0x67,0x6e,0x65,0x72,0x30,0x82,0x01, -0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05, -0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00, -0xb2,0x50,0x28,0x48,0xdd,0xd3,0x68,0x7a,0x84,0x18,0x44,0x66,0x75,0x5d,0x7e, -0xc4,0xb8,0x9f,0x63,0x26,0xff,0x3d,0x43,0x9c,0x7c,0x11,0x38,0x10,0x25,0x55, -0x73,0xd9,0x75,0x27,0x69,0xfd,0x4e,0xb9,0x20,0x5c,0xd3,0x0a,0xf9,0xa0,0x1b, -0x2a,0xed,0x55,0x56,0x21,0x61,0xd8,0x1e,0xdb,0xe4,0xbc,0x33,0x6b,0xc7,0xef, -0xdd,0xa3,0x37,0x65,0x8e,0x1b,0x93,0x0c,0xb6,0x53,0x1e,0x5c,0x7c,0x66,0x35, -0x5f,0x05,0x8a,0x45,0xfe,0x76,0x4e,0xdf,0x53,0x80,0xa2,0x81,0x20,0x9d,0xae, -0x88,0x5c,0xa2,0x08,0xf7,0xe5,0x30,0xf9,0xee,0x22,0x37,0x4c,0x42,0x0a,0xce, -0xdf,0xc6,0x1f,0xc4,0xd6,0x55,0xe9,0x81,0x3f,0xb5,0x52,0xa3,0x2c,0xaa,0x01, -0x7a,0xf2,0xa2,0xaa,0x8d,0x35,0xfe,0x9f,0xe6,0x5d,0x6a,0x05,0x9f,0x3d,0x6b, -0xe3,0xbf,0x96,0xc0,0xfe,0xcc,0x60,0xf9,0x40,0xe7,0x07,0xa0,0x44,0xeb,0x81, -0x51,0x6e,0xa5,0x2a,0xf2,0xb6,0x8a,0x10,0x28,0xed,0x8f,0xdc,0x06,0xa0,0x86, -0x50,0x9a,0x7b,0x4a,0x08,0x0d,0x30,0x1d,0xca,0x10,0x9e,0x6b,0xf7,0xe9,0x58, -0xae,0x04,0xa9,0x40,0x99,0xb2,0x28,0xe8,0x8f,0x16,0xac,0x3c,0xe3,0x53,0x6f, -0x4b,0xd3,0x35,0x9d,0xb5,0x6f,0x64,0x1d,0xb3,0x96,0x2c,0xbb,0x3d,0xe7,0x79, -0xeb,0x6d,0x7a,0xf9,0x16,0xe6,0x26,0xad,0xaf,0xef,0x99,0x53,0xb7,0x40,0x2c, -0x95,0xb8,0x79,0xaa,0xfe,0xd4,0x52,0xab,0x29,0x74,0x7e,0x42,0xec,0x39,0x1e, -0xa2,0x6a,0x16,0xe6,0x59,0xbb,0x24,0x68,0xd8,0x00,0x80,0x43,0x10,0x87,0x80, -0x6b,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xca,0x30,0x81,0xc7,0x30,0x34,0x06, -0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x28,0x30,0x26,0x30,0x24, -0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x18,0x68,0x74,0x74, -0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x76,0x65,0x72,0x69,0x73,0x69, -0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01, -0xff,0x04,0x02,0x30,0x00,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30, -0x2a,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f, -0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63, -0x6f,0x6d,0x2f,0x74,0x73,0x73,0x2d,0x63,0x61,0x2e,0x63,0x72,0x6c,0x30,0x16, -0x06,0x03,0x55,0x1d,0x25,0x01,0x01,0xff,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b, -0x06,0x01,0x05,0x05,0x07,0x03,0x08,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01, -0x01,0xff,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x24,0x06,0x03,0x55,0x1d,0x11, -0x04,0x1d,0x30,0x1b,0xa4,0x19,0x30,0x17,0x31,0x15,0x30,0x13,0x06,0x03,0x55, -0x04,0x03,0x13,0x0c,0x54,0x53,0x41,0x32,0x30,0x34,0x38,0x2d,0x31,0x2d,0x35, -0x34,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, -0x00,0x03,0x82,0x01,0x01,0x00,0x87,0x78,0x70,0xda,0x4e,0x52,0x01,0x20,0x5b, -0xe0,0x79,0xc9,0x82,0x30,0xc4,0xfd,0xb9,0x19,0x96,0xbd,0x91,0x00,0xc3,0xbd, -0xcd,0xcd,0xc6,0xf4,0x0e,0xd8,0xff,0xf9,0x4d,0xc0,0x33,0x62,0x30,0x11,0xc5, -0xf5,0x74,0x1b,0xd4,0x92,0xde,0x5f,0x9c,0x20,0x13,0xb1,0x7c,0x45,0xbe,0x50, -0xcd,0x83,0xe7,0x80,0x17,0x83,0xa7,0x27,0x93,0x67,0x13,0x46,0xfb,0xca,0xb8, -0x98,0x41,0x03,0xcc,0x9b,0x51,0x5b,0x05,0x8b,0x7f,0xa8,0x6f,0xf3,0x1b,0x50, -0x1b,0x24,0x2e,0xf2,0x69,0x8d,0x6c,0x22,0xf7,0xbb,0xca,0x16,0x95,0xed,0x0c, -0x74,0xc0,0x68,0x77,0xd9,0xeb,0x99,0x62,0x87,0xc1,0x73,0x90,0xf8,0x89,0x74, -0x7a,0x23,0xab,0xa3,0x98,0x7b,0x97,0xb1,0xf7,0x8f,0x29,0x71,0x4d,0x2e,0x75, -0x1b,0x48,0x41,0xda,0xf0,0xb5,0x0d,0x20,0x54,0xd6,0x77,0xa0,0x97,0x82,0x63, -0x69,0xfd,0x09,0xcf,0x8a,0xf0,0x75,0xbb,0x09,0x9b,0xd9,0xf9,0x11,0x55,0x26, -0x9a,0x61,0x32,0xbe,0x7a,0x02,0xb0,0x7b,0x86,0xbe,0xa2,0xc3,0x8b,0x22,0x2c, -0x78,0xd1,0x35,0x76,0xbc,0x92,0x73,0x5c,0xf9,0xb9,0xe6,0x4c,0x15,0x0a,0x23, -0xcc,0xe4,0xd2,0xd4,0x34,0x2e,0x49,0x40,0x15,0x3c,0x0f,0x60,0x7a,0x24,0xc6, -0xa5,0x66,0xef,0x96,0xcf,0x70,0xeb,0x3e,0xe7,0xf4,0x0d,0x7e,0xdc,0xd1,0x7c, -0xa3,0x76,0x71,0x69,0xc1,0x9c,0x4f,0x47,0x30,0x35,0x21,0xb1,0xa2,0xaf,0x1a, -0x62,0x3c,0x2b,0xd9,0x8e,0xaa,0x2a,0x07,0x7b,0xd8,0x18,0xb3,0x5c,0x7b,0xe2, -0x9d,0xa5,0x6f,0xfe,0x3c,0x89,0xad }; -static const BYTE iTunesCert2[] = { 0x30,0x82,0x04,0xbf,0x30,0x82,0x04,0x28,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 0x41,0x91,0xa1,0x5a,0x39,0x78,0xdf,0xcf,0x49,0x65,0x66,0x38,0x1d,0x4c,0x75, 0xc2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, @@ -344,7 +206,7 @@ static const BYTE iTunesCert2[] = { 0x6c,0x52,0x4f,0x91,0x75,0x55,0x8a,0xba,0x22,0xf2,0xd2,0xea,0x41,0x75,0x88, 0x2f,0x63,0x55,0x7d,0x1e,0x54,0x5a,0x95,0x59,0xca,0xd9,0x34,0x81,0xc0,0x5f, 0x5e,0xf6,0x7a,0xb5 }; -static const BYTE iTunesCert3[] = { +static const BYTE iTunesCert1[] = { 0x30,0x82,0x04,0xf1,0x30,0x82,0x03,0xd9,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, 0x0f,0x1a,0xa0,0xe0,0x9b,0x9b,0x61,0xa6,0xb6,0xfe,0x40,0xd2,0xdf,0x6a,0xf6, 0x8d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, @@ -470,20 +332,613 @@ static const BYTE verisignCA[] = { 0xbb,0x10,0xa4,0x3d,0xf0,0x32,0x03,0x0e,0xf1,0xce,0xf8,0xe8,0xc9,0x51,0x8c, 0xe6,0x62,0x9f,0xe6,0x9f,0xc0,0x7d,0xb7,0x72,0x9c,0xc9,0x36,0x3a,0x6b,0x9f, 0x4e,0xa8,0xff,0x64,0x0d,0x64 }; +/* www.google.com's cert */ +static const BYTE google[] = { +0x30,0x82,0x03,0x21,0x30,0x82,0x02,0x8a,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9,0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e, +0x7a,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x4c,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x5a, +0x41,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0a,0x13,0x1c,0x54,0x68,0x61, +0x77,0x74,0x65,0x20,0x43,0x6f,0x6e,0x73,0x75,0x6c,0x74,0x69,0x6e,0x67,0x20, +0x28,0x50,0x74,0x79,0x29,0x20,0x4c,0x74,0x64,0x2e,0x31,0x16,0x30,0x14,0x06, +0x03,0x55,0x04,0x03,0x13,0x0d,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x53,0x47, +0x43,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x39,0x30,0x33,0x32,0x37,0x32, +0x32,0x32,0x30,0x30,0x37,0x5a,0x17,0x0d,0x31,0x30,0x30,0x33,0x32,0x37,0x32, +0x32,0x32,0x30,0x30,0x37,0x5a,0x30,0x68,0x31,0x0b,0x30,0x09,0x06,0x03,0x55, +0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08, +0x13,0x0a,0x43,0x61,0x6c,0x69,0x66,0x6f,0x72,0x6e,0x69,0x61,0x31,0x16,0x30, +0x14,0x06,0x03,0x55,0x04,0x07,0x13,0x0d,0x4d,0x6f,0x75,0x6e,0x74,0x61,0x69, +0x6e,0x20,0x56,0x69,0x65,0x77,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0a, +0x13,0x0a,0x47,0x6f,0x6f,0x67,0x6c,0x65,0x20,0x49,0x6e,0x63,0x31,0x17,0x30, +0x15,0x06,0x03,0x55,0x04,0x03,0x13,0x0e,0x77,0x77,0x77,0x2e,0x67,0x6f,0x6f, +0x67,0x6c,0x65,0x2e,0x63,0x6f,0x6d,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30, +0x81,0x89,0x02,0x81,0x81,0x00,0xd6,0xb9,0xe1,0xad,0xb8,0x61,0x0b,0x1f,0x4e, +0xb6,0x3c,0x09,0x3d,0xab,0xe8,0xe3,0x2b,0xb6,0xe8,0xa4,0x3a,0x78,0x2f,0xd3, +0x51,0x20,0x22,0x45,0x95,0xd8,0x00,0x91,0x33,0x9a,0xa7,0xa2,0x48,0xea,0x30, +0x57,0x26,0x97,0x66,0xc7,0x5a,0xef,0xf1,0x9b,0x0c,0x3f,0xe1,0xb9,0x7f,0x7b, +0xc3,0xc7,0xcc,0xaf,0x9c,0xd0,0x1f,0x3c,0x81,0x15,0x10,0x58,0xfc,0x06,0xb3, +0xbf,0xbc,0x9c,0x02,0xb9,0x51,0xdc,0xfb,0xa6,0xb9,0x17,0x42,0xe6,0x46,0xe7, +0x22,0xcf,0x6c,0x27,0x10,0xfe,0x54,0xe6,0x92,0x6c,0x0c,0x60,0x76,0x9a,0xce, +0xf8,0x7f,0xac,0xb8,0x5a,0x08,0x4a,0xdc,0xb1,0x64,0xbd,0xa0,0x74,0x41,0xb2, +0xac,0x8f,0x86,0x9d,0x1a,0xde,0x58,0x09,0xfd,0x6c,0x0a,0x25,0xe0,0x79,0x02, +0x03,0x01,0x00,0x01,0xa3,0x81,0xe7,0x30,0x81,0xe4,0x30,0x28,0x06,0x03,0x55, +0x1d,0x25,0x04,0x21,0x30,0x1f,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03, +0x01,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x60,0x86, +0x48,0x01,0x86,0xf8,0x42,0x04,0x01,0x30,0x36,0x06,0x03,0x55,0x1d,0x1f,0x04, +0x2f,0x30,0x2d,0x30,0x2b,0xa0,0x29,0xa0,0x27,0x86,0x25,0x68,0x74,0x74,0x70, +0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,0x74,0x68,0x61,0x77,0x74,0x65,0x2e,0x63, +0x6f,0x6d,0x2f,0x54,0x68,0x61,0x77,0x74,0x65,0x53,0x47,0x43,0x43,0x41,0x2e, +0x63,0x72,0x6c,0x30,0x72,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01, +0x04,0x66,0x30,0x64,0x30,0x22,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30, +0x01,0x86,0x16,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e, +0x74,0x68,0x61,0x77,0x74,0x65,0x2e,0x63,0x6f,0x6d,0x30,0x3e,0x06,0x08,0x2b, +0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x32,0x68,0x74,0x74,0x70,0x3a,0x2f, +0x2f,0x77,0x77,0x77,0x2e,0x74,0x68,0x61,0x77,0x74,0x65,0x2e,0x63,0x6f,0x6d, +0x2f,0x72,0x65,0x70,0x6f,0x73,0x69,0x74,0x6f,0x72,0x79,0x2f,0x54,0x68,0x61, +0x77,0x74,0x65,0x5f,0x53,0x47,0x43,0x5f,0x43,0x41,0x2e,0x63,0x72,0x74,0x30, +0x0c,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x02,0x30,0x00,0x30,0x0d, +0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81, +0x81,0x00,0x39,0xb6,0xfb,0x11,0xbc,0x33,0x2c,0xc3,0x90,0x48,0xe3,0x6e,0xc3, +0x9b,0x38,0xb1,0x42,0xd1,0x00,0x09,0x58,0x63,0xa0,0xe1,0x98,0x1c,0x85,0xf2, +0xef,0x10,0x1d,0x60,0x4e,0x51,0x09,0x62,0xf5,0x05,0xbd,0x9d,0x4f,0x87,0x6c, +0x98,0x72,0x07,0x80,0xc3,0x59,0x48,0x14,0xe2,0xd6,0xef,0xd0,0x8f,0x33,0x6a, +0x68,0x31,0xfa,0xb7,0xbb,0x85,0xcc,0xf7,0xc7,0x47,0x7b,0x67,0x93,0x3c,0xc3, +0x16,0x51,0x9b,0x6f,0x87,0x20,0xfd,0x67,0x4c,0x2b,0xea,0x6a,0x49,0xdb,0x11, +0xd1,0xbd,0xd7,0x95,0x22,0x43,0x7a,0x06,0x7b,0x4e,0xf6,0x37,0x8e,0xa2,0xb9, +0xcf,0x1f,0xa5,0xd2,0xbd,0x3b,0x04,0x97,0x39,0xb3,0x0f,0xfa,0x38,0xb5,0xaf, +0x55,0x20,0x88,0x60,0x93,0xf2,0xde,0xdb,0xff,0xdf }; +static const BYTE thawte_sgc_ca[] = { +0x30,0x82,0x03,0x23,0x30,0x82,0x02,0x8c,0xa0,0x03,0x02,0x01,0x02,0x02,0x04, +0x30,0x00,0x00,0x02,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x05,0x05,0x00,0x30,0x5f,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06, +0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e, +0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31, +0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x0b,0x13,0x2e,0x43,0x6c,0x61,0x73,0x73, +0x20,0x33,0x20,0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61, +0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f, +0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d, +0x30,0x34,0x30,0x35,0x31,0x33,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d, +0x31,0x34,0x30,0x35,0x31,0x32,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x4c, +0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x5a,0x41,0x31,0x25, +0x30,0x23,0x06,0x03,0x55,0x04,0x0a,0x13,0x1c,0x54,0x68,0x61,0x77,0x74,0x65, +0x20,0x43,0x6f,0x6e,0x73,0x75,0x6c,0x74,0x69,0x6e,0x67,0x20,0x28,0x50,0x74, +0x79,0x29,0x20,0x4c,0x74,0x64,0x2e,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04, +0x03,0x13,0x0d,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x53,0x47,0x43,0x20,0x43, +0x41,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00, +0xd4,0xd3,0x67,0xd0,0x8d,0x15,0x7f,0xae,0xcd,0x31,0xfe,0x7d,0x1d,0x91,0xa1, +0x3f,0x0b,0x71,0x3c,0xac,0xcc,0xc8,0x64,0xfb,0x63,0xfc,0x32,0x4b,0x07,0x94, +0xbd,0x6f,0x80,0xba,0x2f,0xe1,0x04,0x93,0xc0,0x33,0xfc,0x09,0x33,0x23,0xe9, +0x0b,0x74,0x2b,0x71,0xc4,0x03,0xc6,0xd2,0xcd,0xe2,0x2f,0xf5,0x09,0x63,0xcd, +0xff,0x48,0xa5,0x00,0xbf,0xe0,0xe7,0xf3,0x88,0xb7,0x2d,0x32,0xde,0x98,0x36, +0xe6,0x0a,0xad,0x00,0x7b,0xc4,0x64,0x4a,0x3b,0x84,0x75,0x03,0xf2,0x70,0x92, +0x7d,0x0e,0x62,0xf5,0x21,0xab,0x69,0x36,0x84,0x31,0x75,0x90,0xf8,0xbf,0xc7, +0x6c,0x88,0x1b,0x06,0x95,0x7c,0xc9,0xe5,0xa8,0xde,0x75,0xa1,0x2c,0x7a,0x68, +0xdf,0xd5,0xca,0x1c,0x87,0x58,0x60,0x19,0x02,0x03,0x01,0x00,0x01,0xa3,0x81, +0xfe,0x30,0x81,0xfb,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, +0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,0x0b,0x06,0x03,0x55,0x1d, +0x0f,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01, +0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x28,0x06,0x03, +0x55,0x1d,0x11,0x04,0x21,0x30,0x1f,0xa4,0x1d,0x30,0x1b,0x31,0x19,0x30,0x17, +0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x4c, +0x61,0x62,0x65,0x6c,0x33,0x2d,0x31,0x35,0x30,0x31,0x06,0x03,0x55,0x1d,0x1f, +0x04,0x2a,0x30,0x28,0x30,0x26,0xa0,0x24,0xa0,0x22,0x86,0x20,0x68,0x74,0x74, +0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67, +0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,0x61,0x33,0x2e,0x63,0x72,0x6c,0x30, +0x32,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x26,0x30,0x24, +0x30,0x22,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x16,0x68, +0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x74,0x68,0x61,0x77, +0x74,0x65,0x2e,0x63,0x6f,0x6d,0x30,0x34,0x06,0x03,0x55,0x1d,0x25,0x04,0x2d, +0x30,0x2b,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x08,0x2b, +0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8, +0x42,0x04,0x01,0x06,0x0a,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x08,0x01, +0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00, +0x03,0x81,0x81,0x00,0x55,0xac,0x63,0xea,0xde,0xa1,0xdd,0xd2,0x90,0x5f,0x9f, +0x0b,0xce,0x76,0xbe,0x13,0x51,0x8f,0x93,0xd9,0x05,0x2b,0xc8,0x1b,0x77,0x4b, +0xad,0x69,0x50,0xa1,0xee,0xde,0xdc,0xfd,0xdb,0x07,0xe9,0xe8,0x39,0x94,0xdc, +0xab,0x72,0x79,0x2f,0x06,0xbf,0xab,0x81,0x70,0xc4,0xa8,0xed,0xea,0x53,0x34, +0xed,0xef,0x1e,0x53,0xd9,0x06,0xc7,0x56,0x2b,0xd1,0x5c,0xf4,0xd1,0x8a,0x8e, +0xb4,0x2b,0xb1,0x37,0x90,0x48,0x08,0x42,0x25,0xc5,0x3e,0x8a,0xcb,0x7f,0xeb, +0x6f,0x04,0xd1,0x6d,0xc5,0x74,0xa2,0xf7,0xa2,0x7c,0x7b,0x60,0x3c,0x77,0xcd, +0x0e,0xce,0x48,0x02,0x7f,0x01,0x2f,0xb6,0x9b,0x37,0xe0,0x2a,0x2a,0x36,0xdc, +0xd5,0x85,0xd6,0xac,0xe5,0x3f,0x54,0x6f,0x96,0x1e,0x05,0xaf }; +/* global_sign_root -> global_sign_ca -> openssl_org: + * "*.openssl.org"'s certificate + */ +static const BYTE global_sign_root[] = { +0x30,0x82,0x04,0x6e,0x30,0x82,0x03,0x56,0xa0,0x03,0x02,0x01,0x02,0x02,0x0b,0x04, +0x00,0x00,0x00,0x00,0x01,0x12,0x56,0xad,0x62,0x04,0x30,0x0d,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x57,0x31,0x0b,0x30,0x09,0x06, +0x03,0x55,0x04,0x06,0x13,0x02,0x42,0x45,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04, +0x0a,0x13,0x10,0x47,0x6c,0x6f,0x62,0x61,0x6c,0x53,0x69,0x67,0x6e,0x20,0x6e,0x76, +0x2d,0x73,0x61,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x0b,0x13,0x07,0x52,0x6f, +0x6f,0x74,0x20,0x43,0x41,0x31,0x1b,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12, +0x47,0x6c,0x6f,0x62,0x61,0x6c,0x53,0x69,0x67,0x6e,0x20,0x52,0x6f,0x6f,0x74,0x20, +0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x34,0x31,0x30,0x30,0x30, +0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,0x31,0x32,0x37,0x31,0x31,0x30,0x30,0x30, +0x30,0x5a,0x30,0x71,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x42, +0x45,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,0x44,0x6f,0x6d,0x61, +0x69,0x6e,0x20,0x56,0x61,0x6c,0x69,0x64,0x61,0x74,0x69,0x6f,0x6e,0x20,0x43,0x41, +0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0a,0x13,0x10,0x47,0x6c,0x6f,0x62,0x61, +0x6c,0x53,0x69,0x67,0x6e,0x20,0x6e,0x76,0x2d,0x73,0x61,0x31,0x28,0x30,0x26,0x06, +0x03,0x55,0x04,0x03,0x13,0x1f,0x47,0x6c,0x6f,0x62,0x61,0x6c,0x53,0x69,0x67,0x6e, +0x20,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x20,0x56,0x61,0x6c,0x69,0x64,0x61,0x74,0x69, +0x6f,0x6e,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01, +0x0a,0x02,0x82,0x01,0x01,0x00,0xb4,0x9f,0x49,0xe6,0xb3,0x9f,0x01,0x55,0x36,0xd0, +0x36,0x95,0x6c,0xcb,0x16,0x5a,0x6c,0x72,0xb5,0xe2,0x9d,0xe2,0xfa,0x39,0xe9,0x0a, +0xdc,0x73,0x5c,0xa0,0x3b,0x76,0x6d,0x05,0x28,0x93,0x0d,0xa5,0x42,0xf3,0xe8,0xcb, +0xee,0xd3,0x33,0x1a,0x13,0x27,0x0a,0xdf,0x5c,0xd1,0x54,0x62,0x6a,0x9a,0x17,0x36, +0xd6,0x3c,0x58,0x87,0x1e,0xb2,0x66,0x1f,0x55,0x69,0x2b,0x89,0x56,0x47,0xb4,0xc2, +0x50,0x0c,0xe5,0x5d,0xc1,0xfd,0x29,0x1b,0x66,0x73,0x43,0xf4,0x6f,0xd1,0x14,0x4f, +0x2a,0x6d,0x48,0x52,0x3a,0xf5,0xe4,0x90,0x3f,0xde,0xb2,0xf4,0x10,0xd5,0xf9,0xfa, +0xac,0x96,0x0d,0x10,0x32,0x23,0xd2,0xd3,0x51,0xa7,0x95,0x85,0x50,0xfa,0x0f,0x29, +0x9d,0xa7,0x88,0x4e,0x0d,0x31,0x9b,0x44,0x41,0x8e,0x41,0x2f,0x6e,0x9a,0x1a,0xb4, +0xb6,0xa5,0x59,0xf1,0x49,0x59,0x09,0x7e,0x7e,0x49,0xd3,0x69,0x33,0x4b,0x00,0x92, +0xc5,0x1b,0x42,0x20,0x69,0xf8,0x64,0xdf,0xd8,0xa7,0x44,0xd1,0x90,0x5e,0xfd,0x39, +0xad,0x6b,0x7d,0xfe,0xd5,0x8b,0xa4,0x01,0x64,0xf6,0xa7,0xb4,0x20,0x84,0xcc,0x05, +0x2f,0x27,0xee,0x1e,0xd5,0x24,0x96,0xae,0x84,0x43,0xa4,0x3e,0x43,0xf3,0x3b,0x99, +0xd7,0xf9,0xf2,0xde,0x3d,0x19,0xed,0xd0,0x65,0xf1,0x49,0xca,0x48,0xd2,0x38,0x7d, +0xc6,0x48,0xd7,0x72,0x61,0xb8,0xc6,0xc2,0x67,0x0a,0xd8,0x65,0x5a,0xfd,0x5b,0xf3, +0xc5,0xfd,0xbe,0x8c,0x69,0xcf,0x99,0x20,0xb6,0xea,0xec,0x39,0x80,0xe9,0x66,0xa8, +0xee,0x3d,0x9d,0x46,0x7b,0x87,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x1f,0x30, +0x82,0x01,0x1b,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03, +0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30, +0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,0x4b,0x06,0x03,0x55,0x1d,0x20,0x04,0x44, +0x30,0x42,0x30,0x40,0x06,0x09,0x2b,0x06,0x01,0x04,0x01,0xa0,0x32,0x01,0x0a,0x30, +0x33,0x30,0x31,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x25,0x68, +0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x67,0x6c,0x6f,0x62,0x61,0x6c, +0x73,0x69,0x67,0x6e,0x2e,0x6e,0x65,0x74,0x2f,0x72,0x65,0x70,0x6f,0x73,0x69,0x74, +0x6f,0x72,0x79,0x2f,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0x36, +0x12,0x4e,0x9e,0x71,0xc4,0x26,0x41,0xf1,0xfa,0xf1,0x29,0x4c,0xbf,0x17,0xa4,0x53, +0x28,0xb6,0xeb,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,0x2a,0x30,0x28, +0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c, +0x2e,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x73,0x69,0x67,0x6e,0x2e,0x6e,0x65,0x74,0x2f, +0x72,0x6f,0x6f,0x74,0x2e,0x63,0x72,0x6c,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01, +0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x02,0x04,0x30,0x20,0x06,0x03,0x55, +0x1d,0x25,0x04,0x19,0x30,0x17,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a, +0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,0x42,0x04,0x01,0x30,0x1f,0x06, +0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x60,0x7b,0x66,0x1a,0x45,0x0d, +0x97,0xca,0x89,0x50,0x2f,0x7d,0x04,0xcd,0x34,0xa8,0xff,0xfc,0xfd,0x4b,0x30,0x0d, +0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01, +0x01,0x00,0xc3,0x25,0x79,0x4a,0xfa,0xcd,0x26,0x6f,0x40,0x6a,0xb8,0x94,0x1b,0xe6, +0xa0,0xe1,0x6b,0xd2,0x31,0x9a,0x3f,0x89,0xfb,0xc5,0x0a,0x22,0x75,0x7a,0xfd,0xbb, +0x40,0x34,0x9c,0xbc,0x9e,0x85,0x49,0x59,0x7a,0x95,0xcc,0x0d,0x2d,0x44,0x0b,0xc7, +0xcb,0x15,0x10,0x1e,0xd2,0xdc,0xe3,0x78,0xea,0x5f,0xf5,0x35,0x51,0xa6,0xc8,0x3f, +0x39,0x90,0x15,0x9e,0x5f,0x15,0xc9,0xb7,0x8f,0x5d,0x6b,0x63,0x99,0x68,0xe1,0x6e, +0x5c,0xfc,0x9d,0x37,0x33,0x0a,0xae,0x87,0x70,0x4a,0xa2,0xe3,0xab,0x26,0x7d,0x73, +0x07,0xe4,0xf7,0x0a,0xaa,0x75,0x8f,0xa6,0xee,0x9b,0x04,0xd1,0x05,0x43,0x74,0x1a, +0xba,0xd4,0xc2,0x9d,0x7f,0xb7,0xa0,0x6c,0xed,0x16,0x9a,0x67,0x40,0x56,0xab,0x83, +0x9f,0x4c,0x9c,0xeb,0x28,0x34,0x1f,0x8d,0xe6,0x5a,0x0f,0x69,0x40,0xd9,0xa9,0x9e, +0x6a,0xf9,0x89,0x7f,0xd0,0xf8,0x8c,0xb3,0x48,0x2e,0x0b,0x4f,0xf1,0xf9,0xcf,0xf5, +0x0e,0x11,0x02,0x0c,0x89,0x16,0x73,0x53,0x5d,0x2c,0xd3,0xef,0xde,0x5f,0x0b,0x25, +0xba,0xd5,0x4e,0x8f,0x85,0x90,0x3f,0x88,0x93,0x79,0xa5,0x20,0xac,0xff,0xb0,0x8a, +0xcb,0xcb,0xa5,0x55,0x78,0x83,0x39,0x41,0x32,0xaa,0x5d,0x25,0x93,0xa7,0xea,0xee, +0x18,0x72,0xb5,0xe2,0x1d,0x7f,0x08,0x74,0x11,0xb6,0x01,0x27,0x4e,0x96,0xcf,0xa8, +0xf0,0x2a,0xf9,0x52,0xac,0x24,0x1a,0x19,0x9e,0x9f,0x6c,0x52,0x7c,0x8b,0x3a,0xa6, +0x54,0xde,0xc1,0xc7,0x21,0x7d,0x3a,0xd3,0xbc,0x1a,0xa8,0x6d,0xf2,0xbf,0xdf,0x76, +0xca,0x03 +}; +static const BYTE global_sign_ca[] = { +0x30,0x82,0x04,0x6e,0x30,0x82,0x03,0x56,0xa0,0x03,0x02,0x01,0x02,0x02,0x0b,0x04, +0x00,0x00,0x00,0x00,0x01,0x12,0x56,0xad,0x62,0x04,0x30,0x0d,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x57,0x31,0x0b,0x30,0x09,0x06, +0x03,0x55,0x04,0x06,0x13,0x02,0x42,0x45,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04, +0x0a,0x13,0x10,0x47,0x6c,0x6f,0x62,0x61,0x6c,0x53,0x69,0x67,0x6e,0x20,0x6e,0x76, +0x2d,0x73,0x61,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x0b,0x13,0x07,0x52,0x6f, +0x6f,0x74,0x20,0x43,0x41,0x31,0x1b,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12, +0x47,0x6c,0x6f,0x62,0x61,0x6c,0x53,0x69,0x67,0x6e,0x20,0x52,0x6f,0x6f,0x74,0x20, +0x43,0x41,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x34,0x31,0x30,0x30,0x30, +0x30,0x30,0x5a,0x17,0x0d,0x31,0x34,0x30,0x31,0x32,0x37,0x31,0x31,0x30,0x30,0x30, +0x30,0x5a,0x30,0x71,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x42, +0x45,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04,0x0b,0x13,0x14,0x44,0x6f,0x6d,0x61, +0x69,0x6e,0x20,0x56,0x61,0x6c,0x69,0x64,0x61,0x74,0x69,0x6f,0x6e,0x20,0x43,0x41, +0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0a,0x13,0x10,0x47,0x6c,0x6f,0x62,0x61, +0x6c,0x53,0x69,0x67,0x6e,0x20,0x6e,0x76,0x2d,0x73,0x61,0x31,0x28,0x30,0x26,0x06, +0x03,0x55,0x04,0x03,0x13,0x1f,0x47,0x6c,0x6f,0x62,0x61,0x6c,0x53,0x69,0x67,0x6e, +0x20,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x20,0x56,0x61,0x6c,0x69,0x64,0x61,0x74,0x69, +0x6f,0x6e,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01, +0x0a,0x02,0x82,0x01,0x01,0x00,0xb4,0x9f,0x49,0xe6,0xb3,0x9f,0x01,0x55,0x36,0xd0, +0x36,0x95,0x6c,0xcb,0x16,0x5a,0x6c,0x72,0xb5,0xe2,0x9d,0xe2,0xfa,0x39,0xe9,0x0a, +0xdc,0x73,0x5c,0xa0,0x3b,0x76,0x6d,0x05,0x28,0x93,0x0d,0xa5,0x42,0xf3,0xe8,0xcb, +0xee,0xd3,0x33,0x1a,0x13,0x27,0x0a,0xdf,0x5c,0xd1,0x54,0x62,0x6a,0x9a,0x17,0x36, +0xd6,0x3c,0x58,0x87,0x1e,0xb2,0x66,0x1f,0x55,0x69,0x2b,0x89,0x56,0x47,0xb4,0xc2, +0x50,0x0c,0xe5,0x5d,0xc1,0xfd,0x29,0x1b,0x66,0x73,0x43,0xf4,0x6f,0xd1,0x14,0x4f, +0x2a,0x6d,0x48,0x52,0x3a,0xf5,0xe4,0x90,0x3f,0xde,0xb2,0xf4,0x10,0xd5,0xf9,0xfa, +0xac,0x96,0x0d,0x10,0x32,0x23,0xd2,0xd3,0x51,0xa7,0x95,0x85,0x50,0xfa,0x0f,0x29, +0x9d,0xa7,0x88,0x4e,0x0d,0x31,0x9b,0x44,0x41,0x8e,0x41,0x2f,0x6e,0x9a,0x1a,0xb4, +0xb6,0xa5,0x59,0xf1,0x49,0x59,0x09,0x7e,0x7e,0x49,0xd3,0x69,0x33,0x4b,0x00,0x92, +0xc5,0x1b,0x42,0x20,0x69,0xf8,0x64,0xdf,0xd8,0xa7,0x44,0xd1,0x90,0x5e,0xfd,0x39, +0xad,0x6b,0x7d,0xfe,0xd5,0x8b,0xa4,0x01,0x64,0xf6,0xa7,0xb4,0x20,0x84,0xcc,0x05, +0x2f,0x27,0xee,0x1e,0xd5,0x24,0x96,0xae,0x84,0x43,0xa4,0x3e,0x43,0xf3,0x3b,0x99, +0xd7,0xf9,0xf2,0xde,0x3d,0x19,0xed,0xd0,0x65,0xf1,0x49,0xca,0x48,0xd2,0x38,0x7d, +0xc6,0x48,0xd7,0x72,0x61,0xb8,0xc6,0xc2,0x67,0x0a,0xd8,0x65,0x5a,0xfd,0x5b,0xf3, +0xc5,0xfd,0xbe,0x8c,0x69,0xcf,0x99,0x20,0xb6,0xea,0xec,0x39,0x80,0xe9,0x66,0xa8, +0xee,0x3d,0x9d,0x46,0x7b,0x87,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x1f,0x30, +0x82,0x01,0x1b,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03, +0x02,0x01,0x06,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30, +0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,0x4b,0x06,0x03,0x55,0x1d,0x20,0x04,0x44, +0x30,0x42,0x30,0x40,0x06,0x09,0x2b,0x06,0x01,0x04,0x01,0xa0,0x32,0x01,0x0a,0x30, +0x33,0x30,0x31,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x25,0x68, +0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x67,0x6c,0x6f,0x62,0x61,0x6c, +0x73,0x69,0x67,0x6e,0x2e,0x6e,0x65,0x74,0x2f,0x72,0x65,0x70,0x6f,0x73,0x69,0x74, +0x6f,0x72,0x79,0x2f,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0x36, +0x12,0x4e,0x9e,0x71,0xc4,0x26,0x41,0xf1,0xfa,0xf1,0x29,0x4c,0xbf,0x17,0xa4,0x53, +0x28,0xb6,0xeb,0x30,0x33,0x06,0x03,0x55,0x1d,0x1f,0x04,0x2c,0x30,0x2a,0x30,0x28, +0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c, +0x2e,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x73,0x69,0x67,0x6e,0x2e,0x6e,0x65,0x74,0x2f, +0x72,0x6f,0x6f,0x74,0x2e,0x63,0x72,0x6c,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01, +0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x02,0x04,0x30,0x20,0x06,0x03,0x55, +0x1d,0x25,0x04,0x19,0x30,0x17,0x06,0x0a,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a, +0x03,0x03,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,0x42,0x04,0x01,0x30,0x1f,0x06, +0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x60,0x7b,0x66,0x1a,0x45,0x0d, +0x97,0xca,0x89,0x50,0x2f,0x7d,0x04,0xcd,0x34,0xa8,0xff,0xfc,0xfd,0x4b,0x30,0x0d, +0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01, +0x01,0x00,0xc3,0x25,0x79,0x4a,0xfa,0xcd,0x26,0x6f,0x40,0x6a,0xb8,0x94,0x1b,0xe6, +0xa0,0xe1,0x6b,0xd2,0x31,0x9a,0x3f,0x89,0xfb,0xc5,0x0a,0x22,0x75,0x7a,0xfd,0xbb, +0x40,0x34,0x9c,0xbc,0x9e,0x85,0x49,0x59,0x7a,0x95,0xcc,0x0d,0x2d,0x44,0x0b,0xc7, +0xcb,0x15,0x10,0x1e,0xd2,0xdc,0xe3,0x78,0xea,0x5f,0xf5,0x35,0x51,0xa6,0xc8,0x3f, +0x39,0x90,0x15,0x9e,0x5f,0x15,0xc9,0xb7,0x8f,0x5d,0x6b,0x63,0x99,0x68,0xe1,0x6e, +0x5c,0xfc,0x9d,0x37,0x33,0x0a,0xae,0x87,0x70,0x4a,0xa2,0xe3,0xab,0x26,0x7d,0x73, +0x07,0xe4,0xf7,0x0a,0xaa,0x75,0x8f,0xa6,0xee,0x9b,0x04,0xd1,0x05,0x43,0x74,0x1a, +0xba,0xd4,0xc2,0x9d,0x7f,0xb7,0xa0,0x6c,0xed,0x16,0x9a,0x67,0x40,0x56,0xab,0x83, +0x9f,0x4c,0x9c,0xeb,0x28,0x34,0x1f,0x8d,0xe6,0x5a,0x0f,0x69,0x40,0xd9,0xa9,0x9e, +0x6a,0xf9,0x89,0x7f,0xd0,0xf8,0x8c,0xb3,0x48,0x2e,0x0b,0x4f,0xf1,0xf9,0xcf,0xf5, +0x0e,0x11,0x02,0x0c,0x89,0x16,0x73,0x53,0x5d,0x2c,0xd3,0xef,0xde,0x5f,0x0b,0x25, +0xba,0xd5,0x4e,0x8f,0x85,0x90,0x3f,0x88,0x93,0x79,0xa5,0x20,0xac,0xff,0xb0,0x8a, +0xcb,0xcb,0xa5,0x55,0x78,0x83,0x39,0x41,0x32,0xaa,0x5d,0x25,0x93,0xa7,0xea,0xee, +0x18,0x72,0xb5,0xe2,0x1d,0x7f,0x08,0x74,0x11,0xb6,0x01,0x27,0x4e,0x96,0xcf,0xa8, +0xf0,0x2a,0xf9,0x52,0xac,0x24,0x1a,0x19,0x9e,0x9f,0x6c,0x52,0x7c,0x8b,0x3a,0xa6, +0x54,0xde,0xc1,0xc7,0x21,0x7d,0x3a,0xd3,0xbc,0x1a,0xa8,0x6d,0xf2,0xbf,0xdf,0x76, +0xca,0x03 +}; +static const BYTE openssl_org[] = { +0x30,0x82,0x04,0xc8,0x30,0x82,0x03,0xb0,0xa0,0x03,0x02,0x01,0x02,0x02,0x0b,0x01, +0x00,0x00,0x00,0x00,0x01,0x1c,0x57,0x8e,0x3a,0xeb,0x30,0x0d,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x71,0x31,0x0b,0x30,0x09,0x06, +0x03,0x55,0x04,0x06,0x13,0x02,0x42,0x45,0x31,0x1d,0x30,0x1b,0x06,0x03,0x55,0x04, +0x0b,0x13,0x14,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x20,0x56,0x61,0x6c,0x69,0x64,0x61, +0x74,0x69,0x6f,0x6e,0x20,0x43,0x41,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0a, +0x13,0x10,0x47,0x6c,0x6f,0x62,0x61,0x6c,0x53,0x69,0x67,0x6e,0x20,0x6e,0x76,0x2d, +0x73,0x61,0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x03,0x13,0x1f,0x47,0x6c,0x6f, +0x62,0x61,0x6c,0x53,0x69,0x67,0x6e,0x20,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x20,0x56, +0x61,0x6c,0x69,0x64,0x61,0x74,0x69,0x6f,0x6e,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d, +0x30,0x38,0x30,0x39,0x31,0x32,0x31,0x37,0x31,0x34,0x31,0x31,0x5a,0x17,0x0d,0x31, +0x31,0x30,0x39,0x31,0x33,0x31,0x37,0x31,0x34,0x30,0x36,0x5a,0x30,0x60,0x31,0x0b, +0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x21,0x30,0x1f,0x06, +0x03,0x55,0x04,0x0b,0x13,0x18,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x20,0x43,0x6f,0x6e, +0x74,0x72,0x6f,0x6c,0x20,0x56,0x61,0x6c,0x69,0x64,0x61,0x74,0x65,0x64,0x31,0x16, +0x30,0x14,0x06,0x03,0x55,0x04,0x0a,0x14,0x0d,0x2a,0x2e,0x6f,0x70,0x65,0x6e,0x73, +0x73,0x6c,0x2e,0x6f,0x72,0x67,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x14, +0x0d,0x2a,0x2e,0x6f,0x70,0x65,0x6e,0x73,0x73,0x6c,0x2e,0x6f,0x72,0x67,0x30,0x82, +0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05, +0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xb9, +0x23,0x4e,0x1d,0xb5,0xef,0x87,0xb2,0xce,0x43,0x75,0x6a,0xc3,0x11,0x1c,0xd2,0xf7, +0x32,0xf3,0xf7,0x92,0x9b,0xed,0xe6,0x86,0xc3,0xb7,0x93,0x93,0x5e,0x7d,0x32,0x6a, +0x2b,0x03,0xb7,0x2a,0xc8,0x80,0x98,0x91,0x41,0x40,0x08,0xac,0xde,0xa6,0x7a,0x7c, +0x4f,0x44,0x8b,0x9c,0xd8,0xd3,0x87,0x71,0xf2,0x4e,0x3e,0x54,0xd7,0xa4,0x11,0x81, +0xb7,0x71,0x68,0x87,0xc1,0xc9,0xaf,0x2a,0xfa,0xb2,0x74,0xa3,0x70,0xa1,0x4d,0x19, +0x06,0x8d,0x1c,0x95,0x04,0x14,0x9c,0x8f,0x1f,0xf0,0x98,0xc1,0xc0,0x70,0xfa,0xb1, +0x10,0x1d,0x77,0xda,0x80,0x14,0x53,0xa5,0x5c,0xbe,0x05,0x9a,0x43,0xf4,0x54,0xf3, +0x70,0xf4,0x71,0x39,0xea,0x50,0x9c,0xe6,0xa8,0xd0,0x78,0xa6,0x30,0x1e,0x6d,0x4d, +0x22,0x10,0xdd,0x15,0x2d,0x50,0x00,0x5d,0xd9,0xc9,0xd2,0xa6,0xb9,0xdb,0x7f,0xad, +0xd8,0xeb,0xef,0x65,0x1f,0xce,0xbb,0x8d,0x4e,0x51,0x95,0x84,0x6e,0x95,0x16,0xef, +0x0b,0xf0,0x7b,0xff,0x2d,0x6c,0x1b,0x81,0x6c,0xca,0xe0,0x25,0x3d,0x2a,0x5c,0x6f, +0xad,0xce,0x4b,0x5c,0x46,0x7c,0xb1,0xa9,0xf4,0xea,0x72,0x02,0xa1,0xcc,0x87,0x63, +0x85,0x19,0x52,0x01,0x23,0x04,0x8e,0x2a,0xb4,0x94,0xde,0x6d,0x69,0x13,0x65,0x0b, +0x70,0x5f,0x92,0x1a,0x44,0x68,0x41,0xcd,0x80,0xef,0xc9,0xe9,0x83,0xd8,0x1e,0x95, +0x86,0xc7,0x1a,0x51,0xaf,0x3d,0xaa,0xca,0x97,0x19,0xe0,0xb4,0x69,0x87,0x75,0xe1, +0x09,0x9a,0x53,0xcd,0xf5,0x43,0xcf,0x2b,0x1d,0xe7,0x81,0x20,0x1e,0x97,0x25,0x02, +0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0x70,0x30,0x82,0x01,0x6c,0x30,0x1f,0x06,0x03, +0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x36,0x12,0x4e,0x9e,0x71,0xc4,0x26, +0x41,0xf1,0xfa,0xf1,0x29,0x4c,0xbf,0x17,0xa4,0x53,0x28,0xb6,0xeb,0x30,0x49,0x06, +0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x3d,0x30,0x3b,0x30,0x39,0x06, +0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x2d,0x68,0x74,0x74,0x70,0x3a, +0x2f,0x2f,0x73,0x65,0x63,0x75,0x72,0x65,0x2e,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x73, +0x69,0x67,0x6e,0x2e,0x6e,0x65,0x74,0x2f,0x63,0x61,0x63,0x65,0x72,0x74,0x2f,0x64, +0x76,0x68,0x65,0x31,0x2e,0x63,0x72,0x74,0x30,0x39,0x06,0x03,0x55,0x1d,0x1f,0x04, +0x32,0x30,0x30,0x30,0x2e,0xa0,0x2c,0xa0,0x2a,0x86,0x28,0x68,0x74,0x74,0x70,0x3a, +0x2f,0x2f,0x63,0x72,0x6c,0x2e,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x73,0x69,0x67,0x6e, +0x2e,0x6e,0x65,0x74,0x2f,0x44,0x6f,0x6d,0x61,0x69,0x6e,0x56,0x61,0x6c,0x31,0x2e, +0x63,0x72,0x6c,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0xec,0x81, +0x7d,0x47,0xa8,0xc0,0x19,0xa7,0xbc,0x6b,0x52,0x5e,0xb6,0x90,0xfb,0x17,0xae,0x7f, +0x41,0x8f,0x30,0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x0e,0x06, +0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x04,0xf0,0x30,0x29,0x06, +0x03,0x55,0x1d,0x25,0x04,0x22,0x30,0x20,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07, +0x03,0x01,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x0a,0x2b,0x06, +0x01,0x04,0x01,0x82,0x37,0x0a,0x03,0x03,0x30,0x4b,0x06,0x03,0x55,0x1d,0x20,0x04, +0x44,0x30,0x42,0x30,0x40,0x06,0x09,0x2b,0x06,0x01,0x04,0x01,0xa0,0x32,0x01,0x0a, +0x30,0x33,0x30,0x31,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x01,0x16,0x25, +0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x67,0x6c,0x6f,0x62,0x61, +0x6c,0x73,0x69,0x67,0x6e,0x2e,0x6e,0x65,0x74,0x2f,0x72,0x65,0x70,0x6f,0x73,0x69, +0x74,0x6f,0x72,0x79,0x2f,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,0x42, +0x01,0x01,0x04,0x04,0x03,0x02,0x06,0xc0,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x2b,0x22,0xdd,0xa3, +0x1a,0xf9,0x12,0xee,0x77,0xbf,0x34,0xdd,0xbf,0x57,0x98,0x72,0xb3,0x05,0x8d,0x49, +0xa4,0x5d,0x55,0xec,0x08,0xf4,0x70,0xb9,0x83,0xaf,0x57,0xb2,0x0f,0x54,0x12,0xc5, +0xf4,0x0e,0x6e,0xd9,0xe4,0xd4,0x7c,0x6a,0x11,0x4a,0xd7,0xc3,0x46,0x42,0x7e,0x13, +0x4c,0x39,0x1b,0xe3,0x53,0xb1,0x8b,0x8a,0xd7,0xa2,0x74,0xcb,0x18,0x0a,0x40,0x50, +0xbe,0xbe,0x86,0x81,0xa9,0x8e,0x23,0x0b,0xa0,0x38,0x02,0x1c,0x55,0x57,0xfd,0xf7, +0x98,0x43,0x7f,0x6e,0xe9,0x26,0xc5,0x64,0x7d,0x8a,0x42,0xfb,0x67,0xbd,0x93,0x39, +0x75,0x49,0xcd,0x26,0x20,0x71,0xb4,0x65,0xca,0x04,0x15,0xfb,0x1a,0xcb,0x80,0x2e, +0x20,0x43,0x81,0x3e,0x58,0x7f,0x3f,0x2c,0x93,0x92,0x06,0x96,0x69,0xb0,0x49,0x4c, +0xd1,0xa8,0x53,0x9b,0x41,0x55,0x13,0x75,0xc3,0x51,0xe8,0x16,0x3d,0x3e,0x6f,0xbd, +0xb7,0x0c,0x49,0x48,0x64,0x97,0xb4,0x14,0x89,0x57,0x62,0x75,0x32,0x31,0xda,0x94, +0x82,0xf8,0xb3,0xc6,0x02,0x20,0x5e,0x0e,0x00,0x87,0x9c,0x0f,0x34,0x65,0xda,0xf2, +0x47,0x78,0x18,0xf5,0xd5,0xea,0xf3,0x93,0x4e,0x60,0xd6,0x6b,0x7a,0xe8,0x88,0xd7, +0x69,0x41,0xaa,0x10,0x56,0xd7,0x16,0x14,0xde,0xc9,0x1c,0xb6,0xb6,0x10,0xab,0x6b, +0x97,0xbd,0x6a,0xa9,0xb7,0x67,0xd7,0x96,0xeb,0x52,0x12,0x9e,0x9a,0x69,0xaf,0x38, +0x53,0x4d,0x99,0xd8,0x84,0xea,0x54,0xba,0x89,0x67,0xff,0x40,0x66,0x0d,0x53,0x99, +0xb6,0x65,0xba,0xf3,0x8a,0x01,0x3d,0xd0,0xf1,0x21,0x5f,0xdd +}; +/* entrust_ca -> aaa_certificate_services -> cs_stanford_edu: + * cs.stanford.edu's chain, also valid for www.cs.stanford.edu + */ +static const BYTE entrust_ca[] = { +0x30,0x82,0x04,0xd8,0x30,0x82,0x04,0x41,0xa0,0x03,0x02,0x01,0x02,0x02,0x04,0x37, +0x4a,0xd2,0x43,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05, +0x05,0x00,0x30,0x81,0xc3,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, +0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,0x13,0x0b,0x45,0x6e,0x74, +0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04, +0x0b,0x13,0x32,0x77,0x77,0x77,0x2e,0x65,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e, +0x65,0x74,0x2f,0x43,0x50,0x53,0x20,0x69,0x6e,0x63,0x6f,0x72,0x70,0x2e,0x20,0x62, +0x79,0x20,0x72,0x65,0x66,0x2e,0x20,0x28,0x6c,0x69,0x6d,0x69,0x74,0x73,0x20,0x6c, +0x69,0x61,0x62,0x2e,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0b,0x13,0x1c, +0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6e,0x74,0x72,0x75,0x73,0x74, +0x2e,0x6e,0x65,0x74,0x20,0x4c,0x69,0x6d,0x69,0x74,0x65,0x64,0x31,0x3a,0x30,0x38, +0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e, +0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72, +0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41, +0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x39,0x39,0x30,0x35, +0x32,0x35,0x31,0x36,0x30,0x39,0x34,0x30,0x5a,0x17,0x0d,0x31,0x39,0x30,0x35,0x32, +0x35,0x31,0x36,0x33,0x39,0x34,0x30,0x5a,0x30,0x81,0xc3,0x31,0x0b,0x30,0x09,0x06, +0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04, +0x0a,0x13,0x0b,0x45,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x31,0x3b, +0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x77,0x77,0x77,0x2e,0x65,0x6e,0x74, +0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x2f,0x43,0x50,0x53,0x20,0x69,0x6e,0x63, +0x6f,0x72,0x70,0x2e,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2e,0x20,0x28,0x6c,0x69, +0x6d,0x69,0x74,0x73,0x20,0x6c,0x69,0x61,0x62,0x2e,0x29,0x31,0x25,0x30,0x23,0x06, +0x03,0x55,0x04,0x0b,0x13,0x1c,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45, +0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x20,0x4c,0x69,0x6d,0x69,0x74, +0x65,0x64,0x31,0x3a,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6e,0x74, +0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20, +0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, +0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x81, +0x9d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00, +0x03,0x81,0x8b,0x00,0x30,0x81,0x87,0x02,0x81,0x81,0x00,0xcd,0x28,0x83,0x34,0x54, +0x1b,0x89,0xf3,0x0f,0xaf,0x37,0x91,0x31,0xff,0xaf,0x31,0x60,0xc9,0xa8,0xe8,0xb2, +0x10,0x68,0xed,0x9f,0xe7,0x93,0x36,0xf1,0x0a,0x64,0xbb,0x47,0xf5,0x04,0x17,0x3f, +0x23,0x47,0x4d,0xc5,0x27,0x19,0x81,0x26,0x0c,0x54,0x72,0x0d,0x88,0x2d,0xd9,0x1f, +0x9a,0x12,0x9f,0xbc,0xb3,0x71,0xd3,0x80,0x19,0x3f,0x47,0x66,0x7b,0x8c,0x35,0x28, +0xd2,0xb9,0x0a,0xdf,0x24,0xda,0x9c,0xd6,0x50,0x79,0x81,0x7a,0x5a,0xd3,0x37,0xf7, +0xc2,0x4a,0xd8,0x29,0x92,0x26,0x64,0xd1,0xe4,0x98,0x6c,0x3a,0x00,0x8a,0xf5,0x34, +0x9b,0x65,0xf8,0xed,0xe3,0x10,0xff,0xfd,0xb8,0x49,0x58,0xdc,0xa0,0xde,0x82,0x39, +0x6b,0x81,0xb1,0x16,0x19,0x61,0xb9,0x54,0xb6,0xe6,0x43,0x02,0x01,0x03,0xa3,0x82, +0x01,0xd7,0x30,0x82,0x01,0xd3,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8, +0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x00,0x07,0x30,0x82,0x01,0x19,0x06,0x03,0x55, +0x1d,0x1f,0x04,0x82,0x01,0x10,0x30,0x82,0x01,0x0c,0x30,0x81,0xde,0xa0,0x81,0xdb, +0xa0,0x81,0xd8,0xa4,0x81,0xd5,0x30,0x81,0xd2,0x31,0x0b,0x30,0x09,0x06,0x03,0x55, +0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,0x13, +0x0b,0x45,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x31,0x3b,0x30,0x39, +0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x77,0x77,0x77,0x2e,0x65,0x6e,0x74,0x72,0x75, +0x73,0x74,0x2e,0x6e,0x65,0x74,0x2f,0x43,0x50,0x53,0x20,0x69,0x6e,0x63,0x6f,0x72, +0x70,0x2e,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2e,0x20,0x28,0x6c,0x69,0x6d,0x69, +0x74,0x73,0x20,0x6c,0x69,0x61,0x62,0x2e,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55, +0x04,0x0b,0x13,0x1c,0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6e,0x74, +0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x20,0x4c,0x69,0x6d,0x69,0x74,0x65,0x64, +0x31,0x3a,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6e,0x74,0x72,0x75, +0x73,0x74,0x2e,0x6e,0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65, +0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69, +0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x31,0x0d,0x30,0x0b, +0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4c,0x31,0x30,0x29,0xa0,0x27,0xa0, +0x25,0x86,0x23,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x65,0x6e, +0x74,0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x2f,0x43,0x52,0x4c,0x2f,0x6e,0x65, +0x74,0x31,0x2e,0x63,0x72,0x6c,0x30,0x2b,0x06,0x03,0x55,0x1d,0x10,0x04,0x24,0x30, +0x22,0x80,0x0f,0x31,0x39,0x39,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39,0x34, +0x30,0x5a,0x81,0x0f,0x32,0x30,0x31,0x39,0x30,0x35,0x32,0x35,0x31,0x36,0x30,0x39, +0x34,0x30,0x5a,0x30,0x0b,0x06,0x03,0x55,0x1d,0x0f,0x04,0x04,0x03,0x02,0x01,0x06, +0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xf0,0x17,0x62, +0x13,0x55,0x3d,0xb3,0xff,0x0a,0x00,0x6b,0xfb,0x50,0x84,0x97,0xf3,0xed,0x62,0xd0, +0x1a,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0xf0,0x17,0x62,0x13, +0x55,0x3d,0xb3,0xff,0x0a,0x00,0x6b,0xfb,0x50,0x84,0x97,0xf3,0xed,0x62,0xd0,0x1a, +0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x19, +0x06,0x09,0x2a,0x86,0x48,0x86,0xf6,0x7d,0x07,0x41,0x00,0x04,0x0c,0x30,0x0a,0x1b, +0x04,0x56,0x34,0x2e,0x30,0x03,0x02,0x04,0x90,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x90,0xdc,0x30,0x02, +0xfa,0x64,0x74,0xc2,0xa7,0x0a,0xa5,0x7c,0x21,0x8d,0x34,0x17,0xa8,0xfb,0x47,0x0e, +0xff,0x25,0x7c,0x8d,0x13,0x0a,0xfb,0xe4,0x98,0xb5,0xef,0x8c,0xf8,0xc5,0x10,0x0d, +0xf7,0x92,0xbe,0xf1,0xc3,0xd5,0xd5,0x95,0x6a,0x04,0xbb,0x2c,0xce,0x26,0x36,0x65, +0xc8,0x31,0xc6,0xe7,0xee,0x3f,0xe3,0x57,0x75,0x84,0x7a,0x11,0xef,0x46,0x4f,0x18, +0xf4,0xd3,0x98,0xbb,0xa8,0x87,0x32,0xba,0x72,0xf6,0x3c,0xe2,0x3d,0x9f,0xd7,0x1d, +0xd9,0xc3,0x60,0x43,0x8c,0x58,0x0e,0x22,0x96,0x2f,0x62,0xa3,0x2c,0x1f,0xba,0xad, +0x05,0xef,0xab,0x32,0x78,0x87,0xa0,0x54,0x73,0x19,0xb5,0x5c,0x05,0xf9,0x52,0x3e, +0x6d,0x2d,0x45,0x0b,0xf7,0x0a,0x93,0xea,0xed,0x06,0xf9,0xb2 +}; +static const BYTE aaa_certificate_services[] = { +0x30,0x82,0x04,0xf9,0x30,0x82,0x04,0x62,0xa0,0x03,0x02,0x01,0x02,0x02,0x04,0x42, +0x86,0xf2,0x3d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05, +0x05,0x00,0x30,0x81,0xc3,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, +0x55,0x53,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,0x13,0x0b,0x45,0x6e,0x74, +0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04, +0x0b,0x13,0x32,0x77,0x77,0x77,0x2e,0x65,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e, +0x65,0x74,0x2f,0x43,0x50,0x53,0x20,0x69,0x6e,0x63,0x6f,0x72,0x70,0x2e,0x20,0x62, +0x79,0x20,0x72,0x65,0x66,0x2e,0x20,0x28,0x6c,0x69,0x6d,0x69,0x74,0x73,0x20,0x6c, +0x69,0x61,0x62,0x2e,0x29,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0b,0x13,0x1c, +0x28,0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x45,0x6e,0x74,0x72,0x75,0x73,0x74, +0x2e,0x6e,0x65,0x74,0x20,0x4c,0x69,0x6d,0x69,0x74,0x65,0x64,0x31,0x3a,0x30,0x38, +0x06,0x03,0x55,0x04,0x03,0x13,0x31,0x45,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e, +0x65,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72, +0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41, +0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e,0x17,0x0d,0x30,0x36,0x31,0x30, +0x31,0x39,0x31,0x34,0x33,0x39,0x35,0x31,0x5a,0x17,0x0d,0x31,0x32,0x31,0x30,0x31, +0x39,0x31,0x35,0x30,0x39,0x35,0x31,0x5a,0x30,0x7b,0x31,0x0b,0x30,0x09,0x06,0x03, +0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1b,0x30,0x19,0x06,0x03,0x55,0x04,0x08, +0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20,0x4d,0x61,0x6e,0x63,0x68,0x65, +0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0e,0x06,0x03,0x55,0x04,0x07,0x13,0x07,0x53, +0x61,0x6c,0x66,0x6f,0x72,0x64,0x31,0x1a,0x30,0x18,0x06,0x03,0x55,0x04,0x0a,0x13, +0x11,0x43,0x6f,0x6d,0x6f,0x64,0x6f,0x20,0x43,0x41,0x20,0x4c,0x69,0x6d,0x69,0x74, +0x65,0x64,0x31,0x21,0x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x41,0x41,0x41, +0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x53,0x65,0x72, +0x76,0x69,0x63,0x65,0x73,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01, +0x0a,0x02,0x82,0x01,0x01,0x00,0xb0,0x4e,0x2e,0xd1,0x3f,0x51,0x8f,0x37,0x99,0x5d, +0x76,0x6c,0xf8,0xe1,0x23,0x02,0x93,0x44,0x2b,0x4c,0x88,0xf2,0x50,0x04,0x90,0xc6, +0xd7,0xca,0xd7,0x40,0xfe,0xcd,0x17,0xda,0x94,0x6b,0x73,0xf0,0x3d,0x0a,0x9b,0x23, +0xdd,0x98,0x18,0x07,0x62,0xa8,0x6e,0x11,0x99,0x78,0x3d,0x72,0x90,0x14,0x96,0x71, +0xfe,0xfa,0x8f,0xf5,0x03,0x84,0x8e,0xfb,0x85,0xa5,0xc5,0xe4,0xf7,0xed,0xe4,0x78, +0xbe,0xdf,0xaa,0xc7,0x9c,0xc7,0x9f,0xdf,0x21,0xdf,0x7d,0xcf,0x60,0xd4,0x70,0xbb, +0xd4,0xca,0xa6,0x5b,0xb9,0xd7,0x0e,0x6e,0x94,0x55,0x76,0x2d,0x19,0x8c,0x95,0x3a, +0x26,0x2e,0x91,0x67,0x93,0x67,0x27,0xfe,0x94,0x0a,0x48,0x62,0x9d,0x8f,0x98,0xe1, +0x25,0x63,0x4b,0xbe,0x2b,0x92,0x36,0x4f,0x11,0x48,0x39,0x66,0xe1,0xb1,0x1c,0x26, +0x35,0x56,0xe9,0x3d,0xdb,0x8e,0xff,0x1f,0x6e,0x24,0x63,0x0f,0x75,0x75,0x53,0x17, +0x48,0x5c,0x30,0x8f,0xd0,0x04,0xba,0x5e,0xc3,0xe9,0xdb,0x2f,0x1d,0x18,0x06,0x16, +0x71,0xff,0x8a,0xf6,0x99,0xc1,0x79,0x5f,0x82,0xed,0xd8,0xa0,0x2f,0x46,0x06,0xa4, +0xeb,0x29,0xe6,0x8e,0xfd,0x52,0x8d,0xbd,0x83,0x57,0xd0,0x2f,0x71,0x15,0x0e,0xcc, +0x0b,0xf6,0x8e,0xfa,0xab,0x0e,0xfa,0xa0,0xac,0x68,0x97,0xad,0xfd,0x59,0xfc,0x19, +0x13,0x33,0x7b,0x0b,0x83,0x6a,0x90,0x63,0x55,0x26,0xe7,0x78,0x05,0x8a,0xb8,0x1c, +0xef,0x75,0xc1,0xc2,0x27,0x9f,0x4e,0x97,0x04,0x29,0xd0,0x97,0xc1,0x41,0xd8,0xbc, +0x0f,0x13,0xdc,0xa2,0x58,0xb9,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xbb,0x30, +0x82,0x01,0xb7,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30, +0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,0x1d,0x06,0x03,0x55,0x1d,0x25,0x04,0x16, +0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x06,0x08,0x2b,0x06, +0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04, +0x14,0x30,0x43,0xdc,0x64,0xcd,0x19,0x5c,0xa9,0xf3,0x19,0xd2,0x37,0x09,0x96,0x91, +0x9e,0x0c,0xe8,0xd6,0x3d,0x30,0x82,0x01,0x18,0x06,0x03,0x55,0x1d,0x1f,0x04,0x82, +0x01,0x0f,0x30,0x82,0x01,0x0b,0x30,0x28,0xa0,0x26,0xa0,0x24,0x86,0x22,0x68,0x74, +0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,0x65,0x6e,0x74,0x72,0x75,0x73,0x74, +0x2e,0x6e,0x65,0x74,0x2f,0x73,0x65,0x72,0x76,0x65,0x72,0x31,0x2e,0x63,0x72,0x6c, +0x30,0x81,0xde,0xa0,0x81,0xdb,0xa0,0x81,0xd8,0xa4,0x81,0xd5,0x30,0x81,0xd2,0x31, +0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x14,0x30,0x12, +0x06,0x03,0x55,0x04,0x0a,0x13,0x0b,0x45,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e, +0x65,0x74,0x31,0x3b,0x30,0x39,0x06,0x03,0x55,0x04,0x0b,0x13,0x32,0x77,0x77,0x77, +0x2e,0x65,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x2f,0x43,0x50,0x53, +0x20,0x69,0x6e,0x63,0x6f,0x72,0x70,0x2e,0x20,0x62,0x79,0x20,0x72,0x65,0x66,0x2e, +0x20,0x28,0x6c,0x69,0x6d,0x69,0x74,0x73,0x20,0x6c,0x69,0x61,0x62,0x2e,0x29,0x31, +0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0b,0x13,0x1c,0x28,0x63,0x29,0x20,0x31,0x39, +0x39,0x39,0x20,0x45,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x20,0x4c, +0x69,0x6d,0x69,0x74,0x65,0x64,0x31,0x3a,0x30,0x38,0x06,0x03,0x55,0x04,0x03,0x13, +0x31,0x45,0x6e,0x74,0x72,0x75,0x73,0x74,0x2e,0x6e,0x65,0x74,0x20,0x53,0x65,0x63, +0x75,0x72,0x65,0x20,0x53,0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69, +0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69, +0x74,0x79,0x31,0x0d,0x30,0x0b,0x06,0x03,0x55,0x04,0x03,0x13,0x04,0x43,0x52,0x4c, +0x31,0x30,0x0b,0x06,0x03,0x55,0x1d,0x0f,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1f, +0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xf0,0x17,0x62,0x13,0x55, +0x3d,0xb3,0xff,0x0a,0x00,0x6b,0xfb,0x50,0x84,0x97,0xf3,0xed,0x62,0xd0,0x1a,0x30, +0x19,0x06,0x09,0x2a,0x86,0x48,0x86,0xf6,0x7d,0x07,0x41,0x00,0x04,0x0c,0x30,0x0a, +0x1b,0x04,0x56,0x37,0x2e,0x31,0x03,0x02,0x00,0x81,0x30,0x0d,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x54,0x80,0x38, +0xb7,0xb0,0x67,0x2a,0xdd,0xe0,0x10,0xd9,0x0b,0x16,0x65,0xf3,0x96,0x6f,0x41,0x30, +0x3e,0xdf,0xde,0xbb,0xf8,0x5a,0x36,0x51,0x31,0xd7,0x2f,0x0f,0xfa,0x5d,0x23,0x96, +0x98,0xaa,0x45,0xa0,0x18,0x0a,0x82,0x9a,0x11,0x36,0x63,0x58,0x50,0x50,0xa5,0xc1, +0xc3,0x2a,0x3e,0x1d,0xe1,0x6d,0xf6,0x7e,0x3d,0x4a,0xd3,0x99,0xce,0xfe,0xa8,0xaf, +0x0b,0x45,0xc2,0xdb,0xc2,0xb8,0xe9,0x49,0xc5,0xa1,0x62,0xed,0x75,0x66,0xe6,0xde, +0x8b,0x5b,0x73,0x70,0xfa,0x9c,0x4b,0x90,0x51,0x13,0xd7,0x48,0x98,0xc6,0x54,0x12, +0xd4,0xee,0x89,0xc7,0xc9,0xcf,0x00,0x37,0xe7,0xb3,0xd3,0x65,0x8b,0x2c,0xe7,0xf8, +0x3f,0xf1,0x0b,0xe3,0x7a,0x06,0xf9,0x29,0x7e,0xcf,0xb9,0x14,0x76 +}; +static const BYTE cs_stanford_edu[] = { +0x30,0x82,0x05,0x4b,0x30,0x82,0x04,0x33,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x48, +0xdb,0xe2,0x6b,0x07,0xd2,0x79,0x67,0x28,0x23,0xaa,0xaf,0x71,0x4b,0xff,0xc9,0x30, +0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x7b, +0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x47,0x42,0x31,0x1b,0x30, +0x19,0x06,0x03,0x55,0x04,0x08,0x13,0x12,0x47,0x72,0x65,0x61,0x74,0x65,0x72,0x20, +0x4d,0x61,0x6e,0x63,0x68,0x65,0x73,0x74,0x65,0x72,0x31,0x10,0x30,0x0e,0x06,0x03, +0x55,0x04,0x07,0x13,0x07,0x53,0x61,0x6c,0x66,0x6f,0x72,0x64,0x31,0x1a,0x30,0x18, +0x06,0x03,0x55,0x04,0x0a,0x13,0x11,0x43,0x6f,0x6d,0x6f,0x64,0x6f,0x20,0x43,0x41, +0x20,0x4c,0x69,0x6d,0x69,0x74,0x65,0x64,0x31,0x21,0x30,0x1f,0x06,0x03,0x55,0x04, +0x03,0x13,0x18,0x41,0x41,0x41,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, +0x74,0x65,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x30,0x1e,0x17,0x0d,0x30, +0x39,0x30,0x37,0x31,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x31,0x32, +0x30,0x37,0x31,0x36,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x82,0x01,0x15,0x31, +0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x41,0x31,0x0e,0x30,0x0c, +0x06,0x03,0x55,0x04,0x11,0x13,0x05,0x39,0x34,0x33,0x30,0x35,0x31,0x14,0x30,0x12, +0x06,0x03,0x55,0x04,0x08,0x13,0x0b,0x53,0x61,0x6e,0x74,0x61,0x20,0x43,0x6c,0x61, +0x72,0x61,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x07,0x13,0x09,0x50,0x61,0x6c, +0x6f,0x20,0x41,0x6c,0x74,0x6f,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x09,0x13, +0x0e,0x50,0x6f,0x6c,0x79,0x61,0x20,0x48,0x61,0x6c,0x6c,0x20,0x32,0x35,0x31,0x31, +0x1c,0x30,0x1a,0x06,0x03,0x55,0x04,0x0a,0x13,0x13,0x53,0x74,0x61,0x6e,0x66,0x6f, +0x72,0x64,0x20,0x55,0x6e,0x69,0x76,0x65,0x72,0x73,0x69,0x74,0x79,0x31,0x24,0x30, +0x22,0x06,0x03,0x55,0x04,0x0b,0x13,0x1b,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72, +0x20,0x53,0x63,0x69,0x65,0x6e,0x63,0x65,0x20,0x44,0x65,0x70,0x61,0x72,0x74,0x6d, +0x65,0x6e,0x74,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,0x0b,0x13,0x30,0x49,0x73, +0x73,0x75,0x65,0x64,0x20,0x74,0x68,0x72,0x6f,0x75,0x67,0x68,0x20,0x53,0x74,0x61, +0x6e,0x66,0x6f,0x72,0x64,0x20,0x55,0x6e,0x69,0x76,0x65,0x72,0x73,0x69,0x74,0x79, +0x20,0x45,0x2d,0x50,0x4b,0x49,0x20,0x4d,0x61,0x6e,0x61,0x67,0x65,0x72,0x31,0x1a, +0x30,0x18,0x06,0x03,0x55,0x04,0x0b,0x13,0x11,0x43,0x6f,0x6d,0x6f,0x64,0x6f,0x20, +0x49,0x6e,0x73,0x74,0x61,0x6e,0x74,0x53,0x53,0x4c,0x31,0x18,0x30,0x16,0x06,0x03, +0x55,0x04,0x03,0x13,0x0f,0x63,0x73,0x2e,0x73,0x74,0x61,0x6e,0x66,0x6f,0x72,0x64, +0x2e,0x65,0x64,0x75,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, +0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02,0x81,0x81, +0x00,0xc6,0x3a,0x6d,0xf1,0x1e,0xe4,0x69,0xb8,0x32,0xab,0xdb,0xab,0x97,0xe6,0x48, +0xfb,0xba,0xbb,0xce,0xbf,0x34,0x51,0x1b,0xbb,0x17,0x4d,0xac,0x7f,0x46,0xa7,0xe4, +0xbd,0x95,0xb5,0xd1,0x02,0x01,0xcf,0x33,0x94,0xe3,0x42,0xfe,0x50,0x9b,0x20,0xb7, +0x3e,0x49,0x28,0xba,0x34,0x61,0x35,0xa7,0x34,0x44,0x31,0x8b,0xe9,0x6e,0x35,0xd8, +0x36,0xd7,0xd4,0x2e,0x35,0xe1,0x49,0xe7,0x71,0x1f,0x39,0xbf,0x30,0xc4,0x77,0x1b, +0xdf,0xe5,0x12,0x26,0x98,0xf0,0xb1,0x8b,0x3c,0x8f,0x2d,0x18,0x27,0x57,0x62,0x5b, +0x61,0xe0,0xba,0xb0,0xdb,0x43,0xdb,0x71,0x9e,0x43,0x4d,0xc9,0xca,0x35,0x8d,0x32, +0xb4,0x1d,0x26,0x79,0xea,0x6e,0xb2,0x9b,0xb9,0x5a,0x3a,0xd3,0x54,0x09,0xcf,0xbe, +0xf5,0x02,0x03,0x01,0x00,0x01,0xa3,0x82,0x01,0xb1,0x30,0x82,0x01,0xad,0x30,0x1f, +0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x30,0x43,0xdc,0x64,0xcd, +0x19,0x5c,0xa9,0xf3,0x19,0xd2,0x37,0x09,0x96,0x91,0x9e,0x0c,0xe8,0xd6,0x3d,0x30, +0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0x40,0x81,0x69,0xb7,0x41,0xa2, +0xee,0x6d,0x86,0xd0,0x85,0xb8,0x98,0xfd,0x83,0xb8,0xde,0xe9,0xa4,0x36,0x30,0x0e, +0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x05,0xa0,0x30,0x0c, +0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x02,0x30,0x00,0x30,0x1d,0x06,0x03, +0x55,0x1d,0x25,0x04,0x16,0x30,0x14,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03, +0x01,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x30,0x46,0x06,0x03,0x55, +0x1d,0x20,0x04,0x3f,0x30,0x3d,0x30,0x3b,0x06,0x0c,0x2b,0x06,0x01,0x04,0x01,0xb2, +0x31,0x01,0x02,0x01,0x03,0x04,0x30,0x2b,0x30,0x29,0x06,0x08,0x2b,0x06,0x01,0x05, +0x05,0x07,0x02,0x01,0x16,0x1d,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x73,0x65, +0x63,0x75,0x72,0x65,0x2e,0x63,0x6f,0x6d,0x6f,0x64,0x6f,0x2e,0x6e,0x65,0x74,0x2f, +0x43,0x50,0x53,0x30,0x7f,0x06,0x03,0x55,0x1d,0x1f,0x04,0x78,0x30,0x76,0x30,0x3a, +0xa0,0x38,0xa0,0x36,0x86,0x34,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c, +0x2e,0x63,0x6f,0x6d,0x6f,0x64,0x6f,0x63,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x41,0x41, +0x41,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x65,0x72,0x76, +0x69,0x63,0x65,0x73,0x5f,0x32,0x2e,0x63,0x72,0x6c,0x30,0x38,0xa0,0x36,0xa0,0x34, +0x86,0x32,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x63,0x72,0x6c,0x2e,0x63,0x6f,0x6d, +0x6f,0x64,0x6f,0x2e,0x6e,0x65,0x74,0x2f,0x41,0x41,0x41,0x43,0x65,0x72,0x74,0x69, +0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x5f,0x32, +0x2e,0x63,0x72,0x6c,0x30,0x34,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01,0x01, +0x04,0x28,0x30,0x26,0x30,0x24,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x30,0x01, +0x86,0x18,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,0x63,0x73,0x70,0x2e,0x63,0x6f, +0x6d,0x6f,0x64,0x6f,0x63,0x61,0x2e,0x63,0x6f,0x6d,0x30,0x2f,0x06,0x03,0x55,0x1d, +0x11,0x04,0x28,0x30,0x26,0x82,0x0f,0x63,0x73,0x2e,0x73,0x74,0x61,0x6e,0x66,0x6f, +0x72,0x64,0x2e,0x65,0x64,0x75,0x82,0x13,0x77,0x77,0x77,0x2e,0x63,0x73,0x2e,0x73, +0x74,0x61,0x6e,0x66,0x6f,0x72,0x64,0x2e,0x65,0x64,0x75,0x30,0x0d,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x48, +0xe7,0x62,0x8a,0x27,0x72,0x28,0xb1,0x7f,0x7a,0x64,0x92,0xab,0xf9,0x23,0xb3,0xfa, +0x4c,0x3e,0x82,0xe2,0x90,0x20,0x34,0xef,0x6c,0xe7,0x2b,0x2f,0x10,0xc5,0x51,0x2c, +0x33,0xea,0x42,0x11,0xa8,0x79,0x1f,0xe1,0x93,0xc2,0xcf,0xde,0x90,0x49,0xe9,0x2f, +0x1d,0xf3,0x76,0xba,0xc5,0xbe,0x5a,0x69,0xd1,0xb6,0xa5,0xeb,0x8c,0x30,0x27,0xc4, +0x7f,0x07,0x05,0x05,0xa5,0x5c,0x4a,0xd8,0x0b,0x3b,0xdd,0x4e,0x2a,0xc8,0x44,0x40, +0xe7,0xf3,0x7f,0x94,0x73,0x2a,0x51,0x4f,0x89,0x68,0x3f,0xa4,0xd2,0xf4,0xb4,0x86, +0xba,0x0d,0x00,0x21,0xc4,0x0b,0xa6,0xe9,0x47,0x22,0x82,0x49,0xc1,0x87,0x38,0x4f, +0xd5,0x12,0x4f,0xe3,0xb4,0x08,0x49,0xd4,0x15,0xd7,0xb0,0xaa,0xd0,0xae,0xb4,0x9a, +0x9f,0x57,0xb0,0x4b,0x88,0x1d,0x5c,0xb5,0xec,0x66,0x11,0x3e,0x6c,0x11,0x85,0x66, +0x9f,0x71,0xd0,0xc0,0xbd,0x0b,0xbe,0x1a,0x35,0x6f,0x9a,0x9f,0x51,0xf2,0x3b,0xab, +0x1e,0x80,0xc1,0x9c,0x16,0xf7,0xb7,0x0c,0x1e,0xef,0x5f,0xb1,0x4a,0xbf,0x3a,0xfe, +0x48,0x99,0x7c,0x45,0x45,0x35,0x49,0xe1,0x32,0xec,0x55,0x0b,0x19,0xce,0x32,0x71, +0x0c,0x76,0x5a,0xcf,0x26,0x67,0x0d,0x72,0x95,0x32,0x3e,0x6a,0x74,0xf6,0xb1,0xb3, +0xc6,0x64,0x2b,0x20,0xe5,0x96,0x3b,0x7b,0x65,0xa2,0xeb,0xc4,0xff,0x52,0xb5,0x0b, +0x7b,0x47,0x37,0x08,0xdf,0xf7,0xcf,0x08,0x6b,0x9d,0x7c,0xee,0x35,0xdb,0x01,0xf1, +0xa1,0xfa,0x43,0x10,0xd0,0xb6,0x1c,0xfa,0x2a,0x3a,0xc8,0x24,0xab,0x49,0x30 +}; /* chain0_0 -> chain0_1: * A simple, valid chain */ static const BYTE chain0_0[] = { -0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0xa0,0x9a,0x52,0x5b,0xea,0x24,0xa2,0xb8,0x42,0x63,0x07,0xc3,0xda,0x16,0x08, -0x85,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, -0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, -0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, -0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, -0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, -0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, -0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x30,0x82,0x01,0xc2,0x30,0x82,0x01,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x73,0x87,0xdb,0x32,0x3a,0x6c,0x89,0x74,0x0f,0xda,0x07,0xd4,0x6a,0x2c,0x81, +0x59,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, @@ -493,16 +948,19 @@ static const BYTE chain0_0[] = { 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, -0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81, -0x81,0x00,0x98,0x32,0xf8,0xd2,0x7a,0x34,0x64,0x9d,0x40,0xd3,0x85,0x62,0x58, -0x13,0xba,0x2f,0xac,0x2f,0xbd,0x4c,0xe3,0xba,0x05,0xa5,0xbf,0x33,0x4b,0x4a, -0x38,0xd6,0xc9,0x9e,0xa7,0x69,0x95,0xc2,0x67,0x22,0xb6,0xec,0x1f,0x92,0xbc, -0xd3,0xd1,0x59,0x12,0xff,0x83,0xba,0xa1,0x17,0xec,0x52,0x8c,0x21,0x7d,0xf8, -0x68,0x63,0x46,0xbe,0x48,0xd7,0xeb,0x8d,0xbf,0x5e,0x87,0x5f,0xc7,0x56,0x2d, -0xf7,0xf8,0x41,0x8a,0xd1,0xb4,0xe8,0x18,0x71,0xf9,0xf1,0x89,0x7c,0xfc,0x67, -0x9b,0x83,0x5d,0x54,0xb5,0xfd,0x5d,0x94,0x41,0xcd,0x31,0x7d,0x5d,0x02,0x38, -0xff,0x75,0x7d,0xb9,0x86,0x70,0xe4,0x6d,0x96,0x97,0x30,0xeb,0x88,0x45,0xb5, -0x2b,0x7c,0x29,0x84,0x6c,0xe9,0xa3,0xb6,0x11,0x78 }; +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x82,0xcd,0x5c,0x0a, +0x9d,0x0d,0x3f,0xd1,0xd8,0x74,0xfc,0x52,0x65,0x11,0x76,0x10,0x62,0xb0,0x9a, +0xc5,0x54,0x66,0xae,0xfa,0xd5,0x66,0x36,0xcb,0x1e,0xe7,0xad,0xb9,0xfa,0x2e, +0xbb,0xb9,0x0b,0x4b,0xbf,0xe7,0x26,0x75,0x2c,0xae,0x2d,0x14,0x84,0x92,0xae, +0x56,0xdf,0x55,0x56,0xf3,0xa6,0xc5,0x21,0xa8,0x5e,0xce,0x7a,0x9d,0xff,0x7f, +0x10,0xd9,0xc3,0x05,0x52,0x86,0xdc,0x9b,0x46,0xe7,0x69,0xfb,0x1e,0xf0,0x68, +0x7d,0x34,0xd7,0xf3,0x56,0xe3,0x0a,0xf3,0xe4,0xdc,0x0f,0xd6,0x4d,0xa8,0xc5, +0xb5,0x5b,0xbf,0x0b,0x5d,0xe7,0x76,0xa1,0x56,0xc1,0xa7,0x55,0xa0,0x88,0x7f, +0x57,0x8e,0x64,0xda,0x6f,0xaa,0x9c,0xca,0x47,0xf3,0x37,0x08,0x4b,0x9a,0xdc, +0xbc,0x65,0x4d,0x9a }; static const BYTE chain0_1[] = { 0x30,0x82,0x01,0x98,0x30,0x82,0x01,0x01,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, 0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, @@ -568,15 +1026,15 @@ static const BYTE chain1_1[] = { * A chain whose time nesting is invalid. */ static const BYTE chain2_0[] = { -0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0x23,0x82,0x3b,0x9e,0x51,0x6e,0xc9,0x8c,0x4f,0x22,0x48,0x21,0x20,0xb4,0xa3, -0xac,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, -0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, -0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, -0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, -0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, -0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, -0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x30,0x82,0x01,0xc2,0x30,0x82,0x01,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x11,0x58,0x73,0x34,0x62,0x2b,0xa5,0xa5,0x54,0x4a,0x14,0x48,0x3c,0x90,0x4e, +0x86,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x36,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x36,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, @@ -586,16 +1044,19 @@ static const BYTE chain2_0[] = { 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, -0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81, -0x81,0x00,0x18,0x5c,0xb9,0x2f,0x27,0xa5,0x4b,0x2c,0xda,0x04,0x78,0x46,0x5e, -0x36,0xe7,0xc9,0xbb,0x42,0xf6,0x85,0x56,0x45,0xca,0x51,0xb2,0xcf,0x2b,0xbd, -0xed,0x77,0xcf,0x12,0xf5,0x29,0xc2,0x42,0x32,0xf4,0xad,0x25,0xc1,0x17,0xef, -0x93,0xbf,0xa5,0x61,0xb8,0xc7,0x4b,0xae,0xa8,0x1c,0x08,0xda,0x98,0xe0,0x5c, -0x55,0x08,0x74,0xf7,0xf4,0xdc,0x38,0x2b,0xa9,0x2b,0x1e,0x12,0x7b,0xc1,0x61, -0xe5,0x8d,0xf3,0xdc,0x21,0xe2,0xd2,0x56,0x4f,0xb4,0x8d,0x8c,0x36,0x69,0xf8, -0x82,0x83,0x28,0x6d,0x0d,0x81,0x73,0xec,0x41,0x5c,0x90,0x7a,0xc5,0x27,0x36, -0x9d,0xaa,0xf5,0xe0,0x8b,0xf0,0xfa,0x7d,0x41,0x8f,0x6a,0x36,0xa8,0x61,0x75, -0xc0,0xf2,0x06,0xe8,0x83,0xdb,0xbe,0xc4,0x5b,0x72 }; +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x88,0x44,0x83,0xfc, +0x38,0xa4,0x6e,0x53,0x24,0x8f,0xac,0xcf,0xc0,0xb9,0xaa,0xdc,0x5f,0x30,0xf3, +0xc3,0x5c,0xd5,0x10,0x4e,0xb7,0x30,0x24,0x80,0xb3,0x5e,0xcb,0x6a,0xec,0x88, +0xa6,0x02,0xbd,0x37,0x97,0xcc,0x60,0x04,0x03,0xdd,0xfa,0xb0,0x4e,0xd6,0x00, +0x22,0x41,0xaa,0x2b,0x3c,0x3e,0x1f,0xcd,0xe3,0xf0,0x88,0x84,0x1c,0x00,0xc4, +0x97,0x69,0x3d,0x40,0x6d,0x33,0x8c,0xb7,0xb4,0x41,0xf3,0x28,0x00,0xa8,0xa1, +0x81,0x76,0x50,0x69,0xb2,0x2c,0xc4,0x56,0xab,0x2b,0x4a,0x77,0x41,0x3e,0x6c, +0x78,0x0b,0xf9,0x6c,0x86,0x84,0x1a,0x5a,0x0e,0x8c,0x12,0x59,0xbd,0x74,0xf3, +0xb9,0x91,0xa1,0x70,0x91,0xf3,0xe8,0x8d,0x78,0x42,0xc3,0x4f,0xfa,0xef,0xe7, +0xca,0x09,0x5c,0x18 }; /* chain3_0 -> chain0_1: * A chain whose root cannot be a CA. */ @@ -629,19 +1090,19 @@ static const BYTE chain3_0[] = { 0x36,0xe1,0xf1,0x67,0x3a,0x25,0xf3,0x47,0x83,0xce,0x4f,0xb0,0x74,0x7a,0x35, 0xa0,0x7f,0x70,0x64,0x8a,0x14,0x66,0x03,0xf6,0xae,0xdf,0x1b,0xf5,0x80,0x87, 0x06,0x39,0x76,0x70,0x7b,0xd2,0x83,0xe9,0xce,0x1f,0xf8,0x66,0xc1 }; -/* chain4_0 -> chain0_1 -> chain4_2: +/* chain4_0 -> chain4_1 -> chain4_2: * A chain whose path length constraint is violated. */ static const BYTE chain4_0[] = { -0x30,0x82,0x01,0xb3,0x30,0x82,0x01,0x20,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0xcb,0xdc,0x8d,0xca,0xc1,0x0e,0x9c,0x9d,0x4f,0x0a,0xc1,0x09,0x31,0x32,0x94, -0xf9,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, -0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, -0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, -0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, -0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, -0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, -0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x30,0x82,0x01,0xc5,0x30,0x82,0x01,0x30,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x01,0xcd,0x67,0x9e,0xec,0xae,0x1e,0x69,0x16,0x3f,0x92,0x8a,0xed,0x6d,0x57, +0xac,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, @@ -651,18 +1112,50 @@ static const BYTE chain4_0[] = { 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, -0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01, -0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,0x09,0x06,0x05, -0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,0x81,0x00,0x93,0xe8,0x98,0xbe, -0x7b,0x5c,0x4c,0x58,0xbd,0xee,0x31,0x55,0xa8,0xb5,0x86,0xfc,0x23,0x55,0x48, -0xda,0x95,0x60,0x0f,0x53,0x64,0x66,0x50,0x78,0xdc,0x1c,0xf3,0xec,0x38,0x7d, -0x07,0x58,0x19,0xcf,0x83,0xfc,0x92,0xc4,0x3e,0x48,0x5b,0x45,0x54,0xf7,0x15, -0x6f,0xb0,0x5e,0x8c,0xbf,0x03,0x62,0x17,0x27,0x28,0x59,0x49,0xde,0x52,0x2d, -0x4b,0xb3,0x1e,0x4d,0x4f,0x2c,0xa8,0x1e,0x70,0xd1,0xdb,0xe7,0x98,0x6c,0x6f, -0xaa,0x94,0xea,0x5d,0x7f,0xc5,0x1d,0x2a,0x4d,0xb7,0x4c,0xac,0xa6,0xbf,0x79, -0x9a,0xf6,0x1e,0x98,0x64,0x14,0x2e,0xbd,0x8a,0xaf,0xac,0x52,0xd2,0x2c,0xdd, -0xcd,0x1b,0x3d,0x28,0x43,0xea,0x25,0x91,0x15,0xb8,0x54,0x72,0x33,0xca,0xd8, -0x5f,0x06,0x4c,0x97 }; +0x00,0x01,0xa3,0x26,0x30,0x24,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,0x0b,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x70, +0x60,0x8d,0x5f,0x29,0x8e,0x6b,0x48,0x79,0xaa,0xd1,0x7a,0xbb,0x6c,0x7c,0x54, +0x11,0x55,0x08,0xb9,0x2e,0x5e,0x53,0xd6,0x9b,0xb9,0xe4,0xc8,0x0e,0x48,0xe7, +0x20,0x9e,0xbd,0x7c,0x55,0xb8,0xf1,0x69,0x0c,0x08,0xd6,0x32,0x32,0xd9,0x05, +0x81,0x8a,0x33,0x4c,0x57,0x20,0xae,0xe8,0xde,0x61,0x63,0x85,0xc8,0xe1,0x1d, +0xef,0x4b,0xa4,0x42,0x4e,0x0a,0x25,0x48,0x2b,0xc2,0x06,0x79,0x90,0x45,0x90, +0x94,0x3d,0xb0,0x36,0xe6,0x60,0xe6,0xd2,0x1a,0x11,0x01,0x4b,0xaf,0x23,0x4d, +0x62,0x6b,0xdc,0x3a,0xae,0x61,0x93,0xce,0x7b,0xae,0x21,0xfe,0x42,0xd8,0x86, +0x36,0x19,0x00,0x18,0x13,0x4d,0xf9,0xd1,0x94,0xa2,0xb7,0xbd,0xb0,0x5c,0x9b, +0x5c,0x03,0xf5,0x86,0x85,0x07,0x1c }; +static const BYTE chain4_1[] = { +0x30,0x82,0x01,0xb3,0x30,0x82,0x01,0x1e,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,0x0e,0x67,0x5f, +0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,0xb6,0x17,0x8e, +0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,0x9f,0x6e,0xfe, +0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,0xd1,0x57,0x71, +0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,0x72,0xa7,0x87, +0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,0x80,0x83,0x68, +0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,0xb5,0x46,0x36, +0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,0x51,0x9a,0x22, +0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,0x02,0x03,0x01, +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x26,0x56,0x31,0x53, +0x65,0xe3,0xd8,0x59,0xc8,0x6f,0xa3,0x5b,0x8a,0x11,0x53,0xde,0x8d,0x6f,0x6d, +0x8c,0xe1,0x79,0x25,0xb2,0xbf,0xc6,0x3b,0xa1,0x8b,0x6b,0xcd,0x99,0xcf,0x0c, +0x6f,0xaa,0xbc,0xd0,0x3d,0xb2,0xf8,0x1c,0x6f,0xb0,0x84,0x7b,0xb1,0x88,0xec, +0xd6,0x77,0xbe,0xb1,0x0b,0x8c,0x18,0x85,0xb7,0x38,0x81,0x12,0xc9,0xc7,0x4a, +0xf6,0x83,0xc4,0xd9,0xae,0xb6,0x1d,0xbb,0xd2,0x08,0x01,0x4a,0xe1,0xdc,0x8f, +0x67,0xa9,0xed,0xe2,0x3f,0x96,0xf6,0x72,0x7e,0x4a,0x63,0x46,0xc4,0x82,0x89, +0x0a,0x81,0xc8,0x3a,0x9c,0xe7,0x23,0x5f,0x8d,0xd9,0x6c,0xb2,0x5d,0x9a,0x40, +0x04,0x04,0xd5,0x4a,0x29,0x57,0xbd,0x18,0xd8,0xca,0x1f,0xf7,0xf8,0x23,0x07, +0x4b,0x03,0xa3,0xd9 }; static const BYTE chain4_2[] = { 0x30,0x82,0x01,0x98,0x30,0x82,0x01,0x01,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, 0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, @@ -696,15 +1189,15 @@ static const BYTE chain4_2[] = { * A chain whose name constraints aren't met. */ static const BYTE chain5_0[] = { -0x30,0x82,0x01,0xbd,0x30,0x82,0x01,0x2a,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0x80,0xc5,0x90,0x33,0xb6,0xb5,0xf7,0x99,0x4e,0x6d,0xfc,0xf9,0x4a,0xa7,0xcb, -0x20,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, -0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, -0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, -0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, -0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, -0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, -0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x30,0x82,0x01,0xe0,0x30,0x82,0x01,0x4b,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0xed,0xb8,0x3b,0xf2,0x95,0xe6,0x8e,0xdf,0x75,0x6a,0x22,0xbc,0xca,0x51,0xb6, +0x83,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, @@ -714,18 +1207,21 @@ static const BYTE chain5_0[] = { 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, -0x00,0x01,0xa3,0x20,0x30,0x1e,0x30,0x1c,0x06,0x03,0x55,0x1d,0x1e,0x01,0x01, -0xff,0x04,0x12,0x30,0x10,0xa0,0x0e,0x30,0x0c,0x82,0x0a,0x77,0x69,0x6e,0x65, -0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d, -0x05,0x00,0x03,0x81,0x81,0x00,0x17,0x4a,0x31,0x42,0x6a,0x43,0x85,0xf8,0x91, -0x17,0xc2,0x09,0xbe,0xba,0x1f,0x49,0x23,0x2e,0xa1,0x24,0x58,0x46,0xe8,0xfe, -0x6e,0xbc,0x61,0xb9,0x71,0x92,0x99,0x43,0xd4,0x60,0x54,0xe8,0x29,0x78,0x97, -0xb5,0xb4,0x79,0xad,0xe0,0x1e,0x2b,0x8c,0xb8,0x96,0x9f,0xf1,0x23,0x72,0x45, -0xb7,0x1d,0xe1,0xed,0x0a,0x91,0xf3,0x79,0x8b,0x23,0xd8,0xd4,0x10,0x1b,0x9d, -0xf2,0x7b,0xd9,0x6d,0x85,0x23,0x52,0xd5,0xbf,0x56,0x4f,0x81,0x3c,0x8d,0x62, -0x17,0x0b,0xd7,0x2e,0x5b,0xa1,0xee,0x09,0x99,0x39,0x41,0x57,0x8c,0x3b,0xc4, -0x30,0x1d,0xf5,0x87,0x4f,0x81,0x56,0xfa,0xc1,0x83,0x69,0xf2,0x4a,0x97,0xc9, -0xd9,0x20,0xfa,0x09,0x8c,0x9f,0x13,0xfe,0x0f,0x4d,0x50,0xd3,0x24,0x1f }; +0x00,0x01,0xa3,0x41,0x30,0x3f,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1c,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x12,0x30,0x10,0xa0,0x0e,0x30,0x0c,0x82,0x0a,0x77, +0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x7f,0x98,0xd1,0x58, +0x70,0x36,0x2c,0x08,0x63,0x2c,0xf9,0xe0,0x16,0xda,0x59,0xd9,0x1b,0xa5,0xba, +0xe0,0xec,0xd9,0x0a,0x1b,0x78,0xd0,0xea,0x49,0xc7,0x01,0x06,0x78,0xe5,0xb3, +0x81,0x5a,0x53,0x3d,0x9b,0x0d,0xaf,0xc8,0x04,0x57,0x15,0xee,0xfd,0x05,0x80, +0x72,0x8a,0x54,0x51,0x6a,0x15,0xdc,0xbf,0xfc,0xe3,0x04,0xe4,0x6f,0x20,0xb2, +0xfd,0xa6,0x32,0x4c,0xbc,0x1b,0x60,0xf7,0xc3,0x9c,0x5f,0x17,0x94,0xc7,0xdf, +0x9f,0xae,0xdb,0x72,0x8a,0x98,0x28,0x9d,0x26,0x1f,0x14,0x76,0xb1,0x8e,0x26, +0xf6,0x97,0x96,0x57,0x14,0x9e,0x44,0x13,0xef,0x85,0xc1,0x6f,0x38,0xda,0xf2, +0x3a,0xf6,0xad,0x0b,0x35,0xcf,0xea,0xb0,0x5a,0x9c,0x36,0x80,0x45,0x1f,0x88, +0x2f,0xff,0xb4,0xb5 }; static const BYTE chain5_1[] = { 0x30,0x82,0x01,0xb2,0x30,0x82,0x01,0x1b,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, 0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, @@ -757,39 +1253,9 @@ static const BYTE chain5_1[] = { 0xe7,0x8b,0x3b,0x2a,0x2f,0x46,0xed,0xda,0x96,0x1a,0xc1,0x5c,0xfe,0xe0,0xef, 0xdb,0xe0,0x11,0xc4,0x56,0x12,0xe2,0x4b,0x84,0xde,0xaf,0x7f,0x3c,0x9f,0xcb, 0xb6,0xac,0x92 }; -/* chain0_0 -> chain6_1: +/* chain0_0 -> chain4_1: * A chain whose end certificate is a CA. */ -static const BYTE chain6_1[] = { -0x30,0x82,0x01,0xa9,0x30,0x82,0x01,0x12,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, -0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, -0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, -0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30, -0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32, -0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, -0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, -0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, -0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, -0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, -0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, -0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, -0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, -0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, -0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, -0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, -0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, -0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55, -0x1d,0x13,0x01,0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0d,0x06, -0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81, -0x00,0x08,0x71,0x6d,0x6c,0xbf,0xf1,0x0f,0xe9,0x5b,0x9f,0x9c,0x9d,0xa5,0x07, -0x83,0x28,0xa1,0x05,0x0b,0x92,0x73,0xb9,0x8a,0x99,0xbe,0x1e,0x21,0x53,0x9f, -0xae,0x44,0x7b,0x89,0x09,0x36,0x4a,0xef,0xe7,0x73,0x9f,0x84,0x8d,0x9a,0xec, -0x52,0xcd,0x58,0x14,0x2d,0x22,0x5c,0x03,0x6a,0xb3,0x35,0x40,0x35,0x66,0xba, -0xc5,0xe2,0x32,0x72,0x60,0x52,0x86,0xbc,0x6a,0xc3,0x24,0x05,0x6b,0x02,0xe3, -0x70,0xa3,0xad,0x09,0x88,0x1e,0xd1,0x34,0xca,0x52,0x6a,0x55,0x38,0x88,0x60, -0xfa,0x9a,0x1f,0xe9,0x29,0x47,0x54,0x96,0x53,0x65,0x27,0xb1,0x66,0xd0,0x11, -0x1c,0xf6,0x20,0x07,0xb4,0x66,0x88,0x18,0xdc,0x0c,0x57,0x7e,0x1f,0x8a,0x49, -0x7a,0xe2,0x34,0x52,0x0b,0x46,0x6b,0xfd,0x27 }; /* chain0_0 -> chain 7_1: * A chain with a bad critical extension. */ @@ -827,15 +1293,15 @@ static const BYTE chain7_1[] = { * validity time. */ static const BYTE chain8_0[] = { -0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0xfb,0x25,0xa6,0x55,0x98,0xbc,0xdf,0xb7,0x40,0x86,0x44,0xb9,0x36,0x03,0x82, -0x9b,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, -0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, -0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, -0x30,0x5a,0x17,0x0d,0x30,0x37,0x30,0x36,0x30,0x31,0x30,0x30,0x30,0x30,0x30, -0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, -0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, -0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x30,0x82,0x01,0xc2,0x30,0x82,0x01,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x76,0x09,0xeb,0xc1,0x06,0x61,0x69,0x50,0x0e,0x0c,0xaf,0xc9,0x0a,0x6b,0x93, +0x50,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x30,0x36,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, @@ -845,16 +1311,19 @@ static const BYTE chain8_0[] = { 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, -0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81, -0x81,0x00,0x17,0xdf,0x1d,0x1d,0xa3,0x3b,0x0c,0x26,0x3e,0xc7,0x6c,0x8c,0xbd, -0xc7,0x62,0x01,0xba,0xbd,0x2e,0x6a,0x8d,0xe1,0x4e,0x0a,0xc1,0xc1,0x9a,0xb1, -0x43,0x82,0x05,0xb9,0xf8,0x27,0x4d,0x3e,0x8c,0xaa,0xff,0x5c,0x88,0x82,0x3b, -0x09,0xa4,0x23,0x06,0x54,0x16,0xbf,0xc6,0x57,0x6b,0xb1,0x80,0x2c,0xd2,0x7f, -0x28,0xfc,0xb5,0xac,0x5b,0x1f,0x14,0xb9,0xd8,0x49,0x6a,0x0d,0xf1,0x55,0x51, -0xcd,0x0c,0x2b,0x5b,0xfa,0x01,0x08,0x82,0x98,0x6d,0x39,0xde,0x9a,0xb1,0xbf, -0xc5,0xbd,0x05,0xd1,0x64,0x21,0xc4,0x99,0x40,0xdb,0x3e,0xa0,0x8e,0x46,0x80, -0xd0,0x74,0x93,0xbd,0xad,0x81,0xba,0x40,0x8e,0x0a,0x67,0x47,0xc4,0xae,0xd4, -0xca,0xd8,0x3b,0xa4,0xa6,0xbd,0xc8,0xa9,0x67,0xf9 }; +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x87,0x74,0x4a,0xb7, +0xbe,0xd4,0x21,0xa5,0x5f,0x51,0xd6,0xea,0x89,0x4c,0x68,0x16,0x38,0x09,0x49, +0xf5,0xef,0xac,0x0c,0x59,0x27,0xa3,0x0f,0x8f,0xb9,0x21,0x35,0x91,0xef,0x15, +0x91,0xe2,0xac,0xf2,0xad,0xfe,0x05,0x9a,0x9f,0x24,0x81,0x75,0x69,0x57,0x51, +0xe3,0x2f,0x29,0xad,0x55,0x8b,0xc7,0x25,0xbe,0xcd,0x38,0xa7,0xff,0xdb,0xb0, +0x85,0x4e,0x8d,0x56,0x5a,0x79,0xf7,0x7a,0xfb,0x64,0x3d,0x4e,0x04,0x34,0xf7, +0x2f,0x7f,0xe3,0x21,0xee,0x8d,0xd3,0xb0,0x26,0x7d,0xb8,0xc3,0xb6,0x0f,0xe2, +0x3f,0xb6,0x8a,0x53,0x27,0xc0,0xe1,0xfb,0xd8,0xea,0xfe,0xed,0x80,0x51,0xb6, +0x46,0x59,0x65,0x6c,0x34,0x01,0xcc,0x2e,0x50,0xc7,0x4e,0x37,0x83,0x54,0x3f, +0x7b,0xa2,0x1d,0x3a }; static const BYTE chain8_1[] = { 0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00, @@ -1018,15 +1487,15 @@ static const BYTE chain11_1[] = { * A chain whose root has an invalid signature. */ static const BYTE chain12_0[] = { -0x30,0x82,0x01,0x9b,0x30,0x82,0x01,0x08,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, -0x2f,0x67,0x04,0x50,0xe4,0xac,0x81,0x81,0x44,0x25,0x25,0x81,0xbe,0x8a,0x6c, -0x3c,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, -0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, -0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, -0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, -0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, -0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, -0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x30,0x82,0x01,0xc2,0x30,0x82,0x01,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x73,0x87,0xdb,0x32,0x3a,0x6c,0x89,0x74,0x0f,0xda,0x07,0xd4,0x6a,0x2c,0x81, +0x59,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, 0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, 0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, 0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, @@ -1036,16 +1505,19 @@ static const BYTE chain12_0[] = { 0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, 0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, 0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, -0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81, -0x81,0x00,0x82,0xa8,0x28,0x6e,0x85,0xbb,0xa4,0xac,0xf4,0xe3,0xbc,0xe5,0x08, -0x76,0x8a,0x1b,0x51,0xea,0xca,0x49,0x46,0x70,0x75,0x38,0x70,0x71,0xa1,0x1c, -0x67,0x77,0x70,0x7d,0xdf,0xd0,0xc6,0xa4,0xfc,0x30,0x22,0x2f,0x52,0x56,0x16, -0xe7,0xe2,0x7e,0x6a,0xcf,0x24,0x0b,0xe2,0xad,0x94,0x52,0x2c,0xcc,0x56,0xd3, -0x2e,0xe2,0xd3,0x3d,0x2f,0xdb,0x22,0xb2,0xff,0xf3,0x20,0xc1,0x62,0xc2,0x3c, -0x24,0x48,0x19,0x13,0x2c,0x8a,0x80,0xcd,0xb5,0xe1,0x84,0xc2,0xee,0x14,0xfe, -0x59,0xe6,0xed,0x7b,0x8b,0xec,0xcc,0x27,0x56,0xa1,0x0e,0x73,0xe7,0x37,0x20, -0x97,0x27,0x12,0xed,0x9f,0xe9,0xec,0x44,0xde,0x3f,0x07,0xa4,0x07,0x42,0x5b, -0x7e,0xe5,0xe1,0x42,0x10,0x4c,0x38,0xd7,0x2b,0xff }; +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x82,0xcd,0x5c,0x0a, +0x9d,0x0d,0x3f,0xd1,0xd8,0x74,0xfc,0x52,0x65,0x11,0x76,0x10,0x62,0xb0,0x9a, +0xc5,0x54,0x66,0xae,0xfa,0xd5,0x66,0x36,0xcb,0x1e,0xe7,0xad,0xb9,0xfa,0x2e, +0xbb,0xb9,0x0b,0x4b,0xbf,0xe7,0x26,0x75,0x2c,0xae,0x2d,0x14,0x84,0x92,0xae, +0x56,0xdf,0x55,0x56,0xf3,0xa6,0xc5,0x21,0xa8,0x5e,0xce,0x7a,0x9d,0xff,0x7f, +0x10,0xd9,0xc3,0x05,0x52,0x86,0xdc,0x9b,0x46,0xe7,0x69,0xfb,0x1e,0xf0,0x68, +0x7d,0x34,0xd7,0xf3,0x56,0xe3,0x0a,0xf3,0xe4,0xdc,0x0f,0xd6,0x4d,0xa8,0xc5, +0xb5,0x5b,0xbf,0x0b,0x5d,0xe7,0x76,0xa1,0x56,0xc1,0xa7,0x55,0xa0,0x88,0x7f, +0x57,0x8e,0x64,0xda,0x6f,0xaa,0x9c,0xca,0x47,0xf3,0x37,0x08,0x4b,0x9a,0xdc, +0xbc,0x65,0x4d,0xff }; /* chain0_0 -> chain13_1: * A chain whose time validity nesting is invalid. */ @@ -1078,6 +1550,912 @@ static const BYTE chain13_1[] = { 0xf1,0xb0,0x6e,0x82,0x34,0x2b,0x7f,0x3b,0x2e,0x27,0x6b,0xf7,0xde,0x73,0x9a, 0x98,0xac,0x79,0x33,0x1a,0xdd,0x03,0x95,0x60,0x8a,0x08,0xba,0xcb,0x8a,0xbf, 0xea,0xe3 }; +/* chain14_0 -> chain14_1: + * A chain whose root is allowed to sign certificates. + */ +static const BYTE chain14_0[] = { +0x30,0x82,0x01,0xc2,0x30,0x82,0x01,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0xe0,0x3a,0xae,0xb4,0x23,0x65,0x59,0x5c,0x05,0x85,0x76,0x8b,0x8e,0x7f,0xa4, +0x12,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x10,0xb9,0x5c,0x13, +0x7f,0xe9,0xf3,0x45,0xfb,0x40,0xa2,0x2b,0xe6,0x99,0x5e,0x74,0x9a,0x0b,0x15, +0xa0,0x16,0xf2,0xff,0x6e,0xfa,0x92,0x78,0x4f,0x05,0x02,0xbd,0x70,0x4f,0x28, +0x6f,0x43,0xc7,0xaa,0xaf,0xb6,0xd1,0x60,0x77,0xc6,0x8a,0x58,0x85,0xf0,0xac, +0x04,0x90,0x4a,0x06,0xf0,0x17,0x88,0x12,0x90,0x22,0x65,0x98,0xb1,0x67,0x93, +0x8a,0xe6,0x2d,0x54,0x79,0x99,0xd3,0x8c,0xe7,0x86,0xf4,0xec,0x08,0xae,0x18, +0xa3,0xa9,0x23,0x7b,0x4f,0x8d,0xde,0xe6,0xf9,0x11,0x92,0xcf,0xe0,0x45,0xc3, +0x42,0x72,0x43,0x64,0x07,0x8b,0x7f,0x28,0x11,0x0a,0xea,0xf2,0xbd,0x24,0x1b, +0x93,0x5c,0x6f,0xed,0x67,0xae,0xee,0x7e,0x40,0x88,0x8b,0x28,0x2c,0xe7,0xee, +0xec,0x34,0xe0,0x7b }; +static const BYTE chain14_1[] = { +0x30,0x82,0x01,0x8d,0x30,0x81,0xf9,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, +0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,0x10, +0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74, +0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30, +0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39, +0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13, +0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02, +0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,0x0e,0x67,0x5f,0x48, +0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,0xb6,0x17,0x8e,0x20, +0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,0x9f,0x6e,0xfe,0xb8, +0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,0xd1,0x57,0x71,0x3c, +0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,0x72,0xa7,0x87,0x8e, +0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,0x80,0x83,0x68,0x28, +0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,0xb5,0x46,0x36,0x98, +0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,0x51,0x9a,0x22,0x4a, +0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,0x02,0x03,0x01,0x00, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03, +0x81,0x81,0x00,0x63,0x67,0x7f,0x82,0x91,0xe2,0x42,0x45,0x98,0xbc,0xe5,0x03, +0x6c,0x7d,0xc9,0xab,0xdb,0x95,0xc4,0x96,0x86,0xfd,0xcf,0xe6,0x32,0x4a,0x0b, +0x7c,0x5b,0x76,0x39,0x71,0x26,0x54,0x60,0x1d,0xce,0x4f,0x29,0x22,0x9a,0xb7, +0x7d,0x8d,0xfa,0x2c,0x99,0x0d,0xa6,0xa4,0x2e,0xd3,0xf6,0x3e,0xaf,0xea,0x89, +0xa0,0x16,0x40,0x0f,0xf1,0x50,0xaa,0x98,0xdc,0xc2,0x69,0x90,0x6f,0xc6,0x4a, +0xee,0x26,0x9e,0x5e,0x7d,0x4b,0x06,0x65,0x54,0x15,0x67,0x9e,0xe5,0x1d,0x1c, +0x6f,0x0c,0x6e,0x84,0x29,0xf9,0x12,0xe9,0x71,0xdd,0xaf,0x9a,0x3d,0x2a,0xc1, +0x60,0xeb,0x27,0xed,0x7c,0xbf,0xc4,0x84,0x17,0xa5,0xa6,0x41,0x29,0x13,0x8d, +0x6c,0xdd,0x7c,0x3d,0x01,0x03,0xf8,0x70,0x97,0x3c,0x45 }; +/* chain15_0 -> chain14_1: + * A chain whose root is not allowed to sign certificates. + */ +static const BYTE chain15_0[] = { +0x30,0x82,0x01,0xc2,0x30,0x82,0x01,0x2d,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x10,0xb3,0x62,0xed,0xed,0x4a,0x92,0xda,0x74,0x62,0x74,0x48,0x99,0xa5,0xe9, +0x0d,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x00,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x51,0x48,0x43,0xc9, +0xe3,0xb4,0xbc,0xc1,0x1d,0x98,0x14,0x69,0xd9,0xec,0x83,0x4d,0x07,0x70,0x58, +0xe9,0x45,0x88,0xe5,0x11,0x4a,0xf0,0x58,0x2d,0x8d,0x08,0x35,0x76,0x0e,0x42, +0x9f,0x62,0xda,0xf9,0x71,0x51,0x58,0xc7,0xd3,0x7e,0x88,0x6a,0x92,0xd2,0xfe, +0x86,0x4f,0xa2,0x17,0xe3,0xdd,0x9b,0x55,0xe0,0xdc,0xa7,0xe7,0x08,0xe0,0x0a, +0xa6,0xf3,0x09,0x17,0x63,0x10,0x89,0xe6,0x07,0x00,0x8e,0x2c,0x44,0x79,0x3e, +0x6c,0x51,0x9a,0xa3,0x59,0x17,0x8b,0x90,0xa8,0x82,0x64,0x09,0x77,0x95,0x55, +0xd6,0x38,0x43,0x8c,0x66,0xe6,0x7b,0xb9,0xf4,0xe1,0x7b,0x86,0x9b,0x8e,0xe3, +0x56,0xc9,0x62,0x62,0x6e,0x3d,0x4d,0x67,0x8d,0x5e,0x20,0xe5,0xd0,0xfa,0xaa, +0xbe,0x91,0xa8,0xf1 }; +/* chain0_0 -> chain16_1: + * A chain whose end cert has a name constraints extension saying it can't + * be a CA, and which also has a key usage extension allowing it to sign + * certs. + */ +static const BYTE chain16_1[] = { +0x30,0x82,0x01,0xb0,0x30,0x82,0x01,0x1b,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,0x0e,0x67,0x5f, +0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,0xb6,0x17,0x8e, +0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,0x9f,0x6e,0xfe, +0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,0xd1,0x57,0x71, +0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,0x72,0xa7,0x87, +0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,0x80,0x83,0x68, +0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,0xb5,0x46,0x36, +0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,0x51,0x9a,0x22, +0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,0x02,0x03,0x01, +0x00,0x01,0xa3,0x20,0x30,0x1e,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0c,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x02,0x30,0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, +0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x47,0xdb,0xb4,0x95,0xb1,0xe2,0x5c, +0x03,0x3b,0x28,0x16,0x6b,0xed,0xe9,0x38,0xeb,0x74,0xe6,0xde,0xc5,0xaf,0x93, +0xad,0x2e,0xaa,0x29,0x14,0x21,0xae,0xe9,0x7d,0x46,0x18,0x05,0x67,0xad,0x2d, +0xaa,0xfa,0xf8,0x41,0xc8,0x8c,0xde,0xe0,0xd7,0x3e,0x9a,0x89,0x58,0x71,0x73, +0x57,0xc1,0xd9,0x42,0x51,0xfb,0xaa,0xb8,0x50,0x98,0x9b,0x87,0xb1,0x14,0xa2, +0x23,0xa7,0xfc,0x51,0x23,0x97,0x9f,0xef,0x06,0x83,0x63,0x91,0x14,0xc3,0xbe, +0xaa,0xc8,0x7c,0x03,0x0e,0x41,0x5a,0x23,0x9c,0x1d,0x32,0x3a,0xa5,0xf1,0x6a, +0x56,0x6c,0x36,0xe3,0x3d,0xa1,0xac,0x8e,0x1a,0x75,0x30,0x1c,0xd8,0xbc,0xae, +0x3e,0x4a,0x1a,0x05,0xf4,0x09,0x24,0xb2,0x89,0x75,0xa4,0x28,0x78,0x6b,0xfa, +0xcc }; +/* chain0_0 -> chain17_1 -> chain17_2: + * A root cert, an intermediate cert that's a CA and allowed to sign a cert, + * and an end cert. + */ +static const BYTE chain17_1[] = { +0x30,0x82,0x01,0xb3,0x30,0x82,0x01,0x1e,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,0x0e,0x67,0x5f, +0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,0xb6,0x17,0x8e, +0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,0x9f,0x6e,0xfe, +0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,0xd1,0x57,0x71, +0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,0x72,0xa7,0x87, +0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,0x80,0x83,0x68, +0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,0xb5,0x46,0x36, +0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,0x51,0x9a,0x22, +0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,0x02,0x03,0x01, +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x26,0x56,0x31,0x53, +0x65,0xe3,0xd8,0x59,0xc8,0x6f,0xa3,0x5b,0x8a,0x11,0x53,0xde,0x8d,0x6f,0x6d, +0x8c,0xe1,0x79,0x25,0xb2,0xbf,0xc6,0x3b,0xa1,0x8b,0x6b,0xcd,0x99,0xcf,0x0c, +0x6f,0xaa,0xbc,0xd0,0x3d,0xb2,0xf8,0x1c,0x6f,0xb0,0x84,0x7b,0xb1,0x88,0xec, +0xd6,0x77,0xbe,0xb1,0x0b,0x8c,0x18,0x85,0xb7,0x38,0x81,0x12,0xc9,0xc7,0x4a, +0xf6,0x83,0xc4,0xd9,0xae,0xb6,0x1d,0xbb,0xd2,0x08,0x01,0x4a,0xe1,0xdc,0x8f, +0x67,0xa9,0xed,0xe2,0x3f,0x96,0xf6,0x72,0x7e,0x4a,0x63,0x46,0xc4,0x82,0x89, +0x0a,0x81,0xc8,0x3a,0x9c,0xe7,0x23,0x5f,0x8d,0xd9,0x6c,0xb2,0x5d,0x9a,0x40, +0x04,0x04,0xd5,0x4a,0x29,0x57,0xbd,0x18,0xd8,0xca,0x1f,0xf7,0xf8,0x23,0x07, +0x4b,0x03,0xa3,0xd9 }; +static const BYTE chain17_2[] = { +0x30,0x82,0x01,0x8d,0x30,0x81,0xf9,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, +0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,0x10, +0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74, +0x32,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30, +0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39, +0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13, +0x05,0x43,0x65,0x72,0x74,0x33,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02, +0x81,0x81,0x00,0xc3,0x31,0x35,0xc3,0x9d,0x8a,0x87,0x20,0xc6,0x32,0xe9,0xb1, +0xf6,0x8f,0xf9,0x05,0x73,0x1d,0xa7,0xde,0xab,0x15,0x8a,0x9c,0x7f,0x11,0x7e, +0x77,0xa0,0x42,0x80,0xf4,0x79,0xda,0x98,0x7b,0x00,0xfa,0x8f,0x0c,0xd0,0xeb, +0x8a,0x80,0xed,0x07,0xfc,0x64,0x71,0x03,0xc1,0xd6,0x2f,0x9b,0xde,0x42,0x63, +0xd9,0x79,0xea,0xdd,0x10,0xe8,0x68,0xc8,0x69,0x4f,0x4a,0x39,0x23,0x87,0xca, +0xd1,0xc9,0x77,0x14,0x30,0x85,0x9e,0xf7,0x79,0xf9,0x07,0xb7,0x7c,0x55,0xcb, +0xa7,0xd5,0xb8,0x44,0xb5,0x20,0xb5,0x01,0x5c,0xa2,0xd1,0xd5,0xad,0x0f,0x87, +0xaf,0x37,0xd1,0x39,0x0c,0x0d,0xd5,0xde,0x26,0x7a,0xed,0xf9,0x2a,0xb1,0x60, +0x65,0x2d,0x08,0x24,0x51,0x1d,0xb0,0x0a,0xb5,0x13,0xc7,0x02,0x03,0x01,0x00, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03, +0x81,0x81,0x00,0x5c,0xb5,0x55,0xd7,0x2c,0x70,0xc5,0x6e,0xc0,0x8e,0x30,0x1f, +0xf2,0x8e,0x55,0xd6,0xf6,0x95,0xa4,0x51,0xd8,0xf0,0x39,0x98,0x12,0x57,0xa7, +0x6d,0x0c,0xfd,0xcb,0x25,0xf1,0xc4,0x73,0x85,0x78,0x82,0x15,0x12,0x08,0xb6, +0x05,0x85,0x4f,0x5a,0x59,0x1f,0x03,0xdf,0x04,0xef,0xc2,0xb0,0xee,0xd7,0x73, +0x09,0xca,0xbb,0xfb,0xd8,0xec,0x8b,0x39,0x01,0x14,0xc9,0x03,0xc9,0x08,0x4d, +0x97,0xc7,0xf2,0x0b,0x54,0x67,0xf7,0x7c,0xc6,0xee,0x74,0xd5,0xa2,0x10,0x3e, +0xd9,0x3a,0x7a,0x9d,0xeb,0xeb,0xd8,0x8e,0x43,0x74,0xc3,0xa5,0x3b,0x1a,0x4b, +0x8a,0xbc,0x6a,0x2c,0x15,0x4b,0x72,0x0b,0xac,0xa4,0x1a,0x97,0x80,0xf8,0xb1, +0xd3,0xd7,0x1a,0xf3,0xf5,0x9f,0x7c,0x4c,0x7d,0x7c,0xc7 }; +/* chain0_0 -> chain18_1 -> chain18_2: + * A root, an intermediate CA not allowed to sign certs, and an end cert. + */ +static const BYTE chain18_1[] = { +0x30,0x82,0x01,0xb3,0x30,0x82,0x01,0x1e,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30, +0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72, +0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35, +0x39,0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03, +0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33,0x0e,0x67,0x5f, +0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc,0xb6,0x17,0x8e, +0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48,0x9f,0x6e,0xfe, +0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47,0xd1,0x57,0x71, +0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05,0x72,0xa7,0x87, +0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a,0x80,0x83,0x68, +0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85,0xb5,0x46,0x36, +0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3,0x51,0x9a,0x22, +0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3,0x02,0x03,0x01, +0x00,0x01,0xa3,0x23,0x30,0x21,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x00,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03,0x81,0x81,0x00,0x2c,0x49,0x9f,0xc2, +0xce,0xf5,0x0d,0x59,0xaa,0xff,0xa0,0x72,0xa7,0xcf,0x4c,0x35,0xc5,0x5e,0x1b, +0x32,0xe6,0x46,0x53,0x3e,0x70,0xe6,0xbc,0xa2,0x37,0xe0,0x9d,0x41,0x40,0x12, +0x9e,0x81,0x2b,0xd9,0x46,0x3a,0xdc,0xd7,0x37,0xc4,0xbf,0x0f,0x0c,0xf8,0x74, +0x7a,0xf9,0x92,0x2d,0xf8,0xfe,0xec,0x17,0xfb,0x38,0x4f,0x83,0x02,0x6f,0x49, +0xb4,0xad,0xb2,0x84,0x41,0x13,0x71,0x32,0xee,0x34,0x8d,0xea,0x2b,0x64,0x9b, +0x26,0x76,0xe9,0xcc,0xdf,0x73,0xe0,0x84,0xc1,0x8b,0xea,0xfc,0x8c,0x18,0x93, +0xfd,0xa3,0x5f,0x8f,0xde,0x05,0x11,0x88,0x62,0x0b,0x03,0x35,0x1a,0xef,0x65, +0x82,0x06,0xc8,0xa5,0xf6,0xd2,0x1e,0x46,0xc2,0x86,0xe7,0x26,0x8e,0x9e,0x10, +0x33,0xe2,0x89,0x93 }; +static const BYTE chain18_2[] = { +0x30,0x82,0x01,0x8d,0x30,0x81,0xf9,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, +0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x30,0x10, +0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74, +0x32,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30, +0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39, +0x35,0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13, +0x05,0x43,0x65,0x72,0x74,0x33,0x30,0x81,0x9d,0x30,0x0b,0x06,0x09,0x2a,0x86, +0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x03,0x81,0x8d,0x00,0x30,0x81,0x89,0x02, +0x81,0x81,0x00,0xc3,0x31,0x35,0xc3,0x9d,0x8a,0x87,0x20,0xc6,0x32,0xe9,0xb1, +0xf6,0x8f,0xf9,0x05,0x73,0x1d,0xa7,0xde,0xab,0x15,0x8a,0x9c,0x7f,0x11,0x7e, +0x77,0xa0,0x42,0x80,0xf4,0x79,0xda,0x98,0x7b,0x00,0xfa,0x8f,0x0c,0xd0,0xeb, +0x8a,0x80,0xed,0x07,0xfc,0x64,0x71,0x03,0xc1,0xd6,0x2f,0x9b,0xde,0x42,0x63, +0xd9,0x79,0xea,0xdd,0x10,0xe8,0x68,0xc8,0x69,0x4f,0x4a,0x39,0x23,0x87,0xca, +0xd1,0xc9,0x77,0x14,0x30,0x85,0x9e,0xf7,0x79,0xf9,0x07,0xb7,0x7c,0x55,0xcb, +0xa7,0xd5,0xb8,0x44,0xb5,0x20,0xb5,0x01,0x5c,0xa2,0xd1,0xd5,0xad,0x0f,0x87, +0xaf,0x37,0xd1,0x39,0x0c,0x0d,0xd5,0xde,0x26,0x7a,0xed,0xf9,0x2a,0xb1,0x60, +0x65,0x2d,0x08,0x24,0x51,0x1d,0xb0,0x0a,0xb5,0x13,0xc7,0x02,0x03,0x01,0x00, +0x01,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x03, +0x81,0x81,0x00,0x5c,0xb5,0x55,0xd7,0x2c,0x70,0xc5,0x6e,0xc0,0x8e,0x30,0x1f, +0xf2,0x8e,0x55,0xd6,0xf6,0x95,0xa4,0x51,0xd8,0xf0,0x39,0x98,0x12,0x57,0xa7, +0x6d,0x0c,0xfd,0xcb,0x25,0xf1,0xc4,0x73,0x85,0x78,0x82,0x15,0x12,0x08,0xb6, +0x05,0x85,0x4f,0x5a,0x59,0x1f,0x03,0xdf,0x04,0xef,0xc2,0xb0,0xee,0xd7,0x73, +0x09,0xca,0xbb,0xfb,0xd8,0xec,0x8b,0x39,0x01,0x14,0xc9,0x03,0xc9,0x08,0x4d, +0x97,0xc7,0xf2,0x0b,0x54,0x67,0xf7,0x7c,0xc6,0xee,0x74,0xd5,0xa2,0x10,0x3e, +0xd9,0x3a,0x7a,0x9d,0xeb,0xeb,0xd8,0x8e,0x43,0x74,0xc3,0xa5,0x3b,0x1a,0x4b, +0x8a,0xbc,0x6a,0x2c,0x15,0x4b,0x72,0x0b,0xac,0xa4,0x1a,0x97,0x80,0xf8,0xb1, +0xd3,0xd7,0x1a,0xf3,0xf5,0x9f,0x7c,0x4c,0x7d,0x7c,0xc7 }; +/* A chain which allows a.com, where the end cert is issued to a.com */ +static const BYTE chain19_0[] = { +0x30,0x82,0x01,0xd9,0x30,0x82,0x01,0x46,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x22,0xf4,0xa5,0xbe,0xe7,0x5f,0x91,0x89,0x4b,0x10,0x5c,0x86,0x89,0x94,0x36, +0xab,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3c,0x30,0x3a,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x17,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0d,0x30,0x0b,0xa0,0x09,0x30,0x07,0x82,0x05,0x61, +0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00, +0x03,0x81,0x81,0x00,0x19,0x84,0xa8,0xed,0x39,0xb3,0xc0,0x7e,0xc1,0x50,0x50, +0xb7,0x4c,0xf2,0xf4,0x16,0xc8,0x2a,0x00,0xc9,0x9e,0x0a,0x77,0x7f,0x65,0xb0, +0xe9,0x46,0x88,0x39,0x03,0xd9,0xcc,0x83,0x27,0x22,0xd3,0xec,0x98,0xb3,0x0d, +0xf6,0x85,0xe2,0x3f,0x82,0x02,0x96,0xd2,0x9f,0x17,0xcb,0x7c,0x06,0xbb,0xe5, +0x58,0x0d,0x9e,0xc3,0x01,0xcd,0xba,0xee,0x26,0x7d,0xc6,0x2b,0x50,0xa7,0xf3, +0x9e,0x28,0x87,0xa8,0x9a,0x8b,0x1c,0x73,0x79,0x3e,0xed,0xa0,0xcf,0x70,0xf0, +0x53,0x89,0x1f,0xbf,0x0d,0x6b,0x30,0xb1,0x5e,0x16,0x6d,0x57,0x81,0xe9,0xad, +0x63,0xe5,0x03,0x50,0x99,0x3d,0xb3,0xad,0x1d,0x9c,0x6b,0x32,0xea,0xc3,0x7f, +0x54,0x22,0x89,0x69,0xbf,0x73,0xdc,0x87,0xff,0x4b,0xf1,0xf6 }; +static const BYTE chain19_1[] = { +0x30,0x82,0x01,0xaa,0x30,0x82,0x01,0x13,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x14,0x30,0x12,0x30,0x10,0x06,0x03,0x55, +0x1d,0x07,0x04,0x09,0x30,0x07,0x82,0x05,0x61,0x2e,0x63,0x6f,0x6d,0x30,0x0d, +0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81, +0x81,0x00,0x8e,0x1d,0xf5,0xac,0x59,0x8e,0x39,0x7a,0x4d,0x79,0x79,0x68,0xa9, +0x13,0x25,0xbf,0x71,0x62,0x73,0x55,0xb0,0x22,0xcb,0x8a,0x22,0xa2,0x4f,0xa3, +0xfc,0x22,0xa3,0x2c,0x4c,0xe3,0x95,0xc6,0x97,0xe1,0x97,0xf1,0xee,0xb0,0xb4, +0xac,0x7a,0x80,0xe3,0xdd,0x02,0x5a,0x42,0x30,0xe7,0x27,0x0e,0x69,0xff,0x6b, +0xb2,0x83,0x7a,0x4f,0xc7,0xaa,0x05,0x95,0xb5,0x18,0x5f,0xa8,0x29,0x97,0x3b, +0xf2,0xb8,0x35,0x06,0x1b,0xfe,0xfa,0xa8,0x91,0xc7,0xb7,0x1b,0x8b,0xaa,0xd5, +0x23,0x88,0x7f,0xd9,0x88,0x45,0xee,0xd4,0xb9,0xcd,0x36,0xd4,0x5a,0x28,0x86, +0x0d,0x92,0x5d,0xcb,0x8c,0xf1,0xd9,0xfb,0xcc,0xa4,0x65,0xda,0x8d,0x6e,0xfd, +0x99,0xed,0xf1,0xc6,0x45,0xdf,0x5b,0x1f,0xf5,0xa0 }; +/* A chain which allows a.com, where the end cert is issued to b.com */ +static const BYTE chain20_0[] = { +0x30,0x82,0x01,0xd9,0x30,0x82,0x01,0x46,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x5e,0xf5,0xbf,0x5a,0x8d,0x92,0xd9,0x8e,0x46,0x09,0xbf,0x50,0x27,0x2f,0xc1, +0x4b,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3c,0x30,0x3a,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x17,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0d,0x30,0x0b,0xa0,0x09,0x30,0x07,0x82,0x05,0x61, +0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00, +0x03,0x81,0x81,0x00,0x4e,0xd8,0x55,0xa5,0x18,0xa8,0xc3,0xc4,0xa2,0xed,0x11, +0xff,0x12,0x78,0xbe,0xa5,0xaf,0x6c,0x9f,0xa5,0x94,0x46,0xd3,0x74,0x8e,0x44, +0x45,0x9f,0xf2,0xf9,0x0b,0xbe,0x28,0x08,0xf2,0x28,0x4a,0xd5,0x00,0x71,0xb2, +0xa5,0x01,0x3b,0x86,0xd6,0x8f,0xb8,0x9a,0xbc,0x8e,0xe4,0x33,0x9e,0xc2,0x5d, +0xcc,0x5c,0x24,0x90,0x52,0xbc,0xe6,0x83,0x38,0x77,0xd6,0x25,0x1b,0xfa,0x37, +0xc1,0xf6,0x22,0xa7,0xff,0xc6,0x4b,0x16,0x73,0xf5,0xca,0x04,0xad,0xa5,0x71, +0xff,0x15,0x5b,0x34,0x84,0xd4,0x45,0xce,0xfb,0xd1,0x76,0x13,0x2f,0x53,0x3e, +0x82,0xba,0x2f,0x53,0x82,0x48,0xcb,0x3a,0x77,0xd4,0xb0,0x0f,0xb5,0x38,0x68, +0x73,0x3f,0x49,0x60,0x0f,0x61,0x58,0xae,0x25,0xd8,0xe6,0x73 }; +static const BYTE chain20_1[] = { +0x30,0x82,0x01,0xaa,0x30,0x82,0x01,0x13,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x14,0x30,0x12,0x30,0x10,0x06,0x03,0x55, +0x1d,0x07,0x04,0x09,0x30,0x07,0x82,0x05,0x62,0x2e,0x63,0x6f,0x6d,0x30,0x0d, +0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81, +0x81,0x00,0x17,0xbb,0xec,0x37,0x4c,0xaf,0x0f,0xb0,0x57,0x04,0x01,0x67,0x69, +0x77,0xe4,0x73,0xc4,0x12,0x0a,0xa5,0xfe,0x0c,0x8b,0x89,0x90,0x98,0x0d,0x3b, +0x37,0xbe,0xe7,0x7e,0xba,0x84,0x27,0x5f,0xed,0x40,0xc9,0x57,0x91,0x6b,0x72, +0xe3,0x4c,0xfa,0x9f,0x6d,0xd5,0xe6,0xf8,0x33,0xa1,0x6e,0xbd,0x5f,0x8d,0xfb, +0x8f,0xe6,0xe1,0x6a,0x64,0x51,0x1e,0x3b,0x04,0xe4,0x3b,0xa2,0x49,0x15,0x23, +0x35,0x17,0x61,0x4a,0xa6,0x03,0xee,0xa2,0xa6,0x4f,0x42,0x13,0x75,0x14,0xd3, +0x87,0x3b,0x71,0x6a,0x2f,0x11,0xcd,0xe6,0xd0,0x63,0xce,0x62,0x8c,0xd9,0x64, +0xc0,0xaa,0x53,0x4e,0x5e,0xa2,0x4c,0x6e,0xd0,0x13,0x49,0x2e,0xdf,0x81,0x3a, +0x3c,0x67,0xcf,0x4e,0xde,0x95,0x14,0x74,0xa8,0x31 }; +/* A chain which allows A.com, where the end cert is issued to a.COM */ +static const BYTE chain21_0[] = { +0x30,0x82,0x01,0xd9,0x30,0x82,0x01,0x46,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x66,0xaf,0x57,0xcc,0x4b,0x41,0xd1,0x96,0x40,0xef,0xa4,0xc9,0xe0,0x96,0xad, +0x5c,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3c,0x30,0x3a,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x17,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0d,0x30,0x0b,0xa0,0x09,0x30,0x07,0x82,0x05,0x41, +0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00, +0x03,0x81,0x81,0x00,0x66,0x0e,0x8e,0x3d,0x1b,0xe8,0x51,0x2d,0x5f,0xfa,0xf5, +0x01,0xb1,0xf8,0x8e,0x65,0xf6,0xcf,0x63,0x40,0x27,0x20,0x41,0xfc,0xa2,0x97, +0x14,0x8d,0x46,0x33,0x3b,0x79,0xc7,0x3d,0xc8,0x1d,0xb3,0xf1,0xf3,0x52,0xfb, +0x76,0x55,0x00,0xb9,0x4d,0x89,0x4c,0xfd,0xa9,0xcc,0xa0,0x96,0x86,0x15,0x40, +0xfc,0xd2,0x5b,0x60,0xca,0x9c,0x00,0xf8,0x02,0x6a,0x56,0x1c,0x79,0x94,0x01, +0x8a,0x60,0x44,0x1a,0x2f,0x34,0x94,0xb6,0xfb,0x00,0xa7,0xd1,0x47,0xd8,0x8f, +0xf7,0xf5,0xfc,0xfd,0xeb,0xf7,0xa1,0xab,0xa7,0x38,0x13,0x16,0x50,0x04,0x8e, +0xf2,0x17,0x45,0xac,0x10,0x83,0x08,0x1c,0x0d,0xe9,0xa9,0xea,0x4e,0x0e,0x06, +0x09,0xca,0xb3,0x54,0xd1,0x44,0x10,0x47,0xac,0xaf,0xbc,0xbb }; +static const BYTE chain21_1[] = { +0x30,0x82,0x01,0xaa,0x30,0x82,0x01,0x13,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x14,0x30,0x12,0x30,0x10,0x06,0x03,0x55, +0x1d,0x07,0x04,0x09,0x30,0x07,0x82,0x05,0x61,0x2e,0x43,0x4f,0x4d,0x30,0x0d, +0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81, +0x81,0x00,0x65,0xd5,0xaa,0x17,0x1f,0xa8,0xda,0x62,0x04,0x9d,0xf5,0xe0,0x82, +0xe4,0xed,0xc6,0x1b,0x54,0x8f,0xb7,0x46,0xac,0xcd,0xaf,0xaa,0xe3,0xd8,0x4a, +0x8b,0xd9,0xe6,0x87,0x4f,0x8c,0xa6,0x86,0x97,0x75,0x08,0x42,0xf1,0xed,0x3e, +0x70,0x99,0x13,0xf2,0x00,0xf8,0xcc,0xf4,0x55,0x36,0xf5,0x29,0x97,0x47,0x71, +0xb8,0x40,0x8d,0x47,0x03,0xe2,0x66,0x3c,0x00,0x01,0xcc,0xa7,0x39,0xf7,0xf9, +0x76,0xfc,0x14,0x31,0x1f,0x6f,0xf0,0x87,0xe0,0x43,0x8b,0xad,0x98,0xa2,0xe3, +0xfe,0x49,0xa3,0x1e,0x57,0x34,0xe8,0x61,0x97,0x23,0xc8,0x03,0x05,0xa4,0x2f, +0xab,0x49,0x97,0xff,0x3f,0xbf,0x6c,0x08,0x2c,0x6b,0x4d,0x6a,0x54,0x62,0x2e, +0x16,0x83,0xac,0xdd,0x21,0x8f,0xe7,0x71,0x12,0x5f }; +/* A chain which allows A.com, where the end cert is issued to b.COM */ +static const BYTE chain22_0[] = { +0x30,0x82,0x01,0xd9,0x30,0x82,0x01,0x46,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x75,0xff,0x32,0x4c,0x24,0xbb,0x4e,0xb9,0x45,0x70,0xc3,0x4a,0xe1,0xfd,0xdb, +0xdc,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3c,0x30,0x3a,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x17,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0d,0x30,0x0b,0xa0,0x09,0x30,0x07,0x82,0x05,0x41, +0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00, +0x03,0x81,0x81,0x00,0x43,0x9b,0xcf,0x0d,0x31,0x9a,0x33,0x9d,0x7a,0xf8,0x2b, +0x5a,0x6f,0x52,0x68,0x25,0x7e,0x14,0x04,0xb1,0x88,0x90,0xa3,0xa8,0x4e,0xa8, +0x0c,0xc2,0x06,0x35,0x6c,0xb9,0x07,0x9a,0x28,0xd0,0x54,0xad,0x5f,0xc7,0x5e, +0xbf,0x1d,0xde,0x3d,0x76,0x6d,0x32,0x6c,0xc2,0x95,0x26,0x8e,0x6a,0xc5,0xfd, +0x45,0x47,0x3a,0x2e,0x81,0x47,0x37,0xf9,0xe3,0xdb,0x57,0xd5,0x24,0xe9,0x10, +0x91,0x55,0xbf,0x48,0xaa,0x27,0x7a,0x32,0xc8,0x96,0xbc,0xd8,0x9d,0xb5,0x03, +0x6e,0x64,0x50,0xa6,0x9d,0xc2,0xd9,0xdb,0x67,0x8d,0xad,0x76,0x82,0x75,0x42, +0x78,0x38,0x3c,0x31,0x55,0x1e,0x8f,0xbb,0x18,0xc9,0xf3,0xa4,0x49,0xc7,0x24, +0x1a,0x9b,0xef,0x61,0x03,0x75,0xb7,0x2b,0x8b,0xd4,0x50,0x8b }; +static const BYTE chain22_1[] = { +0x30,0x82,0x01,0xaa,0x30,0x82,0x01,0x13,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x14,0x30,0x12,0x30,0x10,0x06,0x03,0x55, +0x1d,0x07,0x04,0x09,0x30,0x07,0x82,0x05,0x62,0x2e,0x43,0x4f,0x4d,0x30,0x0d, +0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81, +0x81,0x00,0x4b,0x4c,0x2f,0x68,0xd2,0x64,0x82,0x7d,0x95,0x1d,0xd0,0x2b,0xa4, +0xab,0xc3,0x9d,0xd8,0xc1,0x0f,0xaa,0x3e,0xc6,0xa3,0x11,0x9a,0xc6,0x58,0x40, +0x49,0xcc,0x92,0x8e,0xd4,0x0d,0x20,0x81,0x65,0x59,0xca,0x7d,0x54,0xce,0xd4, +0x43,0x95,0xb5,0xc3,0x8c,0x79,0x01,0xc6,0x17,0xf8,0x04,0x13,0xf7,0x7c,0xf7, +0x7f,0xd7,0xc6,0x62,0x2c,0x21,0x0d,0xab,0x79,0x82,0xd7,0x70,0x9f,0x38,0xba, +0x5f,0x2f,0xb4,0xfd,0xe8,0x62,0x40,0xe3,0x69,0xe7,0xc4,0xe5,0x5a,0xc1,0x71, +0xc0,0x9a,0xdc,0xcc,0xa6,0x0e,0x5e,0x84,0x27,0x70,0xc3,0x47,0x98,0x72,0x89, +0xf9,0x7c,0xe4,0x15,0x4b,0x4c,0xec,0x56,0x1b,0xbf,0x6c,0xf1,0xf7,0x5a,0x76, +0x80,0x1f,0x43,0x7c,0xae,0xdb,0xb3,0x49,0xbc,0xcb }; +/* A chain which allows *.com, where the end cert is issued to foo.com */ +static const BYTE chain23_0[] = { +0x30,0x82,0x01,0xd9,0x30,0x82,0x01,0x46,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x70,0x29,0x25,0xb2,0x21,0xd9,0x44,0x8a,0x4b,0x9d,0xf3,0x4e,0x6b,0xdb,0x7c, +0xa7,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3c,0x30,0x3a,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x17,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0d,0x30,0x0b,0xa0,0x09,0x30,0x07,0x82,0x05,0x2a, +0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00, +0x03,0x81,0x81,0x00,0x39,0x5b,0xf7,0xc9,0x4e,0xac,0x65,0x8b,0x56,0xf4,0xaf, +0x23,0xaa,0x1b,0x95,0x0a,0x6e,0x62,0xa8,0x39,0xa0,0xc7,0x86,0x6f,0xb2,0xac, +0x45,0xb6,0x99,0x21,0x66,0x48,0x1a,0x7d,0xe9,0xa9,0xfe,0x5c,0xc6,0xa7,0x25, +0x89,0x66,0x84,0xc4,0x8e,0x05,0x3b,0x53,0xcf,0xee,0x78,0x88,0x85,0xf1,0x8f, +0xce,0x6e,0x72,0xc6,0x0c,0x06,0x3d,0xa6,0x12,0xad,0x0a,0x07,0xbb,0x16,0x2f, +0x0c,0x96,0x0c,0x78,0x31,0xfa,0x93,0x5a,0x2d,0x8d,0x02,0xf5,0xb0,0x1c,0x83, +0x53,0x14,0xc6,0xa6,0x29,0xa6,0xfe,0xb1,0xc0,0x65,0x72,0x47,0xe9,0xf6,0x01, +0x09,0xa4,0xff,0xd2,0x60,0x87,0x81,0xc1,0xb4,0xe7,0xe8,0x3e,0x9a,0xba,0x25, +0xb2,0x36,0x50,0xc4,0xf8,0xb1,0x94,0x07,0xba,0xdd,0x6a,0x95 }; +static const BYTE chain23_1[] = { +0x30,0x82,0x01,0xac,0x30,0x82,0x01,0x15,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55, +0x1d,0x07,0x04,0x0b,0x30,0x09,0x82,0x07,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d, +0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00, +0x03,0x81,0x81,0x00,0xa5,0xc0,0xf6,0xb1,0x63,0x3a,0x23,0xc5,0xb0,0x07,0xb4, +0x83,0xcf,0x36,0xb4,0xfe,0x3c,0xcb,0xa6,0x6b,0xed,0xf7,0x4c,0x25,0x9f,0x2d, +0x88,0xcd,0x8a,0xe4,0x88,0xe3,0x33,0xbb,0x50,0x54,0xee,0xc9,0xad,0xed,0x8b, +0xec,0x1e,0x64,0x36,0xe8,0xb5,0x51,0xca,0xd3,0xa5,0xb9,0x7a,0x2d,0x4b,0xe7, +0xe8,0xc9,0xa5,0x1d,0x49,0xa1,0x31,0x0f,0x50,0x46,0xb0,0x0f,0xd0,0xf6,0xad, +0x51,0x18,0x93,0x25,0x8f,0x4f,0x57,0x12,0x72,0x1e,0xa7,0x44,0x37,0x9f,0xf2, +0xc0,0x28,0xe8,0xbe,0xb8,0x75,0x42,0xef,0x1d,0x7a,0xca,0x87,0x0c,0x11,0x25, +0xeb,0xab,0xcf,0xe0,0xe1,0x12,0x38,0xf6,0x68,0x31,0xfb,0x16,0xcb,0xef,0x67, +0x8c,0x4b,0x6b,0xfd,0x69,0xba,0x0b,0x69,0xee,0x74,0xe0,0x73 }; +/* A chain which allows *.com, where the end cert is issued to foo.bar.com */ +static const BYTE chain24_0[] = { +0x30,0x82,0x01,0xd9,0x30,0x82,0x01,0x46,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x57,0xa6,0x19,0xe0,0x2a,0x65,0x89,0x8d,0x4c,0xd9,0x58,0x8f,0xd0,0xe5,0x5a, +0x02,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3c,0x30,0x3a,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x17,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0d,0x30,0x0b,0xa0,0x09,0x30,0x07,0x82,0x05,0x2a, +0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00, +0x03,0x81,0x81,0x00,0x44,0xec,0x96,0x0c,0x82,0x70,0xd6,0x4f,0xa0,0xa0,0x9e, +0x6f,0xfc,0x93,0xcb,0xbb,0x9b,0xb7,0x34,0xf9,0x9c,0x00,0x00,0x7e,0x11,0xeb, +0x38,0x85,0x8d,0xc9,0xc5,0x69,0x05,0x8e,0xcd,0x82,0x6c,0xe4,0xe5,0xb8,0x63, +0xa6,0x8b,0xe5,0x17,0x9e,0x24,0x67,0x34,0xdd,0x4c,0x62,0xdd,0x08,0xfe,0xdc, +0x90,0xe1,0x8e,0x02,0xfe,0xe9,0xc4,0x19,0xfc,0x7d,0xef,0x24,0xcc,0x99,0x9f, +0x11,0x81,0x6a,0x4d,0x46,0xc8,0x48,0x73,0xc8,0x52,0x89,0xab,0xc7,0x0d,0x9b, +0x77,0xc0,0xbc,0xb5,0x57,0x51,0x2e,0x64,0xad,0x98,0x39,0xd3,0x6d,0xe9,0xe1, +0x58,0x32,0x01,0xfa,0xc7,0xa9,0x89,0x58,0x86,0x3c,0x34,0xc3,0x90,0xd6,0xed, +0x4a,0xdc,0x23,0x66,0xc5,0xab,0x76,0xb9,0x47,0xc8,0x00,0x4c }; +static const BYTE chain24_1[] = { +0x30,0x82,0x01,0xb0,0x30,0x82,0x01,0x19,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x1a,0x30,0x18,0x30,0x16,0x06,0x03,0x55, +0x1d,0x07,0x04,0x0f,0x30,0x0d,0x82,0x0b,0x66,0x6f,0x6f,0x2e,0x62,0x61,0x72, +0x2e,0x63,0x6f,0x6d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x28,0x64,0x0b,0xad,0x9f,0x12,0xd4, +0x77,0xbe,0x1d,0x20,0x3b,0x69,0x74,0xce,0x91,0x69,0xbe,0x3f,0x76,0x1d,0xe7, +0x81,0x92,0x2b,0xdc,0xbb,0xf9,0xd9,0xba,0xf0,0xba,0x58,0x4a,0x9b,0x47,0x59, +0x34,0xf7,0x19,0xb5,0x15,0x31,0x35,0x4a,0x6d,0x7b,0x91,0x3d,0xc2,0x6c,0x8f, +0x58,0x27,0x0f,0x79,0x96,0x57,0xee,0x4e,0x66,0x3e,0xfa,0x5c,0x22,0xb9,0x57, +0xbf,0x8e,0x7e,0xce,0x98,0x62,0x28,0xb1,0x39,0x0e,0x2d,0x7b,0x5d,0x23,0x70, +0xf0,0x4a,0x63,0x11,0x66,0x80,0xf9,0x99,0x53,0x80,0xda,0x87,0x87,0xf7,0x3c, +0x44,0x76,0x66,0x26,0xa7,0x05,0x3c,0x68,0x66,0x1c,0x07,0x4d,0xcf,0x54,0xaa, +0x5d,0xba,0x7a,0x8f,0x06,0xa7,0x1e,0x86,0xf1,0x5a,0x4b,0x50,0x16,0xad,0x9f, +0x89 }; +/* A chain which allows f*.com, where the end cert is issued to foo.com */ +static const BYTE chain25_0[] = { +0x30,0x82,0x01,0xda,0x30,0x82,0x01,0x47,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x58,0x61,0x5e,0xb3,0x52,0x48,0xc2,0xa7,0x4a,0xa4,0x70,0x8a,0x64,0x96,0xac, +0xc6,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3d,0x30,0x3b,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x18,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0e,0x30,0x0c,0xa0,0x0a,0x30,0x08,0x82,0x06,0x66, +0x2a,0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05, +0x00,0x03,0x81,0x81,0x00,0x18,0xb1,0xb1,0x84,0x3c,0x55,0x29,0xfc,0xd0,0xa7, +0xcd,0x40,0x88,0x9b,0x35,0x9a,0x14,0xa1,0x34,0xd7,0x20,0xd9,0xfb,0x52,0x2f, +0xba,0x6c,0x19,0x5c,0xdc,0x0b,0x0b,0xa5,0x21,0xf9,0x0f,0x98,0x23,0xb6,0xcd, +0x36,0x3f,0xed,0xeb,0xf3,0x10,0xbf,0x62,0x33,0xbb,0xb1,0x94,0x79,0x45,0xe4, +0x42,0x2b,0x9e,0x32,0x53,0x18,0x19,0x59,0x4d,0xc9,0x2d,0x65,0xa4,0xcb,0xd4, +0x0b,0x90,0x2a,0xfe,0xea,0x7f,0x10,0xa9,0xb7,0x65,0xf8,0xc3,0xad,0x26,0x4c, +0x29,0x45,0x60,0xce,0x6a,0x63,0x3e,0xa4,0x6f,0x47,0xaf,0x96,0xea,0xc4,0x35, +0xb0,0x83,0xd7,0x52,0xa9,0x1a,0xd0,0x9a,0x6d,0xac,0xcf,0x6a,0xa6,0xe8,0x8e, +0x52,0x61,0x34,0x95,0xd2,0x22,0x83,0x1f,0x86,0x15,0xa0,0x91,0x2b }; +static const BYTE chain25_1[] = { +0x30,0x82,0x01,0xac,0x30,0x82,0x01,0x15,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55, +0x1d,0x07,0x04,0x0b,0x30,0x09,0x82,0x07,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d, +0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00, +0x03,0x81,0x81,0x00,0xa5,0xc0,0xf6,0xb1,0x63,0x3a,0x23,0xc5,0xb0,0x07,0xb4, +0x83,0xcf,0x36,0xb4,0xfe,0x3c,0xcb,0xa6,0x6b,0xed,0xf7,0x4c,0x25,0x9f,0x2d, +0x88,0xcd,0x8a,0xe4,0x88,0xe3,0x33,0xbb,0x50,0x54,0xee,0xc9,0xad,0xed,0x8b, +0xec,0x1e,0x64,0x36,0xe8,0xb5,0x51,0xca,0xd3,0xa5,0xb9,0x7a,0x2d,0x4b,0xe7, +0xe8,0xc9,0xa5,0x1d,0x49,0xa1,0x31,0x0f,0x50,0x46,0xb0,0x0f,0xd0,0xf6,0xad, +0x51,0x18,0x93,0x25,0x8f,0x4f,0x57,0x12,0x72,0x1e,0xa7,0x44,0x37,0x9f,0xf2, +0xc0,0x28,0xe8,0xbe,0xb8,0x75,0x42,0xef,0x1d,0x7a,0xca,0x87,0x0c,0x11,0x25, +0xeb,0xab,0xcf,0xe0,0xe1,0x12,0x38,0xf6,0x68,0x31,0xfb,0x16,0xcb,0xef,0x67, +0x8c,0x4b,0x6b,0xfd,0x69,0xba,0x0b,0x69,0xee,0x74,0xe0,0x73 }; +/* A chain which allows f*.com, where the end cert is issued to bar.com */ +static const BYTE chain26_0[] = { +0x30,0x82,0x01,0xda,0x30,0x82,0x01,0x47,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x6f,0x9d,0x2b,0x8a,0x6d,0xf2,0xd4,0x9f,0x42,0xea,0x3d,0x16,0xe8,0xa5,0x80, +0x7e,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3d,0x30,0x3b,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x18,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0e,0x30,0x0c,0xa0,0x0a,0x30,0x08,0x82,0x06,0x66, +0x2a,0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05, +0x00,0x03,0x81,0x81,0x00,0x6c,0x34,0x75,0x37,0xd9,0x65,0x9e,0x20,0x05,0x67, +0x16,0x2e,0xc9,0x53,0xc1,0x69,0x53,0xd6,0x00,0x2c,0x92,0x53,0x91,0xa2,0x2a, +0x94,0x2c,0xfa,0x6f,0xc1,0x7e,0xee,0x3c,0x22,0x06,0xcc,0xd1,0xdc,0xd7,0x21, +0x6a,0xf2,0xd3,0x1b,0xaf,0x34,0x20,0x97,0x0f,0xa1,0xec,0x7f,0x72,0x22,0xf2, +0x98,0x5d,0xf4,0x0b,0x83,0x23,0xa7,0x73,0xb2,0xde,0x12,0x56,0xc9,0x11,0xa6, +0x5d,0xbc,0x32,0x79,0x41,0x8b,0xe6,0x8c,0x9c,0xf9,0x78,0xd2,0x20,0x96,0x27, +0x85,0x41,0xc1,0xb8,0x8a,0x74,0x1e,0xbb,0x27,0xc1,0xf7,0xaf,0xe8,0x1c,0x21, +0xe4,0x10,0x64,0x6a,0xdf,0x79,0x30,0x29,0x0e,0x5a,0x04,0x48,0x18,0xdd,0xb0, +0xaa,0x43,0x08,0x71,0x2e,0x49,0x9f,0x9b,0xc1,0x1a,0xcc,0x5f,0xee }; +static const BYTE chain26_1[] = { +0x30,0x82,0x01,0xac,0x30,0x82,0x01,0x15,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55, +0x1d,0x07,0x04,0x0b,0x30,0x09,0x82,0x07,0x62,0x61,0x72,0x2e,0x63,0x6f,0x6d, +0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00, +0x03,0x81,0x81,0x00,0x47,0xa6,0x37,0x73,0x4f,0x19,0xf9,0xaf,0xa9,0xb5,0xa8, +0x41,0x99,0x31,0xa5,0xaa,0x0d,0x6c,0xb8,0x9d,0xe6,0xf6,0x59,0x4d,0xd8,0x12, +0x76,0xcc,0x0b,0xaa,0x2f,0x08,0x1c,0x75,0x54,0x5a,0xae,0x09,0x39,0x25,0xfc, +0x44,0xa1,0x00,0x24,0x5c,0xec,0x20,0x04,0xc7,0xe9,0x14,0xb0,0x71,0x4a,0x33, +0x41,0x7f,0x1d,0x47,0xe5,0x7c,0xe4,0x86,0xb1,0xeb,0xa4,0x9d,0x2a,0x89,0xeb, +0x1d,0x15,0xd6,0x42,0x39,0xe4,0x05,0x26,0xbf,0xc2,0x09,0x6c,0x5c,0xd1,0x56, +0xfd,0x18,0x42,0xd3,0xd5,0x7c,0x52,0xa8,0x4a,0x77,0xe8,0xc0,0x53,0x2b,0xa6, +0x01,0xf9,0x90,0x68,0x60,0x3f,0xcb,0xb8,0x24,0x16,0x0b,0x69,0x4b,0xd9,0xf8, +0x2c,0x92,0xed,0x89,0xa5,0xff,0x71,0xc5,0xed,0xe8,0xbc,0x70 }; +/* A chain which allows foo.com, where the end cert is issued to + * foo.com\0baddie + */ +static const BYTE chain27_0[] = { +0x30,0x82,0x01,0xdb,0x30,0x82,0x01,0x48,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x3d,0xd2,0x79,0xf1,0xa7,0x1a,0xac,0xb2,0x43,0x5e,0x53,0x67,0xc9,0xa1,0x8c, +0x53,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x3e,0x30,0x3c,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x19,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x0f,0x30,0x0d,0xa0,0x0b,0x30,0x09,0x82,0x07,0x66, +0x6f,0x6f,0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d, +0x05,0x00,0x03,0x81,0x81,0x00,0x18,0x5d,0xb0,0x42,0x96,0xf7,0x96,0x7b,0x23, +0x46,0xa9,0xf4,0x99,0x57,0x27,0x8e,0x24,0xae,0x29,0xb8,0x04,0xe3,0x1b,0x64, +0x22,0x8e,0x20,0xf1,0x45,0xb8,0x84,0x38,0x41,0x99,0x73,0xb2,0xbc,0xd9,0xcb, +0x9d,0x9f,0xf4,0x86,0xed,0x21,0x34,0x42,0x21,0xf4,0x8f,0xa7,0xcf,0x19,0xe5, +0xd3,0x4f,0x7c,0x4f,0xc7,0x9e,0x91,0x3a,0x16,0x0b,0x61,0x9e,0xfa,0x08,0x1b, +0x01,0xc0,0x19,0xeb,0xe8,0xd4,0x5a,0xe9,0xe0,0x71,0x04,0xaa,0x88,0x93,0x10, +0x3e,0xc5,0x23,0xbe,0x0b,0xab,0xa9,0x07,0x46,0x4d,0x4b,0xf2,0x95,0xeb,0x69, +0xf2,0x70,0x33,0x5c,0xf7,0xd1,0xa9,0x5b,0xd2,0x84,0x10,0xa6,0x00,0xbe,0xb5, +0xd4,0xe7,0xa3,0x54,0x63,0x3c,0xca,0xb0,0xbf,0x96,0xd1,0x6f,0x64,0xaf }; +static const BYTE chain27_1[] = { +0x30,0x82,0x01,0xb3,0x30,0x82,0x01,0x1c,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x1d,0x30,0x1b,0x30,0x19,0x06,0x03,0x55, +0x1d,0x07,0x04,0x12,0x30,0x10,0x82,0x0e,0x66,0x6f,0x6f,0x2e,0x63,0x6f,0x6d, +0x00,0x62,0x61,0x64,0x64,0x69,0x65,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x6f,0x06,0xc6,0xd0, +0xa1,0x8c,0xc6,0xed,0x33,0x04,0xf6,0x64,0x81,0xa1,0x0f,0x79,0x4d,0x9a,0xbd, +0xc0,0x8f,0x18,0xc2,0xb8,0x82,0xb9,0x70,0x6f,0xbe,0xaa,0xbb,0x43,0x95,0x79, +0x58,0xec,0xdf,0x94,0x8b,0x4d,0xe1,0xee,0x56,0xc4,0x57,0x7c,0xff,0xde,0x5f, +0x52,0xf9,0x3a,0x9e,0x33,0x99,0x6e,0xdf,0xf2,0xce,0x40,0xc7,0xd8,0xb5,0x86, +0xae,0xb7,0x52,0x8b,0xc5,0x62,0x17,0xce,0x03,0x06,0x29,0x5a,0xf6,0x5a,0x9a, +0x8e,0xb7,0xe3,0xb2,0xcd,0x3f,0xa7,0x61,0x2b,0xba,0xe6,0x68,0xa8,0x92,0x8a, +0xe5,0x32,0xe0,0x49,0xd4,0x42,0xc0,0x1a,0x92,0x72,0xb0,0x66,0x48,0x84,0x74, +0xd3,0x25,0xe3,0x66,0x2f,0x30,0xea,0x40,0x72,0x82,0xc4,0xc5,0x4a,0x4e,0xcc, +0x32,0xbc,0x36,0xa4 }; +/* A chain which allows foo.*.com, where the end cert is issued to foo.bar.com. + */ +static const BYTE chain28_0[] = { +0x30,0x82,0x01,0xdd,0x30,0x82,0x01,0x4a,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x72,0x7f,0x98,0xcd,0x99,0xa6,0x5f,0x89,0x4a,0x5c,0xd2,0x15,0xd0,0x68,0x25, +0xc8,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x40,0x30,0x3e,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x04,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1b,0x06,0x03,0x55,0x1d, +0x1e,0x01,0x01,0xff,0x04,0x11,0x30,0x0f,0xa0,0x0d,0x30,0x0b,0x82,0x09,0x66, +0x6f,0x6f,0x2e,0x2a,0x2e,0x63,0x6f,0x6d,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03, +0x02,0x1d,0x05,0x00,0x03,0x81,0x81,0x00,0x01,0x9a,0x8c,0x75,0x20,0x9f,0x91, +0xe9,0xde,0x28,0x3c,0x7a,0xd9,0xf1,0x2d,0xa3,0x0d,0x66,0x9f,0xd8,0x2a,0xb0, +0xb5,0x19,0x9a,0x29,0xc7,0xd5,0xe5,0xf6,0x75,0xee,0x06,0xe4,0xd2,0x71,0x77, +0x7e,0xbc,0x1a,0x5f,0xbe,0x28,0xba,0x6e,0x50,0x8e,0xe6,0xd9,0xd5,0x5a,0x21, +0xa6,0x29,0xff,0xb0,0xc7,0xfe,0x06,0xb6,0xde,0x51,0x5b,0xab,0xe4,0xbb,0xbf, +0xaa,0x03,0xa9,0xfe,0x71,0xb8,0x3f,0x65,0xe2,0x2c,0xa9,0x31,0x18,0x6d,0xe6, +0x54,0xd0,0x90,0x6b,0x7b,0x3a,0x9a,0x45,0xa9,0x1b,0x05,0x2e,0xca,0xd7,0x5f, +0x79,0x3d,0x1c,0xbf,0xdb,0xce,0x23,0x5d,0x0a,0x9b,0xb4,0x91,0xfe,0xd4,0x94, +0x92,0x76,0x36,0xae,0x03,0xb8,0x30,0x13,0x58,0x69,0x71,0xea,0xc2,0xbc,0x31, +0x83 }; +static const BYTE chain28_1[] = { +0x30,0x82,0x01,0xb0,0x30,0x82,0x01,0x19,0xa0,0x03,0x02,0x01,0x02,0x02,0x01, +0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05, +0x00,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43, +0x65,0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55, +0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06, +0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5, +0x33,0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6, +0xdc,0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7, +0x48,0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b, +0x47,0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b, +0x05,0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc, +0x6a,0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85, +0x85,0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2, +0xd3,0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72, +0xa3,0x02,0x03,0x01,0x00,0x01,0xa3,0x1a,0x30,0x18,0x30,0x16,0x06,0x03,0x55, +0x1d,0x07,0x04,0x0f,0x30,0x0d,0x82,0x0b,0x66,0x6f,0x6f,0x2e,0x62,0x61,0x72, +0x2e,0x63,0x6f,0x6d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x28,0x64,0x0b,0xad,0x9f,0x12,0xd4, +0x77,0xbe,0x1d,0x20,0x3b,0x69,0x74,0xce,0x91,0x69,0xbe,0x3f,0x76,0x1d,0xe7, +0x81,0x92,0x2b,0xdc,0xbb,0xf9,0xd9,0xba,0xf0,0xba,0x58,0x4a,0x9b,0x47,0x59, +0x34,0xf7,0x19,0xb5,0x15,0x31,0x35,0x4a,0x6d,0x7b,0x91,0x3d,0xc2,0x6c,0x8f, +0x58,0x27,0x0f,0x79,0x96,0x57,0xee,0x4e,0x66,0x3e,0xfa,0x5c,0x22,0xb9,0x57, +0xbf,0x8e,0x7e,0xce,0x98,0x62,0x28,0xb1,0x39,0x0e,0x2d,0x7b,0x5d,0x23,0x70, +0xf0,0x4a,0x63,0x11,0x66,0x80,0xf9,0x99,0x53,0x80,0xda,0x87,0x87,0xf7,0x3c, +0x44,0x76,0x66,0x26,0xa7,0x05,0x3c,0x68,0x66,0x1c,0x07,0x4d,0xcf,0x54,0xaa, +0x5d,0xba,0x7a,0x8f,0x06,0xa7,0x1e,0x86,0xf1,0x5a,0x4b,0x50,0x16,0xad,0x9f, +0x89 }; typedef struct _CONST_DATA_BLOB { @@ -1359,13 +2737,12 @@ static const SimpleChainStatusCheck simpleStatus3[] = { }; static CONST_DATA_BLOB chain4[] = { { sizeof(chain4_0), chain4_0 }, - { sizeof(chain0_1), chain0_1 }, + { sizeof(chain4_1), chain4_1 }, { sizeof(chain4_2), chain4_2 }, }; static const CERT_TRUST_STATUS elementStatus4[] = { { CERT_TRUST_IS_NOT_TIME_VALID, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, - { CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_NOT_TIME_VALID, - CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_INVALID_BASIC_CONSTRAINTS, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, { CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_NAME_MATCH_ISSUER | CERT_TRUST_IS_SELF_SIGNED }, }; @@ -1387,7 +2764,7 @@ static const SimpleChainStatusCheck simpleStatus5[] = { }; static CONST_DATA_BLOB chain6[] = { { sizeof(chain0_0), chain0_0 }, - { sizeof(chain6_1), chain6_1 }, + { sizeof(chain4_1), chain4_1 }, }; static const CERT_TRUST_STATUS elementStatus6[] = { { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, @@ -1478,6 +2855,202 @@ static const CERT_TRUST_STATUS elementStatus13[] = { static const SimpleChainStatusCheck simpleStatus13[] = { { sizeof(elementStatus13) / sizeof(elementStatus13[0]), elementStatus13 }, }; +static CONST_DATA_BLOB chain14[] = { + { sizeof(chain14_0), chain14_0 }, + { sizeof(chain14_1), chain14_1 }, +}; +static const CERT_TRUST_STATUS elementStatus14[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus14[] = { + { sizeof(elementStatus14) / sizeof(elementStatus14[0]), elementStatus14 }, +}; +static CONST_DATA_BLOB chain15[] = { + { sizeof(chain15_0), chain15_0 }, + { sizeof(chain14_1), chain14_1 }, +}; +static const CERT_TRUST_STATUS elementStatus15[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus15[] = { + { sizeof(elementStatus15) / sizeof(elementStatus15[0]), elementStatus15 }, +}; +static CONST_DATA_BLOB chain16[] = { + { sizeof(chain0_0), chain0_0 }, + { sizeof(chain16_1), chain16_1 }, +}; +static const CERT_TRUST_STATUS elementStatus16[] = { + { CERT_TRUST_NO_ERROR | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, + CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus16[] = { + { sizeof(elementStatus16) / sizeof(elementStatus16[0]), elementStatus16 }, +}; +static CONST_DATA_BLOB chain17[] = { + { sizeof(chain0_0), chain0_0 }, + { sizeof(chain17_1), chain17_1 }, + { sizeof(chain17_2), chain17_2 }, +}; +static const CERT_TRUST_STATUS elementStatus17[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus17[] = { + { sizeof(elementStatus17) / sizeof(elementStatus17[0]), elementStatus17 }, +}; +static CONST_DATA_BLOB chain18[] = { + { sizeof(chain0_0), chain0_0 }, + { sizeof(chain18_1), chain18_1 }, + { sizeof(chain18_2), chain18_2 }, +}; +static const CERT_TRUST_STATUS elementStatus18[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_NOT_VALID_FOR_USAGE, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus18[] = { + { sizeof(elementStatus18) / sizeof(elementStatus18[0]), elementStatus18 }, +}; +static CONST_DATA_BLOB chain19[] = { + { sizeof(chain19_0), chain19_0 }, + { sizeof(chain19_1), chain19_1 }, +}; +static const CERT_TRUST_STATUS elementStatus19[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus19[] = { + { sizeof(elementStatus19) / sizeof(elementStatus19[0]), elementStatus19 }, +}; +static CONST_DATA_BLOB chain20[] = { + { sizeof(chain20_0), chain20_0 }, + { sizeof(chain20_1), chain20_1 }, +}; +static const CERT_TRUST_STATUS elementStatus20[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus20[] = { + { sizeof(elementStatus20) / sizeof(elementStatus20[0]), elementStatus20 }, +}; +static CONST_DATA_BLOB chain21[] = { + { sizeof(chain21_0), chain21_0 }, + { sizeof(chain21_1), chain21_1 }, +}; +static const CERT_TRUST_STATUS elementStatus21[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus21[] = { + { sizeof(elementStatus21) / sizeof(elementStatus21[0]), elementStatus21 }, +}; +static CONST_DATA_BLOB chain22[] = { + { sizeof(chain22_0), chain22_0 }, + { sizeof(chain22_1), chain22_1 }, +}; +static const CERT_TRUST_STATUS elementStatus22[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus22[] = { + { sizeof(elementStatus22) / sizeof(elementStatus22[0]), elementStatus22 }, +}; +static CONST_DATA_BLOB chain23[] = { + { sizeof(chain23_0), chain23_0 }, + { sizeof(chain23_1), chain23_1 }, +}; +static const CERT_TRUST_STATUS elementStatus23[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus23[] = { + { sizeof(elementStatus23) / sizeof(elementStatus23[0]), elementStatus23 }, +}; +static CONST_DATA_BLOB chain24[] = { + { sizeof(chain24_0), chain24_0 }, + { sizeof(chain24_1), chain24_1 }, +}; +static const CERT_TRUST_STATUS elementStatus24[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus24[] = { + { sizeof(elementStatus24) / sizeof(elementStatus24[0]), elementStatus24 }, +}; +static CONST_DATA_BLOB chain25[] = { + { sizeof(chain25_0), chain25_0 }, + { sizeof(chain25_1), chain25_1 }, +}; +static const CERT_TRUST_STATUS elementStatus25[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus25[] = { + { sizeof(elementStatus25) / sizeof(elementStatus25[0]), elementStatus25 }, +}; +static CONST_DATA_BLOB chain26[] = { + { sizeof(chain26_0), chain26_0 }, + { sizeof(chain26_1), chain26_1 }, +}; +static const CERT_TRUST_STATUS elementStatus26[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus26[] = { + { sizeof(elementStatus26) / sizeof(elementStatus26[0]), elementStatus26 }, +}; +static CONST_DATA_BLOB chain27[] = { + { sizeof(chain27_0), chain27_0 }, + { sizeof(chain27_1), chain27_1 }, +}; +static const CERT_TRUST_STATUS elementStatus27[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_INVALID_NAME_CONSTRAINTS | + CERT_TRUST_INVALID_EXTENSION, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus27[] = { + { sizeof(elementStatus27) / sizeof(elementStatus27[0]), elementStatus27 }, +}; +static const CERT_TRUST_STATUS elementStatus27Broken[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER | + CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS }, +}; +static const SimpleChainStatusCheck simpleStatus27Broken[] = { + { sizeof(elementStatus27Broken) / sizeof(elementStatus27Broken[0]), + elementStatus27Broken }, +}; +static CONST_DATA_BLOB chain28[] = { + { sizeof(chain28_0), chain28_0 }, + { sizeof(chain28_1), chain28_1 }, +}; +static const CERT_TRUST_STATUS elementStatus28[] = { + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER }, +}; +static const SimpleChainStatusCheck simpleStatus28[] = { + { sizeof(elementStatus28) / sizeof(elementStatus28[0]), elementStatus28 }, +}; static CONST_DATA_BLOB selfSignedChain[] = { { sizeof(selfSignedCert), selfSignedCert } }; @@ -1493,8 +3066,6 @@ static CONST_DATA_BLOB iTunesChain[] = { { sizeof(verisignCA), verisignCA }, { sizeof(iTunesCert0), iTunesCert0 }, { sizeof(iTunesCert1), iTunesCert1 }, - { sizeof(iTunesCert2), iTunesCert2 }, - { sizeof(iTunesCert3), iTunesCert3 }, }; static const CERT_TRUST_STATUS iTunesElementStatus[] = { { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_KEY_MATCH_ISSUER }, @@ -1506,6 +3077,61 @@ static const SimpleChainStatusCheck iTunesSimpleStatus[] = { { sizeof(iTunesElementStatus) / sizeof(iTunesElementStatus[0]), iTunesElementStatus }, }; +static CONST_DATA_BLOB googleChain[] = { + { sizeof(verisignCA), verisignCA }, + { sizeof(thawte_sgc_ca), thawte_sgc_ca }, + { sizeof(google), google }, +}; +/* The Google cert is only valid from 3/27/2009 to 3/27/2010, so with the date + * tested (October 2007) it's not time valid. + */ +static const CERT_TRUST_STATUS googleElementStatus[] = { + { CERT_TRUST_IS_NOT_TIME_VALID, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_NAME_MATCH_ISSUER }, + { CERT_TRUST_NO_ERROR, + CERT_TRUST_HAS_NAME_MATCH_ISSUER | CERT_TRUST_IS_SELF_SIGNED}, +}; +static const SimpleChainStatusCheck googleSimpleStatus[] = { + { sizeof(googleElementStatus) / sizeof(googleElementStatus[0]), + googleElementStatus }, +}; +/* The openssl cert is only valid from 9/12/2008 to 9/13/2012, so with the date + * tested (October 2007) it's not time valid. + */ +static CONST_DATA_BLOB opensslChain[] = { + { sizeof(global_sign_root), global_sign_root }, + { sizeof(global_sign_ca), global_sign_ca }, + { sizeof(openssl_org), openssl_org }, +}; +static const CERT_TRUST_STATUS opensslElementStatus[] = { + { CERT_TRUST_IS_NOT_TIME_VALID, CERT_TRUST_HAS_KEY_MATCH_ISSUER }, + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_KEY_MATCH_ISSUER }, + { CERT_TRUST_NO_ERROR, + CERT_TRUST_HAS_NAME_MATCH_ISSUER | CERT_TRUST_IS_SELF_SIGNED}, +}; +static const SimpleChainStatusCheck opensslSimpleStatus[] = { + { sizeof(opensslElementStatus) / sizeof(opensslElementStatus[0]), + opensslElementStatus }, +}; +/* entrust_ca -> aaa_certificate_services -> cs_stanford_edu */ +/* cs.stanford.edu's cert is only valid from 7/16/2009 to 7/16/2012, so with + * the date tested (October 2007) it's not time valid. + */ +static CONST_DATA_BLOB stanfordChain[] = { + { sizeof(entrust_ca), entrust_ca }, + { sizeof(aaa_certificate_services), aaa_certificate_services }, + { sizeof(cs_stanford_edu), cs_stanford_edu }, +}; +static const CERT_TRUST_STATUS stanfordElementStatus[] = { + { CERT_TRUST_IS_NOT_TIME_VALID, CERT_TRUST_HAS_KEY_MATCH_ISSUER }, + { CERT_TRUST_NO_ERROR, CERT_TRUST_HAS_KEY_MATCH_ISSUER }, + { CERT_TRUST_NO_ERROR, + CERT_TRUST_HAS_KEY_MATCH_ISSUER | CERT_TRUST_IS_SELF_SIGNED}, +}; +static const SimpleChainStatusCheck stanfordSimpleStatus[] = { + { sizeof(stanfordElementStatus) / sizeof(stanfordElementStatus[0]), + stanfordElementStatus }, +}; static ChainCheck chainCheck[] = { /* Windows XP erroneously sets CERT_TRUST_HAS_PREFERRED_ISSUER on all * elements, so ignore it. @@ -1592,6 +3218,124 @@ static ChainCheck chainCheck[] = { { { CERT_TRUST_IS_NOT_TIME_NESTED, CERT_TRUST_HAS_PREFERRED_ISSUER }, { CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, 1, simpleStatus13 }, 0 }, + { { sizeof(chain14) / sizeof(chain14[0]), chain14 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED, CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, 1, simpleStatus14 }, + 0 }, + /* Earlier versions of crypt32 incorrectly do not complain that the end cert's + * key usage is invalid, so ignore that error. + */ + { { sizeof(chain15) / sizeof(chain15[0]), chain15 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, 0 }, + 1, simpleStatus15 }, + 0 }, + { { sizeof(chain16) / sizeof(chain16[0]), chain16 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, 0 }, + 1, simpleStatus16 }, + 0 }, + { { sizeof(chain17) / sizeof(chain17[0]), chain17 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED, CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, 1, simpleStatus17 }, + 0 }, + { { sizeof(chain18) / sizeof(chain18[0]), chain18 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, 0 }, + 1, simpleStatus18 }, + 0 }, + /* Older versions of crypt32 set CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT + * even though the constraint and alt name match. + * They also do not set CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS, since they + * incorrectly find a name constraint error. + */ + { { sizeof(chain19) / sizeof(chain19[0]), chain19 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER | CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS + }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, + 1, simpleStatus19 }, + 0 }, + /* Older versions of crypt32 do not set + * CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, though they should. So + * ignore it (on Windows) but require it (on Wine.) + */ + { { sizeof(chain20) / sizeof(chain20[0]), chain20 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, 0 }, + 1, simpleStatus20 }, + 0 }, + { { sizeof(chain21) / sizeof(chain21[0]), chain21 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER | CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS + }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, + 1, simpleStatus21 }, + 0 }, + { { sizeof(chain22) / sizeof(chain22[0]), chain22 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, 0 }, + 1, simpleStatus22 }, + 0 }, + { { sizeof(chain23) / sizeof(chain23[0]), chain23 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, 0 }, + 1, simpleStatus23 }, + 0 }, + { { sizeof(chain24) / sizeof(chain24[0]), chain24 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, 0 }, + 1, simpleStatus24 }, + 0 }, + { { sizeof(chain25) / sizeof(chain25[0]), chain25 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, 0 }, + 1, simpleStatus25 }, + 0 }, + { { sizeof(chain26) / sizeof(chain26[0]), chain26 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, 0 }, + 1, simpleStatus26 }, + 0 }, + /* chain27 is handled separately elsewhere */ + { { sizeof(chain28) / sizeof(chain28[0]), chain28 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | + CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT, 0 }, + 1, simpleStatus28 }, + 0 }, { { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain }, { { 0, CERT_TRUST_HAS_PREFERRED_ISSUER }, { CERT_TRUST_IS_NOT_TIME_VALID | CERT_TRUST_IS_UNTRUSTED_ROOT, 0 }, @@ -1603,6 +3347,24 @@ static ChainCheck chainCheck[] = { { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, { 0, 0 }, 1, iTunesSimpleStatus }, 0 }, + /* The google chain may or may not have its root trusted, so ignore the error + */ + { { sizeof(googleChain) / sizeof(googleChain[0]), googleChain }, + { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_NOT_TIME_VALID, 0 }, + 1, googleSimpleStatus }, 0 }, + /* The openssl chain may or may not have its root trusted, so ignore the error + */ + { { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain }, + { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_NOT_TIME_VALID, 0 }, + 1, opensslSimpleStatus }, 0 }, + /* The stanford chain may or may not have its root trusted, so ignore the error + */ + { { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain }, + { { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_NOT_TIME_VALID, 0 }, + 1, stanfordSimpleStatus }, TODO_INFO }, }; static const CERT_TRUST_STATUS elementStatus8NoStore[] = { @@ -1625,8 +3387,33 @@ static ChainCheck chainCheckNoStore[] = { 0 }, }; +/* Chain27 checks a certificate with a subject alternate name containing an + * embedded NULL. Newer crypt32 versions fail to decode such alternate names, + * correctly prohibiting them. Older crypt32 versions do not. Rather than + * ignoring the expected error bits, check each version separately depending + * on the chain's error status. + */ +static ChainCheck chainCheckEmbeddedNull = { + { sizeof(chain27) / sizeof(chain27[0]), chain27 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_INVALID_NAME_CONSTRAINTS | + CERT_TRUST_INVALID_EXTENSION, 0 }, + 1, simpleStatus27 }, + 0 }; +static ChainCheck chainCheckEmbeddedNullBroken = { + { sizeof(chain27) / sizeof(chain27[0]), chain27 }, + { { CERT_TRUST_IS_NOT_TIME_NESTED | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | + CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT, + CERT_TRUST_HAS_PREFERRED_ISSUER }, + { CERT_TRUST_IS_UNTRUSTED_ROOT, CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS }, + 1, simpleStatus27Broken }, + 0 }; + /* Wednesday, Oct 1, 2007 */ static SYSTEMTIME oct2007 = { 2007, 10, 1, 1, 0, 0, 0, 0 }; +/* Wednesday, Oct 28, 2009 */ +static SYSTEMTIME oct2009 = { 2009, 10, 3, 28, 0, 0, 0, 0 }; static void testGetCertChain(void) { @@ -1682,6 +3469,16 @@ static void testGetCertChain(void) ok(GetLastError() == ERROR_INVALID_DATA || GetLastError() == CRYPT_E_ASN1_BADTAG /* Vista */, "Expected ERROR_INVALID_DATA or CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError()); + + para.cbSize = 0; + SetLastError(0xdeadbeef); + ret = pCertGetCertificateChain(NULL, cert, NULL, NULL, ¶, 0, NULL, + &chain); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_DATA || + GetLastError() == CRYPT_E_ASN1_BADTAG, /* Vista and higher */ + "Expected ERROR_INVALID_DATA or CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError()); + CertFreeCertificateContext(cert); for (i = 0; i < sizeof(chainCheck) / sizeof(chainCheck[0]); i++) @@ -1707,6 +3504,61 @@ static void testGetCertChain(void) pCertFreeCertificateChain(chain); } } + chain = getChain(&chainCheckEmbeddedNull.certs, 0, TRUE, &oct2007, + chainCheckEmbeddedNull.todo, 0); + if (chain) + { + ok(chain->TrustStatus.dwErrorStatus == + chainCheckEmbeddedNull.status.status.dwErrorStatus || + broken(chain->TrustStatus.dwErrorStatus == + chainCheckEmbeddedNullBroken.status.status.dwErrorStatus), + "unexpected chain error status %08x\n", + chain->TrustStatus.dwErrorStatus); + if (chainCheckEmbeddedNull.status.status.dwErrorStatus == + chain->TrustStatus.dwErrorStatus) + checkChainStatus(chain, &chainCheckEmbeddedNull.status, + chainCheckEmbeddedNull.todo, 0); + else + checkChainStatus(chain, &chainCheckEmbeddedNullBroken.status, + chainCheckEmbeddedNullBroken.todo, 0); + pCertFreeCertificateChain(chain); + } +} + +static void test_CERT_CHAIN_PARA_cbSize(void) +{ + BOOL ret; + PCCERT_CONTEXT cert; + CERT_CHAIN_PARA para = { 0 }; + PCCERT_CHAIN_CONTEXT chain; + HCERTSTORE store; + DWORD i; + + store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + + ret = CertAddEncodedCertificateToStore(store, + X509_ASN_ENCODING, chain0_0, sizeof(chain0_0), + CERT_STORE_ADD_ALWAYS, NULL); + ret = CertAddEncodedCertificateToStore(store, + X509_ASN_ENCODING, chain0_1, sizeof(chain0_1), + CERT_STORE_ADD_ALWAYS, &cert); + + for (i = 0; i < sizeof(CERT_CHAIN_PARA) + 2; i++) + { + FILETIME fileTime; + + SystemTimeToFileTime(&oct2007, &fileTime); + + para.cbSize = i; + ret = pCertGetCertificateChain(NULL, cert, &fileTime, + NULL, ¶, 0, NULL, &chain); + ok(ret, "CertGetCertificateChain failed %u\n", GetLastError()); + pCertFreeCertificateChain(chain); + } + + CertFreeCertificateContext(cert); + CertCloseStore(store, 0); } typedef struct _ChainPolicyCheck @@ -1744,10 +3596,104 @@ static const ChainPolicyCheck basePolicyCheck[] = { { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, { { sizeof(chain12) / sizeof(chain12[0]), chain12 }, { 0, TRUST_E_CERT_SIGNATURE, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain13) / sizeof(chain13[0]), chain13 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain14) / sizeof(chain14[0]), chain14 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain15) / sizeof(chain15[0]), chain15 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain16) / sizeof(chain16[0]), chain16 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain17) / sizeof(chain17[0]), chain17 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, NULL, 0 }, + { { sizeof(chain18) / sizeof(chain18[0]), chain18 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, NULL, 0 }, { { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain }, { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }, NULL, 0 }, }; +static const ChainPolicyCheck sslPolicyCheck[] = { + { { sizeof(chain0) / sizeof(chain0[0]), chain0 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain1) / sizeof(chain1[0]), chain1 }, + { 0, TRUST_E_CERT_SIGNATURE, 0, 0, NULL }, NULL, 0 }, + { { sizeof(chain2) / sizeof(chain2[0]), chain2 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain3) / sizeof(chain3[0]), chain3 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain4) / sizeof(chain4[0]), chain4 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, NULL, 0 }, + { { sizeof(chain5) / sizeof(chain5[0]), chain5 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain6) / sizeof(chain6[0]), chain6 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain7) / sizeof(chain7[0]), chain7 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain8) / sizeof(chain8[0]), chain8 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, NULL, 0 }, + { { sizeof(chain9) / sizeof(chain9[0]), chain9 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, -1, NULL }, NULL, 0 }, + { { sizeof(chain10) / sizeof(chain10[0]), chain10 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain11) / sizeof(chain11[0]), chain11 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain12) / sizeof(chain12[0]), chain12 }, + { 0, TRUST_E_CERT_SIGNATURE, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain13) / sizeof(chain13[0]), chain13 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain14) / sizeof(chain14[0]), chain14 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain15) / sizeof(chain15[0]), chain15 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain16) / sizeof(chain16[0]), chain16 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain17) / sizeof(chain17[0]), chain17 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, NULL, 0 }, + { { sizeof(chain18) / sizeof(chain18[0]), chain18 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, NULL, 0 }, + { { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }, NULL, 0 }, +}; + +static const ChainPolicyCheck googlePolicyCheckWithMatchingNameExpired = { + { sizeof(googleChain) / sizeof(googleChain[0]), googleChain }, + { 0, CERT_E_EXPIRED, 0, 0, NULL}, NULL, 0 +}; + +static const ChainPolicyCheck googlePolicyCheckWithMatchingName = { + { sizeof(googleChain) / sizeof(googleChain[0]), googleChain }, + { 0, 0, -1, -1, NULL}, NULL, 0 +}; + +/* Windows NT 4 has a different error code when the name doesn't match. */ +static const CERT_CHAIN_POLICY_STATUS noMatchingNameBrokenStatus = + { 0, CERT_E_ROLE, 0, 0, NULL }; + +static const ChainPolicyCheck iTunesPolicyCheckWithoutMatchingName = { + { sizeof(iTunesChain) / sizeof(iTunesChain[0]), iTunesChain }, + { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, &noMatchingNameBrokenStatus, 0 +}; + +static const ChainPolicyCheck opensslPolicyCheckWithMatchingName = { + { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain }, + { 0, 0, -1, -1, NULL}, NULL, 0 +}; + +static const ChainPolicyCheck opensslPolicyCheckWithoutMatchingName = { + { sizeof(opensslChain) / sizeof(opensslChain[0]), opensslChain }, + { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0 +}; + +static const ChainPolicyCheck stanfordPolicyCheckWithMatchingName = { + { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain }, + { 0, 0, -1, -1, NULL}, NULL, 0 +}; + +static const ChainPolicyCheck stanfordPolicyCheckWithoutMatchingName = { + { sizeof(stanfordChain) / sizeof(stanfordChain[0]), stanfordChain }, + { 0, CERT_E_CN_NO_MATCH, 0, 0, NULL}, NULL, 0 +}; + static const ChainPolicyCheck authenticodePolicyCheck[] = { { { sizeof(chain0) / sizeof(chain0[0]), chain0 }, { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, @@ -1775,6 +3721,18 @@ static const ChainPolicyCheck authenticodePolicyCheck[] = { { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, { { sizeof(chain12) / sizeof(chain12[0]), chain12 }, { 0, TRUST_E_CERT_SIGNATURE, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain13) / sizeof(chain13[0]), chain13 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain14) / sizeof(chain14[0]), chain14 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain15) / sizeof(chain15[0]), chain15 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain16) / sizeof(chain16[0]), chain16 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 1, NULL }, NULL, 0 }, + { { sizeof(chain17) / sizeof(chain17[0]), chain17 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, NULL, 0 }, + { { sizeof(chain18) / sizeof(chain18[0]), chain18 }, + { 0, CERT_E_UNTRUSTEDROOT, 0, 2, NULL }, NULL, 0 }, { { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain }, { 0, CERT_E_UNTRUSTEDROOT, 0, 0, NULL }, NULL, 0 }, }; @@ -1813,6 +3771,18 @@ static const ChainPolicyCheck basicConstraintsPolicyCheck[] = { { 0, 0, -1, -1, NULL }, NULL, 0 }, { { sizeof(chain12) / sizeof(chain12[0]), chain12 }, { 0, 0, -1, -1, NULL }, NULL, 0 }, + { { sizeof(chain13) / sizeof(chain13[0]), chain13 }, + { 0, 0, -1, -1, NULL }, NULL, 0 }, + { { sizeof(chain14) / sizeof(chain14[0]), chain14 }, + { 0, 0, -1, -1, NULL }, NULL, 0 }, + { { sizeof(chain15) / sizeof(chain15[0]), chain15 }, + { 0, 0, -1, -1, NULL }, NULL, 0 }, + { { sizeof(chain16) / sizeof(chain16[0]), chain16 }, + { 0, 0, -1, -1, NULL }, NULL, 0 }, + { { sizeof(chain17) / sizeof(chain17[0]), chain17 }, + { 0, 0, -1, -1, NULL }, NULL, 0 }, + { { sizeof(chain18) / sizeof(chain18[0]), chain18 }, + { 0, 0, -1, -1, NULL }, NULL, 0 }, { { sizeof(selfSignedChain) / sizeof(selfSignedChain[0]), selfSignedChain }, { 0, 0, -1, -1, NULL }, NULL, 0 }, }; @@ -1826,15 +3796,16 @@ static const char *num_to_str(WORD num) } static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, - DWORD testIndex) + DWORD testIndex, SYSTEMTIME *sysTime, PCERT_CHAIN_POLICY_PARA para) + { - PCCERT_CHAIN_CONTEXT chain = getChain(&check->certs, 0, TRUE, &oct2007, + PCCERT_CHAIN_CONTEXT chain = getChain(&check->certs, 0, TRUE, sysTime, check->todo, testIndex); if (chain) { CERT_CHAIN_POLICY_STATUS policyStatus = { 0 }; - BOOL ret = pCertVerifyCertificateChainPolicy(policy, chain, NULL, + BOOL ret = pCertVerifyCertificateChainPolicy(policy, chain, para, &policyStatus); if (check->todo & TODO_POLICY) @@ -1920,6 +3891,140 @@ static void checkChainPolicyStatus(LPCSTR policy, const ChainPolicyCheck *check, } } +static void check_ssl_policy(void) +{ + DWORD i; + CERT_CHAIN_POLICY_PARA policyPara = { 0 }; + SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslPolicyPara = { { 0 } }; + WCHAR winehq[] = { 'w','i','n','e','h','q','.','o','r','g',0 }; + WCHAR google_dot_com[] = { 'w','w','w','.','g','o','o','g','l','e','.', + 'c','o','m',0 }; + WCHAR a_dot_openssl_dot_org[] = { 'a','.','o','p','e','n','s','s','l','.', + 'o','r','g',0 }; + WCHAR openssl_dot_org[] = { 'o','p','e','n','s','s','l','.','o','r','g',0 }; + WCHAR fopenssl_dot_org[] = { 'f','o','p','e','n','s','s','l','.', + 'o','r','g',0 }; + WCHAR a_dot_b_dot_openssl_dot_org[] = { 'a','.','b','.', + 'o','p','e','n','s','s','l','.','o','r','g',0 }; + WCHAR cs_dot_stanford_dot_edu[] = { 'c','s','.', + 's','t','a','n','f','o','r','d','.','e','d','u',0 }; + WCHAR www_dot_cs_dot_stanford_dot_edu[] = { 'w','w','w','.','c','s','.', + 's','t','a','n','f','o','r','d','.','e','d','u',0 }; + WCHAR a_dot_cs_dot_stanford_dot_edu[] = { 'a','.','c','s','.', + 's','t','a','n','f','o','r','d','.','e','d','u',0 }; + + /* Check ssl policy with no parameter */ + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, NULL); + /* Check again with a policy parameter that specifies nothing */ + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, &policyPara); + /* Check yet again, but specify an empty SSL_EXTRA_CERT_CHAIN_POLICY_PARA + * argument. + */ + policyPara.pvExtraPolicyPara = &sslPolicyPara; + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, &policyPara); + /* And again, but specify the auth type as a client */ + sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT; + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, &policyPara); + /* And again, but specify the auth type as a server */ + sslPolicyPara.dwAuthType = AUTHTYPE_SERVER; + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, &policyPara); + /* And again authenticating a client, but specify the size of the policy + * parameter. + */ + sslPolicyPara.cbSize = sizeof(sslPolicyCheck); + sslPolicyPara.dwAuthType = AUTHTYPE_CLIENT; + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, &policyPara); + /* One more time authenticating a client, but specify winehq.org as the + * server name. + */ + sslPolicyPara.pwszServerName = winehq; + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, &policyPara); + /* And again authenticating a server, still specifying winehq.org as the + * server name. + */ + sslPolicyPara.dwAuthType = AUTHTYPE_SERVER; + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, &policyPara); + /* And again authenticating a server, this time specifying the size of the + * policy param. + */ + policyPara.cbSize = sizeof(policyPara); + for (i = 0; + i < sizeof(sslPolicyCheck) / sizeof(sslPolicyCheck[0]); i++) + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, &sslPolicyCheck[i], i, + &oct2007, &policyPara); + /* Yet again, but checking the iTunes chain, which contains a name + * extension. + */ + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &iTunesPolicyCheckWithoutMatchingName, 0, &oct2007, &policyPara); + /* And again, but checking the Google chain at a bad date */ + sslPolicyPara.pwszServerName = google_dot_com; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &googlePolicyCheckWithMatchingNameExpired, 0, &oct2007, &policyPara); + /* And again, but checking the Google chain at a good date */ + sslPolicyPara.pwszServerName = google_dot_com; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &googlePolicyCheckWithMatchingName, 0, &oct2009, &policyPara); + /* Check again with the openssl cert, which has a wildcard in its name, + * with various combinations of matching and non-matching names. + * With "a.openssl.org": match + */ + sslPolicyPara.pwszServerName = a_dot_openssl_dot_org; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &opensslPolicyCheckWithMatchingName, 0, &oct2009, &policyPara); + /* With "openssl.org": no match */ + sslPolicyPara.pwszServerName = openssl_dot_org; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara); + /* With "fopenssl.org": no match */ + sslPolicyPara.pwszServerName = fopenssl_dot_org; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara); + /* with "a.b.openssl.org": no match */ + sslPolicyPara.pwszServerName = a_dot_b_dot_openssl_dot_org; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &opensslPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara); + /* Check again with the cs.stanford.edu, which has both cs.stanford.edu + * and www.cs.stanford.edu in its subject alternative name. + * With "cs.stanford.edu": match + */ + sslPolicyPara.pwszServerName = cs_dot_stanford_dot_edu; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &stanfordPolicyCheckWithMatchingName, 0, &oct2009, &policyPara); + /* With "www.cs.stanford.edu": match */ + sslPolicyPara.pwszServerName = www_dot_cs_dot_stanford_dot_edu; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &stanfordPolicyCheckWithMatchingName, 0, &oct2009, &policyPara); + /* With "a.cs.stanford.edu": no match */ + sslPolicyPara.pwszServerName = a_dot_cs_dot_stanford_dot_edu; + checkChainPolicyStatus(CERT_CHAIN_POLICY_SSL, + &stanfordPolicyCheckWithoutMatchingName, 0, &oct2009, &policyPara); +} + static void testVerifyCertChainPolicy(void) { BOOL ret; @@ -1984,7 +4089,9 @@ static void testVerifyCertChainPolicy(void) for (i = 0; i < sizeof(basePolicyCheck) / sizeof(basePolicyCheck[0]); i++) - checkChainPolicyStatus(CERT_CHAIN_POLICY_BASE, &basePolicyCheck[i], i); + checkChainPolicyStatus(CERT_CHAIN_POLICY_BASE, &basePolicyCheck[i], i, + &oct2007, NULL); + check_ssl_policy(); /* The authenticode policy doesn't seem to check anything beyond the base * policy. It might check for chains signed by the MS test cert, but none * of these chains is. @@ -1992,12 +4099,12 @@ static void testVerifyCertChainPolicy(void) for (i = 0; i < sizeof(authenticodePolicyCheck) / sizeof(authenticodePolicyCheck[0]); i++) checkChainPolicyStatus(CERT_CHAIN_POLICY_AUTHENTICODE, - &authenticodePolicyCheck[i], i); + &authenticodePolicyCheck[i], i, &oct2007, NULL); for (i = 0; i < sizeof(basicConstraintsPolicyCheck) / sizeof(basicConstraintsPolicyCheck[0]); i++) checkChainPolicyStatus(CERT_CHAIN_POLICY_BASIC_CONSTRAINTS, - &basicConstraintsPolicyCheck[i], i); + &basicConstraintsPolicyCheck[i], i, &oct2007, NULL); } START_TEST(chain) @@ -2018,5 +4125,6 @@ START_TEST(chain) { testVerifyCertChainPolicy(); testGetCertChain(); + test_CERT_CHAIN_PARA_cbSize(); } } diff --git a/rostests/winetests/crypt32/crl.c b/rostests/winetests/crypt32/crl.c index abd8491df90..1b8cb18e4d1 100644 --- a/rostests/winetests/crypt32/crl.c +++ b/rostests/winetests/crypt32/crl.c @@ -118,6 +118,21 @@ static void testCreateCRL(void) CertFreeCRLContext(context); } +static void testDupCRL(void) +{ + PCCRL_CONTEXT context, dupContext; + + context = CertDuplicateCRLContext(NULL); + ok(context == NULL, "expected NULL\n"); + context = CertCreateCRLContext(X509_ASN_ENCODING, signedCRL, + sizeof(signedCRL)); + dupContext = CertDuplicateCRLContext(context); + ok(dupContext != NULL, "expected a context\n"); + ok(dupContext == context, "expected identical context addresses\n"); + CertFreeCRLContext(dupContext); + CertFreeCRLContext(context); +} + static void testAddCRL(void) { HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, @@ -722,6 +737,7 @@ START_TEST(crl) init_function_pointers(); testCreateCRL(); + testDupCRL(); testAddCRL(); testFindCRL(); testGetCRLFromStore(); diff --git a/rostests/winetests/crypt32/ctl.c b/rostests/winetests/crypt32/ctl.c index f09420c8a21..8ee26526289 100644 --- a/rostests/winetests/crypt32/ctl.c +++ b/rostests/winetests/crypt32/ctl.c @@ -187,6 +187,21 @@ static void testCreateCTL(void) CertFreeCTLContext(ctl); } +static void testDupCTL(void) +{ + PCCTL_CONTEXT context, dupContext; + + context = CertDuplicateCTLContext(NULL); + ok(context == NULL, "expected NULL\n"); + context = CertCreateCTLContext(X509_ASN_ENCODING, + signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent)); + dupContext = CertDuplicateCTLContext(context); + ok(dupContext != NULL, "expected a context\n"); + ok(dupContext == context, "expected identical context addresses\n"); + CertFreeCTLContext(dupContext); + CertFreeCTLContext(context); +} + static void checkHash(const BYTE *data, DWORD dataLen, ALG_ID algID, PCCTL_CONTEXT context, DWORD propID) { @@ -444,6 +459,7 @@ static void testAddCTLToStore(void) START_TEST(ctl) { testCreateCTL(); + testDupCTL(); testCTLProperties(); testAddCTLToStore(); } diff --git a/rostests/winetests/crypt32/encode.c b/rostests/winetests/crypt32/encode.c index 3e99800638c..f2fc7275a55 100644 --- a/rostests/winetests/crypt32/encode.c +++ b/rostests/winetests/crypt32/encode.c @@ -1264,6 +1264,9 @@ static BYTE bmpCommonNameValue[] = { 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 }; static BYTE utf8CommonNameValue[] = { 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 }; +static char embedded_null[] = "foo\0com"; +static BYTE ia5EmbeddedNull[] = { + 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d }; static struct EncodedNameValue nameValues[] = { { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } }, @@ -1299,6 +1302,12 @@ static struct EncodedNameValue nameValues[] = { { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } }, bin44, sizeof(bin44) }, }; +/* This is kept separate, because the decoding doesn't return to the original + * value. + */ +static struct EncodedNameValue embeddedNullNameValue = { + { CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } }, + ia5EmbeddedNull, sizeof(ia5EmbeddedNull) }; static void test_encodeNameValue(DWORD dwEncoding) { @@ -1337,6 +1346,19 @@ static void test_encodeNameValue(DWORD dwEncoding) LocalFree(buf); } } + ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, + &embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */, + "Type %d: CryptEncodeObjectEx failed: %08x\n", + embeddedNullNameValue.value.dwValueType, GetLastError()); + if (ret) + { + ok(size == embeddedNullNameValue.encodedSize, + "Expected size %d, got %d\n", embeddedNullNameValue.encodedSize, size); + ok(!memcmp(buf, embeddedNullNameValue.encoded, size), + "Got unexpected encoding\n"); + LocalFree(buf); + } } static void test_decodeNameValue(DWORD dwEncoding) @@ -1361,6 +1383,45 @@ static void test_decodeNameValue(DWORD dwEncoding) LocalFree(buf); } } + ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE, + embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize, + CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL, + &buf, &bufSize); + ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n", + embeddedNullNameValue.value.dwValueType, GetLastError()); + if (ret) + { + CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB, + { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } }; + CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING, + { sizeof(embedded_null) - 1, (BYTE *)embedded_null } }; + const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf, + *expected = NULL; + + /* Some Windows versions decode name values with embedded NULLs, + * others leave them encoded, even with the same version of crypt32. + * Accept either. + */ + ok(got->dwValueType == CERT_RDN_ENCODED_BLOB || + got->dwValueType == CERT_RDN_IA5_STRING, + "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n", + got->dwValueType); + if (got->dwValueType == CERT_RDN_ENCODED_BLOB) + expected = &rdnEncodedValue; + else if (got->dwValueType == CERT_RDN_IA5_STRING) + expected = &embeddedNullValue; + if (expected) + { + ok(got->Value.cbData == expected->Value.cbData, + "String type %d: unexpected data size, got %d, expected %d\n", + got->dwValueType, got->Value.cbData, expected->Value.cbData); + if (got->Value.cbData && got->Value.pbData) + ok(!memcmp(got->Value.pbData, expected->Value.pbData, + min(got->Value.cbData, expected->Value.cbData)), + "String type %d: unexpected value\n", expected->dwValueType); + } + LocalFree(buf); + } } static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 }; @@ -1504,6 +1565,12 @@ static void test_decodeAltName(DWORD dwEncoding) 0x00, 0x00, 0x01 }; static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00, 0x01 }; + static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f, + 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 }; + static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f, + 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 }; + static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f, + 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 }; BOOL ret; BYTE *buf = NULL; DWORD bufSize = 0; @@ -1642,6 +1709,40 @@ static void test_decodeAltName(DWORD dwEncoding) "Unexpected directory name value\n"); LocalFree(buf); } + ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, + dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG, + NULL, &buf, &bufSize); + /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the + * particular failure, just that it doesn't decode. + * It succeeds on (broken) Windows versions that haven't addressed + * embedded NULLs in alternate names. + */ + ok(!ret || broken(ret), "expected failure\n"); + /* An embedded bell character is allowed, however. */ + ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, + dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG, + NULL, &buf, &bufSize); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + info = (CERT_ALT_NAME_INFO *)buf; + + ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n", + info->cAltEntry); + ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME, + "Expected CERT_ALT_NAME_DNS_NAME, got %d\n", + info->rgAltEntry[0].dwAltNameChoice); + LocalFree(buf); + } + ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, + url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG, + NULL, &buf, &bufSize); + /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned + * about the particular failure, just that it doesn't decode. + * It succeeds on (broken) Windows versions that haven't addressed + * embedded NULLs in alternate names. + */ + ok(!ret || broken(ret), "expected failure\n"); } struct UnicodeExpectedError @@ -2613,8 +2714,8 @@ static void test_decodeExtensions(DWORD dwEncoding) /* MS encodes public key info with a NULL if the algorithm identifier's * parameters are empty. However, when encoding an algorithm in a CERT_INFO, - * it encodes them by omitting the algorithm parameters. This latter approach - * seems more correct, so accept either form. + * it encodes them by omitting the algorithm parameters. It accepts either + * form for decoding. */ struct encodedPublicKey { @@ -2692,16 +2793,11 @@ static void test_encodePublicKeyInfo(DWORD dwEncoding) "CryptEncodeObjectEx failed: %08x\n", GetLastError()); if (buf) { - ok(bufSize == pubKeys[i].encoded[1] + 2 || - bufSize == pubKeys[i].encodedNoNull[1] + 2, - "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, - pubKeys[i].encodedNoNull[1] + 2, bufSize); + ok(bufSize == pubKeys[i].encoded[1] + 2, + "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize); if (bufSize == pubKeys[i].encoded[1] + 2) ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2), "Unexpected value\n"); - else if (bufSize == pubKeys[i].encodedNoNull[1] + 2) - ok(!memcmp(buf, pubKeys[i].encodedNoNull, - pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n"); LocalFree(buf); } } @@ -2789,6 +2885,11 @@ static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 }; +static const BYTE v4Cert[] = { +0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22, +0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30, +0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 }; static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, @@ -2846,6 +2947,35 @@ static const BYTE v1CertWithSubjectKeyId[] = { 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30, 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20, 0x4c,0x61,0x6e,0x67,0x00 }; +static const BYTE v1CertWithIssuerUniqueId[] = { +0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36, +0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f, +0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, +0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 }; +static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = { +0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, +0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, +0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, +0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, +0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, +0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, +0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, +0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30, +0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06, +0x01,0x01,0xff,0x02,0x01,0x01 }; +static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = { +0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30, +0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61, +0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31, +0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31, +0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11, +0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e, +0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, +0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, +0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30, +0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01, +0xff,0x02,0x01,0x01 }; static const BYTE serialNum[] = { 0x01 }; @@ -2903,6 +3033,16 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n"); LocalFree(buf); } + /* A v4 cert? */ + info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */ + ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + if (buf) + { + ok(size == sizeof(v4Cert), "Wrong size %d\n", size); + ok(!memcmp(buf, v4Cert, size), "Unexpected value\n"); + LocalFree(buf); + } /* see if a V1 cert can have basic constraints set (RFC3280 says no, but * API doesn't prevent it) */ @@ -2930,7 +3070,27 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n"); LocalFree(buf); } + /* Test v1 cert with an issuer name, serial number, and issuer unique id */ + info.dwVersion = CERT_V1; + info.cExtension = 0; + info.IssuerUniqueId.cbData = sizeof(serialNum); + info.IssuerUniqueId.pbData = (BYTE *)serialNum; + ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */), + "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (buf) + { + ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size); + ok(!memcmp(buf, v1CertWithIssuerUniqueId, size), + "Got unexpected value\n"); + LocalFree(buf); + } /* Test v1 cert with an issuer name, a subject name, and a serial number */ + info.IssuerUniqueId.cbData = 0; + info.IssuerUniqueId.pbData = NULL; + info.cExtension = 1; + info.rgExtension = &criticalExt; info.Issuer.cbData = sizeof(encodedCommonName); info.Issuer.pbData = (BYTE *)encodedCommonName; info.Subject.cbData = sizeof(encodedCommonName); @@ -2960,7 +3120,30 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) "Got unexpected value\n"); LocalFree(buf); } + /* Again add an issuer unique id */ + info.IssuerUniqueId.cbData = sizeof(serialNum); + info.IssuerUniqueId.pbData = (BYTE *)serialNum; + ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (buf) + { + ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) || + size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull), + "Wrong size %d\n", size); + if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId)) + ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId, + size), "unexpected value\n"); + else if (size == + sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull)) + ok(!memcmp(buf, + v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size), + "unexpected value\n"); + LocalFree(buf); + } /* Remove the public key, and add a subject key identifier extension */ + info.IssuerUniqueId.cbData = 0; + info.IssuerUniqueId.pbData = NULL; info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL; info.SubjectPublicKeyInfo.PublicKey.cbData = 0; info.SubjectPublicKeyInfo.PublicKey.pbData = NULL; @@ -2982,8 +3165,8 @@ static void test_encodeCertToBeSigned(DWORD dwEncoding) static void test_decodeCertToBeSigned(DWORD dwEncoding) { - static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, - v1CertWithConstraints, v1CertWithSerial }; + static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert, + v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId }; BOOL ret; BYTE *buf = NULL; DWORD size = 0, i; @@ -3002,9 +3185,9 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding) ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError()); } - /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a - * minimum a cert must have a non-zero serial number, an issuer, and a - * subject. + /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or + * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero + * serial number, an issuer, a subject, and a public key. */ for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++) { @@ -3013,6 +3196,45 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding) &buf, &size); ok(!ret, "Expected failure\n"); } + /* The following succeeds, even though v1 certs are not allowed to have + * extensions. + */ + ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, + v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId), + CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + CERT_INFO *info = (CERT_INFO *)buf; + + ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); + ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n", + info->dwVersion); + ok(info->cExtension == 1, "expected 1 extension, got %d\n", + info->cExtension); + LocalFree(buf); + } + /* The following also succeeds, even though V1 certs are not allowed to + * have issuer unique ids. + */ + ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, + v1CertWithSubjectIssuerSerialAndIssuerUniqueId, + sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId), + CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + CERT_INFO *info = (CERT_INFO *)buf; + + ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size); + ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n", + info->dwVersion); + ok(info->IssuerUniqueId.cbData == sizeof(serialNum), + "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData); + ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)), + "unexpected issuer unique id value\n"); + LocalFree(buf); + } /* Now check with serial number, subject and issuer specified */ ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert, sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); @@ -5520,7 +5742,10 @@ static void test_decodeCTL(DWORD dwEncoding) SetLastError(0xdeadbeef); ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry, sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size); - ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT), + ok(!ret && + (GetLastError() == CRYPT_E_ASN1_EOD || + GetLastError() == CRYPT_E_ASN1_CORRUPT || + GetLastError() == OSS_MORE_INPUT), /* Win9x */ "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError()); info.SubjectAlgorithm.Parameters.cbData = 0; @@ -7302,6 +7527,305 @@ static void test_decodeCertPolicies(DWORD dwEncoding) } } +static const BYTE policyMappingWithOneMapping[] = { +0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 }; +static const BYTE policyMappingWithTwoMappings[] = { +0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06, +0x02,0x2b,0x04,0x06,0x02,0x55,0x06 }; +static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS, + szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS }; + +static void test_encodeCertPolicyMappings(DWORD dwEncoding) +{ + static char oid2[] = "2.3.4"; + static char oid3[] = "1.3.4"; + static char oid4[] = "2.5.6"; + BOOL ret; + CERT_POLICY_MAPPINGS_INFO info = { 0 }; + CERT_POLICY_MAPPING mapping[2]; + LPBYTE buf; + DWORD size, i; + + /* Each of the mapping OIDs is equivalent, so check with all of them */ + for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++) + { + memset(&info, 0, sizeof(info)); + ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), + "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) + { + win_skip("no policy mappings support\n"); + return; + } + if (ret) + { + ok(size == sizeof(emptySequence), "unexpected size %d\n", size); + ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), + "unexpected value\n"); + LocalFree(buf); + } + mapping[0].pszIssuerDomainPolicy = NULL; + mapping[0].pszSubjectDomainPolicy = NULL; + info.cPolicyMapping = 1; + info.rgPolicyMapping = mapping; + SetLastError(0xdeadbeef); + ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(!ret && GetLastError() == E_INVALIDARG, + "expected E_INVALIDARG, got %08x\n", GetLastError()); + mapping[0].pszIssuerDomainPolicy = oid1; + mapping[0].pszSubjectDomainPolicy = oid2; + ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(size == sizeof(policyMappingWithOneMapping), + "unexpected size %d\n", size); + ok(!memcmp(buf, policyMappingWithOneMapping, size), + "unexpected value\n"); + LocalFree(buf); + } + mapping[1].pszIssuerDomainPolicy = oid3; + mapping[1].pszSubjectDomainPolicy = oid4; + info.cPolicyMapping = 2; + ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(size == sizeof(policyMappingWithTwoMappings), + "unexpected size %d\n", size); + ok(!memcmp(buf, policyMappingWithTwoMappings, size), + "unexpected value\n"); + LocalFree(buf); + } + } +} + +static void test_decodeCertPolicyMappings(DWORD dwEncoding) +{ + DWORD size, i; + CERT_POLICY_MAPPINGS_INFO *info; + BOOL ret; + + /* Each of the mapping OIDs is equivalent, so check with all of them */ + for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++) + { + ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], + emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, + &info, &size); + ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), + "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) + { + win_skip("no policy mappings support\n"); + return; + } + if (ret) + { + ok(info->cPolicyMapping == 0, + "expected 0 policy mappings, got %d\n", info->cPolicyMapping); + LocalFree(info); + } + ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], + policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping), + CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(info->cPolicyMapping == 1, + "expected 1 policy mappings, got %d\n", info->cPolicyMapping); + ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"), + "unexpected issuer policy %s\n", + info->rgPolicyMapping[0].pszIssuerDomainPolicy); + ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy, + "2.3.4"), "unexpected subject policy %s\n", + info->rgPolicyMapping[0].pszSubjectDomainPolicy); + LocalFree(info); + } + ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i], + policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings), + CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(info->cPolicyMapping == 2, + "expected 2 policy mappings, got %d\n", info->cPolicyMapping); + ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"), + "unexpected issuer policy %s\n", + info->rgPolicyMapping[0].pszIssuerDomainPolicy); + ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy, + "2.3.4"), "unexpected subject policy %s\n", + info->rgPolicyMapping[0].pszSubjectDomainPolicy); + ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"), + "unexpected issuer policy %s\n", + info->rgPolicyMapping[1].pszIssuerDomainPolicy); + ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy, + "2.5.6"), "unexpected subject policy %s\n", + info->rgPolicyMapping[1].pszSubjectDomainPolicy); + LocalFree(info); + } + } +} + +static const BYTE policyConstraintsWithRequireExplicit[] = { +0x30,0x03,0x80,0x01,0x00 }; +static const BYTE policyConstraintsWithInhibitMapping[] = { +0x30,0x03,0x81,0x01,0x01 }; +static const BYTE policyConstraintsWithBoth[] = { +0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 }; + +static void test_encodeCertPolicyConstraints(DWORD dwEncoding) +{ + CERT_POLICY_CONSTRAINTS_INFO info = { 0 }; + LPBYTE buf; + DWORD size; + BOOL ret; + + /* Even though RFC 5280 explicitly states CAs must not issue empty + * policy constraints (section 4.2.1.11), the API doesn't prevent it. + */ + ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), + "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) + { + win_skip("no policy constraints support\n"); + return; + } + if (ret) + { + ok(size == sizeof(emptySequence), "unexpected size %d\n", size); + ok(!memcmp(buf, emptySequence, sizeof(emptySequence)), + "unexpected value\n"); + LocalFree(buf); + } + /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts + * is not, then a skip of 0 is encoded. + */ + info.fRequireExplicitPolicy = TRUE; + ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(size == sizeof(policyConstraintsWithRequireExplicit), + "unexpected size %d\n", size); + ok(!memcmp(buf, policyConstraintsWithRequireExplicit, + sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n"); + LocalFree(buf); + } + /* With inhibit policy mapping */ + info.fRequireExplicitPolicy = FALSE; + info.dwRequireExplicitPolicySkipCerts = 0; + info.fInhibitPolicyMapping = TRUE; + info.dwInhibitPolicyMappingSkipCerts = 1; + ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(size == sizeof(policyConstraintsWithInhibitMapping), + "unexpected size %d\n", size); + ok(!memcmp(buf, policyConstraintsWithInhibitMapping, + sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n"); + LocalFree(buf); + } + /* And with both */ + info.fRequireExplicitPolicy = TRUE; + info.dwRequireExplicitPolicySkipCerts = 1; + ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info, + CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size); + ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n", + size); + ok(!memcmp(buf, policyConstraintsWithBoth, + sizeof(policyConstraintsWithBoth)), "unexpected value\n"); + LocalFree(buf); + } +} + +static void test_decodeCertPolicyConstraints(DWORD dwEncoding) +{ + CERT_POLICY_CONSTRAINTS_INFO *info; + DWORD size; + BOOL ret; + + /* Again, even though CAs must not issue such constraints, they can be + * decoded. + */ + ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, + emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL, + &info, &size); + ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND), + "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) + { + win_skip("no policy mappings support\n"); + return; + } + if (ret) + { + ok(!info->fRequireExplicitPolicy, + "expected require explicit = FALSE\n"); + ok(!info->fInhibitPolicyMapping, + "expected implicit mapping = FALSE\n"); + LocalFree(info); + } + ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, + policyConstraintsWithRequireExplicit, + sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG, + NULL, &info, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(info->fRequireExplicitPolicy, + "expected require explicit = TRUE\n"); + ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n", + info->dwRequireExplicitPolicySkipCerts); + ok(!info->fInhibitPolicyMapping, + "expected implicit mapping = FALSE\n"); + LocalFree(info); + } + ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, + policyConstraintsWithInhibitMapping, + sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG, + NULL, &info, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(!info->fRequireExplicitPolicy, + "expected require explicit = FALSE\n"); + ok(info->fInhibitPolicyMapping, + "expected implicit mapping = TRUE\n"); + ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n", + info->dwInhibitPolicyMappingSkipCerts); + LocalFree(info); + } + ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, + policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth), + CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size); + ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError()); + if (ret) + { + ok(info->fRequireExplicitPolicy, + "expected require explicit = TRUE\n"); + ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n", + info->dwRequireExplicitPolicySkipCerts); + ok(info->fInhibitPolicyMapping, + "expected implicit mapping = TRUE\n"); + ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n", + info->dwInhibitPolicyMappingSkipCerts); + LocalFree(info); + } +} + /* Free *pInfo with HeapFree */ static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo) { @@ -7572,6 +8096,10 @@ START_TEST(encode) test_decodePolicyQualifierUserNotice(encodings[i]); test_encodeCertPolicies(encodings[i]); test_decodeCertPolicies(encodings[i]); + test_encodeCertPolicyMappings(encodings[i]); + test_decodeCertPolicyMappings(encodings[i]); + test_encodeCertPolicyConstraints(encodings[i]); + test_decodeCertPolicyConstraints(encodings[i]); } testPortPublicKeyInfo(); } diff --git a/rostests/winetests/crypt32/oid.c b/rostests/winetests/crypt32/oid.c index 8b680c44a80..030a548ac1a 100644 --- a/rostests/winetests/crypt32/oid.c +++ b/rostests/winetests/crypt32/oid.c @@ -98,16 +98,8 @@ static void testOIDToAlgID(void) DWORD alg; /* Test with a bogus one */ - SetLastError(0xdeadbeef); alg = CertOIDToAlgId("1.2.3"); ok(!alg, "Expected failure, got %d\n", alg); - ok(GetLastError() == 0xdeadbeef || - GetLastError() == ERROR_RESOURCE_NAME_NOT_FOUND || - GetLastError() == ERROR_INVALID_PARAMETER || /* Vista */ - GetLastError() == ERROR_SUCCESS || /* win2k */ - GetLastError() == ERROR_FILE_INVALID, /* another Vista */ - "Expected ERROR_RESOURCE_NAME_NOT_FOUND, ERROR_INVALID_PARAMETER, " - "ERROR_SUCCESS or no error set, got %08x\n", GetLastError()); for (i = 0; i < sizeof(oidToAlgID) / sizeof(oidToAlgID[0]); i++) { diff --git a/rostests/winetests/crypt32/protectdata.c b/rostests/winetests/crypt32/protectdata.c index 82cf1aa2667..c3173c39d2c 100644 --- a/rostests/winetests/crypt32/protectdata.c +++ b/rostests/winetests/crypt32/protectdata.c @@ -213,6 +213,40 @@ static void test_cryptunprotectdata(void) plain.cbData=0; } +static void test_simpleroundtrip(const char *plaintext, int wine_fails) +{ + DATA_BLOB input; + DATA_BLOB encrypted; + DATA_BLOB output; + int res; + WCHAR emptyW[1]; + + emptyW[0] = 0; + input.pbData = (unsigned char *)plaintext; + input.cbData = strlen(plaintext); + res = pCryptProtectData(&input, emptyW, NULL, NULL, NULL, 0, &encrypted); + ok(res != 0 || broken(!res), "can't protect\n"); + if (!res) + { + /* Fails on Win9x, NT4 */ + win_skip("CryptProtectData failed\n"); + return; + } + + res = pCryptUnprotectData(&encrypted, NULL, NULL, NULL, NULL, 0, &output); + if (wine_fails) { + todo_wine + ok(res != 0, "can't unprotect; last error %u\n", GetLastError()); + } else { + ok(res != 0, "can't unprotect; last error %u\n", GetLastError()); + } + + if (res) { + ok(output.cbData == strlen(plaintext), "output wrong length %d for input '%s', wanted %d\n", output.cbData, plaintext, strlen(plaintext)); + ok(!memcmp(plaintext, (char *)output.pbData, output.cbData), "output wrong contents for input '%s'\n", plaintext); + } +} + START_TEST(protectdata) { HMODULE hCrypt32 = GetModuleHandleA("crypt32.dll"); @@ -228,6 +262,8 @@ START_TEST(protectdata) protected=FALSE; test_cryptprotectdata(); test_cryptunprotectdata(); + test_simpleroundtrip("", 1); + test_simpleroundtrip("hello", 0); /* deinit globals here */ if (cipher.pbData) LocalFree(cipher.pbData); diff --git a/rostests/winetests/crypt32/sip.c b/rostests/winetests/crypt32/sip.c index 372d7ceaac9..8d9af75a73c 100644 --- a/rostests/winetests/crypt32/sip.c +++ b/rostests/winetests/crypt32/sip.c @@ -181,8 +181,10 @@ static void test_SIPRetrieveSubjectGUID(void) memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(deadbeef, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); - ok (GetLastError() == ERROR_FILE_NOT_FOUND, - "Expected ERROR_FILE_NOT_FOUND, got %d.\n", GetLastError()); + ok (GetLastError() == ERROR_FILE_NOT_FOUND || + GetLastError() == ERROR_PATH_NOT_FOUND, + "Expected ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND, got %d.\n", + GetLastError()); ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", show_guid(&subject, guid1)); diff --git a/rostests/winetests/crypt32/store.c b/rostests/winetests/crypt32/store.c index ae10fbcfed2..ee91e73b77d 100644 --- a/rostests/winetests/crypt32/store.c +++ b/rostests/winetests/crypt32/store.c @@ -277,11 +277,53 @@ static void testMemStore(void) CertCloseStore(store1, 0); } +static void compareFile(LPCWSTR filename, const BYTE *pb, DWORD cb) +{ + HANDLE h; + BYTE buf[200]; + BOOL ret; + DWORD cbRead = 0, totalRead = 0; + + h = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) + return; + do { + ret = ReadFile(h, buf, sizeof(buf), &cbRead, NULL); + if (ret && cbRead) + { + ok(totalRead + cbRead <= cb, "Expected total count %d, see %d\n", + cb, totalRead + cbRead); + ok(!memcmp(pb + totalRead, buf, cbRead), + "Unexpected data in file\n"); + totalRead += cbRead; + } + } while (ret && cbRead); + CloseHandle(h); +} + +static const BYTE serializedStoreWithCert[] = { + 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00, + 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, + 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, + 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, + 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, + 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, + 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, + 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00, + 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, + 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00 }; + static void testCollectionStore(void) { HCERTSTORE store1, store2, collection, collection2; PCCERT_CONTEXT context; BOOL ret; + static const WCHAR szPrefix[] = { 'c','e','r',0 }; + static const WCHAR szDot[] = { '.',0 }; + WCHAR filename[MAX_PATH]; + HANDLE file; if (!pCertAddStoreToCollection) { @@ -573,6 +615,86 @@ static void testCollectionStore(void) CertCloseStore(collection, 0); CertCloseStore(store2, 0); CertCloseStore(store1, 0); + + /* Test adding certificates to and deleting certificates from collections. + */ + store1 = CertOpenSystemStoreA(0, "My"); + collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + + ret = CertAddEncodedCertificateToStore(store1, X509_ASN_ENCODING, + bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); + CertDeleteCertificateFromStore(context); + + CertAddStoreToCollection(collection, store1, + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); + + ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, + bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, &context); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", GetLastError()); + CertDeleteCertificateFromStore(context); + + CertCloseStore(collection, 0); + CertCloseStore(store1, 0); + + /* Test whether a collection store can be committed */ + if (!pCertControlStore) + { + win_skip("CertControlStore() is not available\n"); + return; + } + collection = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + + SetLastError(0xdeadbeef); + ret = pCertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL); + ok(ret, "CertControlStore failed: %08x\n", GetLastError()); + + /* Adding a mem store that can't be committed prevents a successful commit. + */ + store1 = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + pCertAddStoreToCollection(collection, store1, 0, 0); + SetLastError(0xdeadbeef); + ret = pCertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL); + ok(!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, + "expected ERROR_CALL_NOT_IMPLEMENTED, got %d\n", GetLastError()); + pCertRemoveStoreFromCollection(collection, store1); + CertCloseStore(store1, 0); + + /* Test adding a cert to a collection with a file store, committing the + * change to the collection, and comparing the resulting file. + */ + if (!GetTempFileNameW(szDot, szPrefix, 0, filename)) + return; + + DeleteFileW(filename); + file = CreateFileW(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) + return; + + store1 = CertOpenStore(CERT_STORE_PROV_FILE, 0, 0, + CERT_FILE_STORE_COMMIT_ENABLE_FLAG, file); + ok(store1 != NULL, "CertOpenStore failed: %08x\n", GetLastError()); + CloseHandle(file); + pCertAddStoreToCollection(collection, store1, + CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG, 0); + CertCloseStore(store1, 0); + + ret = CertAddEncodedCertificateToStore(collection, X509_ASN_ENCODING, + bigCert, sizeof(bigCert), CERT_STORE_ADD_ALWAYS, NULL); + ok(ret, "CertAddEncodedCertificateToStore failed: %08x\n", + GetLastError()); + ret = pCertControlStore(collection, 0, CERT_STORE_CTRL_COMMIT, NULL); + ok(ret, "CertControlStore failed: %d\n", ret); + + CertCloseStore(collection, 0); + + compareFile(filename, serializedStoreWithCert, + sizeof(serializedStoreWithCert)); + DeleteFileW(filename); } /* Looks for the property with ID propID in the buffer buf. Returns a pointer @@ -1046,18 +1168,6 @@ static void testSystemStore(void) RegDeleteKeyW(HKEY_CURRENT_USER, BogusPathW); } -static const BYTE serializedStoreWithCert[] = { - 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00, - 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, - 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61, - 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31, - 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36, - 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15, - 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e, - 0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00, - 0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04, - 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00 }; static const BYTE serializedStoreWithCertAndCRL[] = { 0x00,0x00,0x00,0x00,0x43,0x45,0x52,0x54,0x20,0x00,0x00,0x00,0x01,0x00,0x00, 0x00,0x7c,0x00,0x00,0x00,0x30,0x7a,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30, @@ -1076,31 +1186,6 @@ static const BYTE serializedStoreWithCertAndCRL[] = { 0x00,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; -static void compareFile(LPCWSTR filename, const BYTE *pb, DWORD cb) -{ - HANDLE h; - BYTE buf[200]; - BOOL ret; - DWORD cbRead = 0, totalRead = 0; - - h = CreateFileW(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (h == INVALID_HANDLE_VALUE) - return; - do { - ret = ReadFile(h, buf, sizeof(buf), &cbRead, NULL); - if (ret && cbRead) - { - ok(totalRead + cbRead <= cb, "Expected total count %d, see %d\n", - cb, totalRead + cbRead); - ok(!memcmp(pb + totalRead, buf, cbRead), - "Unexpected data in file\n"); - totalRead += cbRead; - } - } while (ret && cbRead); - CloseHandle(h); -} - static void testFileStore(void) { static const WCHAR szPrefix[] = { 'c','e','r',0 }; @@ -2074,7 +2159,6 @@ static void test_I_UpdateStore(void) certs = countCertsInStore(store1); ok(certs == 0, "Expected 0 certs, got %d\n", certs); - CertFreeCertificateContext(cert); CertCloseStore(store1, 0); CertCloseStore(store2, 0); } From 767e2566ffba4dd91aa579eab51e77ef8dbf6bc1 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 15 Nov 2009 23:19:33 +0000 Subject: [PATCH 058/140] partial shell32 sync svn path=/trunk/; revision=44186 --- reactos/dll/win32/shell32/dde.c | 2 +- reactos/dll/win32/shell32/shellord.c | 33 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/reactos/dll/win32/shell32/dde.c b/reactos/dll/win32/shell32/dde.c index 63f47877954..e2d1458b972 100644 --- a/reactos/dll/win32/shell32/dde.c +++ b/reactos/dll/win32/shell32/dde.c @@ -104,7 +104,7 @@ static HDDEDATA CALLBACK DdeCallback( case XTYP_WILDCONNECT: return (HDDEDATA)(DWORD_PTR)Dde_OnWildConnect(hsz1, hsz2); case XTYP_REQUEST: - return (HDDEDATA)Dde_OnRequest(uFmt, hconv, hsz1, hsz2); + return Dde_OnRequest(uFmt, hconv, hsz1, hsz2); case XTYP_EXECUTE: return (HDDEDATA)(DWORD_PTR)Dde_OnExecute(hconv, hsz1, hdata); case XTYP_DISCONNECT: diff --git a/reactos/dll/win32/shell32/shellord.c b/reactos/dll/win32/shell32/shellord.c index 13d33c5fe9c..05adda5c5b3 100644 --- a/reactos/dll/win32/shell32/shellord.c +++ b/reactos/dll/win32/shell32/shellord.c @@ -383,7 +383,7 @@ int WINAPIV ShellMessageBoxW( va_end(args); ret = MessageBoxW(hWnd,pszTemp,pszTitle,uType); - LocalFree((HLOCAL)pszTemp); + LocalFree(pszTemp); return ret; } @@ -441,16 +441,18 @@ int WINAPIV ShellMessageBoxA( va_end(args); ret = MessageBoxA(hWnd,pszTemp,pszTitle,uType); - LocalFree((HLOCAL)pszTemp); + LocalFree(pszTemp); return ret; } /************************************************************************* * SHRegisterDragDrop [SHELL32.86] * - * Probably equivalent to RegisterDragDrop but under Windows 9x it could use the + * Probably equivalent to RegisterDragDrop but under Windows 95 it could use the * shell32 built-in "mini-COM" without the need to load ole32.dll - see SHLoadOLE - * for details + * for details. Under Windows 98 this function initializes the true OLE when called + * the first time, on XP always returns E_OUTOFMEMORY and it got removed from Vista. + * * * NOTES * exported by ordinal @@ -471,7 +473,7 @@ HRESULT WINAPI SHRegisterDragDrop( * * Probably equivalent to RevokeDragDrop but under Windows 9x it could use the * shell32 built-in "mini-COM" without the need to load ole32.dll - see SHLoadOLE - * for details + * for details. Function removed from Windows Vista. * * NOTES * exported by ordinal @@ -648,7 +650,7 @@ static INT SHADD_create_add_mru_data(HANDLE mruhandle, LPCSTR doc_name, LPCSTR n /* Add the new entry into the MRU list */ - return AddMRUData(mruhandle, (LPCVOID)buffer, *len); + return AddMRUData(mruhandle, buffer, *len); } /************************************************************************* @@ -704,7 +706,7 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv) /* See if we need to do anything. */ datalen = 64; - ret=SHADD_get_policy( "NoRecentDocsHistory", &type, &data, &datalen); + ret=SHADD_get_policy( "NoRecentDocsHistory", &type, data, &datalen); if ((ret > 0) && (ret != ERROR_FILE_NOT_FOUND)) { ERR("Error %d getting policy \"NoRecentDocsHistory\"\n", ret); return; @@ -799,15 +801,15 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv) switch (uFlags) { case SHARD_PIDL: - SHGetPathFromIDListA((LPCITEMIDLIST) pv, doc_name); + SHGetPathFromIDListA(pv, doc_name); break; case SHARD_PATHA: - lstrcpynA(doc_name, (LPCSTR)pv, MAX_PATH); + lstrcpynA(doc_name, pv, MAX_PATH); break; case SHARD_PATHW: - WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pv, -1, doc_name, MAX_PATH, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, pv, -1, doc_name, MAX_PATH, NULL, NULL); break; default: @@ -955,9 +957,9 @@ void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv) /* Set the document path or pidl */ if (uFlags == SHARD_PIDL) { - hres = IShellLinkA_SetIDList(psl, (LPCITEMIDLIST) pv); + hres = IShellLinkA_SetIDList(psl, pv); } else { - hres = IShellLinkA_SetPath(psl, (LPCSTR) pv); + hres = IShellLinkA_SetPath(psl, pv); } if(FAILED(hres)) { /* bombed */ @@ -1277,7 +1279,7 @@ BOOL WINAPI FileIconInit(BOOL bFullInit) * RETURNS * Success: TRUE * Failure: FALSE - */ + */ BOOL WINAPI IsUserAnAdmin(VOID) { SID_IDENTIFIER_AUTHORITY Authority = {SECURITY_NT_AUTHORITY}; @@ -1289,7 +1291,6 @@ BOOL WINAPI IsUserAnAdmin(VOID) BOOL bResult = FALSE; TRACE("\n"); - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { return FALSE; @@ -1706,7 +1707,7 @@ HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_ if (lRet == ERROR_SUCCESS) { /* Create and initialize the Property Sheet Extensions Array */ - psxa = (PPSXA)LocalAlloc(LMEM_FIXED, FIELD_OFFSET(PSXA, pspsx[max_iface])); + psxa = LocalAlloc(LMEM_FIXED, FIELD_OFFSET(PSXA, pspsx[max_iface])); if (psxa) { ZeroMemory(psxa, FIELD_OFFSET(PSXA, pspsx[max_iface])); @@ -1836,7 +1837,7 @@ void WINAPI SHDestroyPropSheetExtArray(HPSXA hpsxa) psxa->pspsx[i]->lpVtbl->Release(psxa->pspsx[i]); } - LocalFree((HLOCAL)psxa); + LocalFree(psxa); } } From 25f74e7771159b259280d7de6e117a01a3f3a8a6 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 15 Nov 2009 23:25:01 +0000 Subject: [PATCH 059/140] sync rsaenh winetest with wine 1.1.33 svn path=/trunk/; revision=44187 --- rostests/winetests/rsaenh/rsaenh.c | 247 ++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 5 deletions(-) diff --git a/rostests/winetests/rsaenh/rsaenh.c b/rostests/winetests/rsaenh/rsaenh.c index bfe2b5a6a54..e59ad95a8c2 100644 --- a/rostests/winetests/rsaenh/rsaenh.c +++ b/rostests/winetests/rsaenh/rsaenh.c @@ -176,7 +176,7 @@ static int init_aes_environment(void) result = CryptAcquireContext(&hProv, szContainer, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT); if (!result && GetLastError() == NTE_PROV_TYPE_NOT_DEF) { - win_skip("RSA_ASE provider not supported\n"); + win_skip("RSA_AES provider not supported\n"); return 0; } ok(!result && GetLastError()==NTE_BAD_FLAGS, "%d, %08x\n", result, GetLastError()); @@ -459,7 +459,7 @@ static void test_block_cipher_modes(void) result = derive_key(CALG_RC2, &hKey, 40); if (!result) return; - memcpy(abData, plain, sizeof(abData)); + memcpy(abData, plain, sizeof(plain)); dwMode = CRYPT_MODE_ECB; result = CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&dwMode, 0); @@ -1632,10 +1632,10 @@ static void test_rsa_encrypt(void) static void test_import_export(void) { DWORD dwLen, dwDataLen, dwVal; - HCRYPTKEY hPublicKey; + HCRYPTKEY hPublicKey, hPrivKey; BOOL result; ALG_ID algID; - BYTE emptyKey[2048]; + BYTE emptyKey[2048], *exported_key; static BYTE abPlainPublicKey[84] = { 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00, @@ -1649,6 +1649,160 @@ static void test_import_export(void) 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; + static BYTE priv_key_with_high_bit[] = { + 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66, + 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58, + 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e, + 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03, + 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4, + 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91, + 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5, + 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1, + 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd, + 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8, + 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53, + 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37, + 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26, + 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1, + 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d, + 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e, + 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68, + 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b, + 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8, + 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b, + 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15, + 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78, + 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2, + 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2, + 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31, + 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c, + 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7, + 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d, + 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37, + 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a, + 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c, + 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99, + 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef, + 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9, + 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec, + 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d, + 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e, + 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42, + 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98, + 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12, + 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73, + 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d, + 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23, + 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0, + 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19, + 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0, + 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8, + 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa, + 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8, + 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c, + 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2, + 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12, + 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42, + 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d, + 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1, + 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4, + 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91, + 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15, + 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe, + 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7, + 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4, + 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60, + 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17, + 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e, + 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33, + 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98, + 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50, + 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6, + 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f, + 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98, + 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08, + 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59, + 0xb6, 0x5f, 0x01, 0x5e + }; + static const BYTE expected_exported_priv_key[] = { + 0x07, 0x02, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x52, 0x53, 0x41, 0x32, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0xd5, 0xa2, 0x0d, 0x66, + 0xfe, 0x65, 0xb5, 0xf1, 0xc9, 0x6b, 0xf5, 0x58, + 0x04, 0x38, 0x2d, 0xf4, 0xa3, 0x5a, 0xda, 0x9e, + 0x95, 0x81, 0x85, 0x3d, 0x01, 0x07, 0xb2, 0x03, + 0x77, 0x70, 0x79, 0x6e, 0x6c, 0x26, 0x42, 0xa4, + 0x12, 0xfd, 0xaa, 0x29, 0x83, 0x04, 0xce, 0x91, + 0x90, 0x39, 0x5e, 0x49, 0x56, 0xfd, 0x0a, 0xe5, + 0xb1, 0xea, 0x3b, 0xb2, 0x70, 0xb0, 0x20, 0xc1, + 0x1f, 0x22, 0x07, 0x3e, 0x4d, 0xc0, 0x73, 0xfd, + 0x92, 0x8f, 0x87, 0xd8, 0xd1, 0xd1, 0x28, 0xd8, + 0x19, 0xd1, 0x93, 0x83, 0xe0, 0xb8, 0x9f, 0x53, + 0xf4, 0x6a, 0x7c, 0xcb, 0x10, 0x53, 0xd0, 0x37, + 0x02, 0xb4, 0xa5, 0xf7, 0xa2, 0x28, 0x6e, 0x26, + 0xef, 0x5c, 0x14, 0x01, 0x40, 0x1e, 0xa3, 0xe1, + 0xda, 0x76, 0xd0, 0x12, 0x84, 0xb7, 0x48, 0x7d, + 0xc8, 0x67, 0x5c, 0xb2, 0xd5, 0x2e, 0xaf, 0x8e, + 0x7d, 0x32, 0x59, 0x92, 0x01, 0xd6, 0x5b, 0x68, + 0x28, 0x9b, 0xb1, 0x6c, 0x69, 0xeb, 0x61, 0x5b, + 0x4b, 0x13, 0xe2, 0xbd, 0x7d, 0xbe, 0xce, 0xe8, + 0x41, 0x54, 0xca, 0xa8, 0xdd, 0xc7, 0xfe, 0x8b, + 0xdf, 0xf6, 0x55, 0x6c, 0x50, 0x11, 0xc8, 0x15, + 0x13, 0x42, 0x59, 0x9f, 0xbb, 0xea, 0x73, 0x78, + 0x7b, 0x22, 0x8d, 0x96, 0x62, 0xe5, 0xda, 0xa2, + 0x85, 0x5c, 0x20, 0x74, 0x9f, 0x1c, 0x12, 0xf2, + 0x48, 0x06, 0x1a, 0xc6, 0xd5, 0x94, 0xec, 0x31, + 0x6b, 0xb6, 0x7b, 0x54, 0x61, 0x77, 0xec, 0x7c, + 0x6f, 0xb7, 0x55, 0x3d, 0x6b, 0x98, 0x05, 0xd7, + 0x8a, 0x73, 0x25, 0xf2, 0x8f, 0xe4, 0xb8, 0x8d, + 0x27, 0x18, 0x0d, 0x05, 0xba, 0x23, 0x54, 0x37, + 0x10, 0xf0, 0x1c, 0x41, 0xa6, 0xae, 0x4c, 0x2a, + 0x6a, 0x2f, 0x7f, 0x68, 0x43, 0x86, 0xe7, 0x9c, + 0xfd, 0x9e, 0xf1, 0xfe, 0x84, 0xe3, 0xb6, 0x99, + 0x51, 0xfe, 0x1e, 0xbd, 0x01, 0xc6, 0x10, 0xef, + 0x88, 0xa4, 0xd8, 0x53, 0x14, 0x88, 0x15, 0xc9, + 0xe5, 0x86, 0xe2, 0x8d, 0x85, 0x2e, 0x0d, 0xec, + 0x15, 0xa7, 0x48, 0xfa, 0x18, 0xfb, 0x01, 0x8d, + 0x2b, 0x90, 0x70, 0x7f, 0x78, 0xb1, 0x33, 0x7e, + 0xfe, 0x82, 0x40, 0x5f, 0x4a, 0x97, 0xc2, 0x42, + 0x22, 0xd5, 0x5f, 0xbc, 0xbd, 0xab, 0x26, 0x98, + 0xcd, 0xb5, 0xdf, 0x7e, 0xa0, 0x68, 0xa7, 0x12, + 0x9e, 0xa5, 0xa2, 0x90, 0x85, 0xc5, 0xca, 0x73, + 0x4a, 0x59, 0x8a, 0xec, 0xcf, 0xdd, 0x65, 0x5d, + 0xc1, 0xaa, 0x86, 0x53, 0xd5, 0xde, 0xbb, 0x23, + 0x24, 0xb8, 0x9b, 0x74, 0x03, 0x20, 0xb4, 0xf0, + 0xe4, 0xdd, 0xd2, 0x03, 0xfd, 0x67, 0x55, 0x19, + 0x28, 0x1d, 0xc1, 0xb8, 0xa5, 0x89, 0x0e, 0xc0, + 0x80, 0x9d, 0xdd, 0xda, 0x9d, 0x30, 0x5c, 0xc8, + 0xbb, 0xfe, 0x8f, 0xce, 0xd5, 0xf6, 0xdf, 0xfa, + 0x14, 0xaf, 0xe4, 0xba, 0xb0, 0x84, 0x45, 0xd8, + 0x67, 0xa7, 0xd0, 0xce, 0x89, 0x2a, 0x30, 0x8c, + 0xfa, 0xe9, 0x65, 0xa4, 0x21, 0x2d, 0x6b, 0xa2, + 0x9b, 0x8f, 0x92, 0xbd, 0x3a, 0x10, 0x71, 0x12, + 0xc2, 0x02, 0x3d, 0xd5, 0x83, 0x1d, 0xfa, 0x42, + 0xb7, 0x48, 0x1b, 0x31, 0xe3, 0x82, 0x90, 0x2d, + 0x91, 0x59, 0xf9, 0x38, 0x52, 0xe5, 0xdb, 0xc1, + 0x4d, 0x3a, 0xe6, 0x9b, 0x6a, 0xbb, 0xea, 0xa4, + 0x8d, 0x5e, 0xc4, 0x00, 0x01, 0xb8, 0xec, 0x91, + 0xc1, 0xdb, 0x63, 0xbd, 0x57, 0xb6, 0x26, 0x15, + 0xb6, 0x3e, 0xa2, 0xdf, 0x62, 0x8d, 0xa8, 0xbe, + 0xe1, 0xf1, 0x39, 0xbd, 0x18, 0xd2, 0x6f, 0xd7, + 0xda, 0xdc, 0x71, 0x30, 0xf1, 0x21, 0x71, 0xa4, + 0x08, 0x43, 0x46, 0xdf, 0x50, 0xbd, 0x3c, 0x60, + 0x5b, 0x63, 0x35, 0xe3, 0x37, 0x5b, 0x25, 0x17, + 0x54, 0x5e, 0x68, 0x60, 0xb6, 0x49, 0xef, 0x6e, + 0x09, 0xef, 0xda, 0x90, 0x3e, 0xd4, 0x09, 0x33, + 0x36, 0x57, 0x9a, 0x14, 0xbd, 0xf7, 0xb1, 0x98, + 0x30, 0x42, 0x03, 0x84, 0x61, 0xeb, 0x8e, 0x50, + 0xdc, 0x6a, 0x93, 0x1b, 0x32, 0x51, 0xf9, 0xc6, + 0xc2, 0x19, 0xb3, 0x5d, 0xe2, 0xf8, 0xc5, 0x8f, + 0x68, 0xaa, 0x1d, 0xdb, 0xd3, 0x7f, 0x8d, 0x98, + 0x9c, 0x16, 0x8c, 0xc3, 0xcd, 0xd9, 0xdb, 0x08, + 0xe6, 0x36, 0x60, 0xb6, 0x36, 0xdc, 0x1d, 0x59, + 0xb6, 0x5f, 0x01, 0x5e + }; dwLen=84; result = CryptImportKey(hProv, abPlainPublicKey, dwLen, 0, 0, &hPublicKey); @@ -1674,6 +1828,26 @@ static void test_import_export(void) ok(!memcmp(emptyKey, abPlainPublicKey, dwLen), "exported key is different from the imported key\n"); CryptDestroyKey(hPublicKey); + + result = CryptImportKey(hProv, priv_key_with_high_bit, + sizeof(priv_key_with_high_bit), 0, CRYPT_EXPORTABLE, &hPrivKey); + ok(result, "CryptImportKey failed: %08x\n", GetLastError()); + + result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, NULL, &dwDataLen); + ok(result, "CryptExportKey failed: %08x\n", GetLastError()); + exported_key = HeapAlloc(GetProcessHeap(), 0, dwDataLen); + result = CryptExportKey(hPrivKey, 0, PRIVATEKEYBLOB, 0, exported_key, + &dwDataLen); + ok(result, "CryptExportKey failed: %08x\n", GetLastError()); + + ok(dwDataLen == sizeof(expected_exported_priv_key), "unexpected size %d\n", + dwDataLen); + ok(!memcmp(exported_key, expected_exported_priv_key, dwDataLen), + "unexpected value\n"); + + HeapFree(GetProcessHeap(), 0, exported_key); + + CryptDestroyKey(hPrivKey); } static void test_schannel_provider(void) @@ -1857,6 +2031,68 @@ static void test_schannel_provider(void) CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SCHANNEL, CRYPT_DELETEKEYSET); } +/* Test that a key can be used to encrypt data and exported, and that, when + * the exported key is imported again, can be used to decrypt the original + * data again. + */ +static void test_rsa_round_trip(void) +{ + static const char test_string[] = "Well this is a fine how-do-you-do."; + HCRYPTPROV prov; + HCRYPTKEY signKey, keyExchangeKey; + BOOL result; + BYTE data[256], *exportedKey; + DWORD dataLen, keyLen; + + CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, + CRYPT_DELETEKEYSET); + + /* Generate a new key... */ + result = CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, + CRYPT_NEWKEYSET); + ok(result, "CryptAcquireContext failed: %08x\n", GetLastError()); + result = CryptGenKey(prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &signKey); + ok(result, "CryptGenKey with CALG_RSA_KEYX failed with error %08x\n", GetLastError()); + result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &keyExchangeKey); + ok(result, "CryptGetUserKey failed: %08x\n", GetLastError()); + /* encrypt some data with it... */ + memcpy(data, test_string, strlen(test_string) + 1); + dataLen = strlen(test_string) + 1; + result = CryptEncrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen, + sizeof(data)); + ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */), + "CryptEncrypt failed: %08x\n", GetLastError()); + /* export the key... */ + result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, NULL, + &keyLen); + ok(result, "CryptExportKey failed: %08x\n", GetLastError()); + exportedKey = HeapAlloc(GetProcessHeap(), 0, keyLen); + result = CryptExportKey(keyExchangeKey, 0, PRIVATEKEYBLOB, 0, exportedKey, + &keyLen); + /* destroy the key... */ + CryptDestroyKey(keyExchangeKey); + CryptDestroyKey(signKey); + /* import the key again... */ + result = CryptImportKey(prov, exportedKey, keyLen, 0, 0, &keyExchangeKey); + ok(result, "CryptImportKey failed: %08x\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, exportedKey); + /* and decrypt the data encrypted with the original key with the imported + * key. + */ + result = CryptDecrypt(keyExchangeKey, 0, TRUE, 0, data, &dataLen); + ok(result || broken(GetLastError() == NTE_BAD_KEY /* Win9x/2000 */), + "CryptDecrypt failed: %08x\n", GetLastError()); + if (result) + { + ok(dataLen == sizeof(test_string), "unexpected size %d\n", dataLen); + ok(!memcmp(data, test_string, sizeof(test_string)), "unexpected value"); + } + CryptReleaseContext(prov, 0); + + CryptAcquireContext(&prov, szContainer, NULL, PROV_RSA_FULL, + CRYPT_DELETEKEYSET); +} + static void test_enum_container(void) { BYTE abContainerName[MAX_PATH + 2]; /* Larger than maximum name len */ @@ -2071,7 +2307,7 @@ static void test_null_provider(void) ok(result, "CryptAcquireContext failed: %08x\n", GetLastError()); if (!result) return; result = CryptImportKey(prov, signBlob, sizeof(signBlob), 0, 0, &key); - ok(result, "CryptGenKey failed: %08x\n", GetLastError()); + ok(result, "CryptImportKey failed: %08x\n", GetLastError()); CryptDestroyKey(key); /* doesn't allow access to the key exchange key.. */ result = CryptGetUserKey(prov, AT_KEYEXCHANGE, &key); @@ -2319,6 +2555,7 @@ START_TEST(rsaenh) test_key_initialization(); test_schannel_provider(); test_null_provider(); + test_rsa_round_trip(); if (!init_aes_environment()) return; test_aes(128); From 20028cfb2f60646725091ad2b5e49605c035e3d8 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 15 Nov 2009 23:28:15 +0000 Subject: [PATCH 060/140] sync rsaenh with wine 1.1.33 svn path=/trunk/; revision=44188 --- reactos/dll/win32/rsaenh/implglue.c | 40 +++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/reactos/dll/win32/rsaenh/implglue.c b/reactos/dll/win32/rsaenh/implglue.c index 68a9380f6a7..b73eba93ec6 100644 --- a/reactos/dll/win32/rsaenh/implglue.c +++ b/reactos/dll/win32/rsaenh/implglue.c @@ -361,7 +361,10 @@ BOOL gen_rand_impl(BYTE *pbBuffer, DWORD dwLen) BOOL export_public_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD dwKeyLen,DWORD *pdwPubExp) { mp_to_unsigned_bin(&pKeyContext->rsa.N, pbDest); - reverse_bytes(pbDest, dwKeyLen); + reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.N)); + if (mp_unsigned_bin_size(&pKeyContext->rsa.N) < dwKeyLen) + memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.N), 0, + dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.N)); *pdwPubExp = (DWORD)mp_get_int(&pKeyContext->rsa.e); return TRUE; } @@ -396,25 +399,46 @@ BOOL export_private_key_impl(BYTE *pbDest, const KEY_CONTEXT *pKeyContext, DWORD DWORD *pdwPubExp) { mp_to_unsigned_bin(&pKeyContext->rsa.N, pbDest); - reverse_bytes(pbDest, dwKeyLen); + reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.N)); + if (mp_unsigned_bin_size(&pKeyContext->rsa.N) < dwKeyLen) + memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.N), 0, + dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.N)); pbDest += dwKeyLen; mp_to_unsigned_bin(&pKeyContext->rsa.p, pbDest); - reverse_bytes(pbDest, (dwKeyLen+1)>>1); + reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.p)); + if (mp_unsigned_bin_size(&pKeyContext->rsa.p) < (dwKeyLen+1)>>1) + memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.p), 0, + ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.p)); pbDest += (dwKeyLen+1)>>1; mp_to_unsigned_bin(&pKeyContext->rsa.q, pbDest); - reverse_bytes(pbDest, (dwKeyLen+1)>>1); + reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.q)); + if (mp_unsigned_bin_size(&pKeyContext->rsa.q) < (dwKeyLen+1)>>1) + memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.q), 0, + ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.q)); pbDest += (dwKeyLen+1)>>1; mp_to_unsigned_bin(&pKeyContext->rsa.dP, pbDest); - reverse_bytes(pbDest, (dwKeyLen+1)>>1); + reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.dP)); + if (mp_unsigned_bin_size(&pKeyContext->rsa.dP) < (dwKeyLen+1)>>1) + memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.dP), 0, + ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.dP)); pbDest += (dwKeyLen+1)>>1; mp_to_unsigned_bin(&pKeyContext->rsa.dQ, pbDest); - reverse_bytes(pbDest, (dwKeyLen+1)>>1); + reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.dQ)); + if (mp_unsigned_bin_size(&pKeyContext->rsa.dQ) < (dwKeyLen+1)>>1) + memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.dQ), 0, + ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.dQ)); pbDest += (dwKeyLen+1)>>1; mp_to_unsigned_bin(&pKeyContext->rsa.qP, pbDest); - reverse_bytes(pbDest, (dwKeyLen+1)>>1); + reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.qP)); + if (mp_unsigned_bin_size(&pKeyContext->rsa.qP) < (dwKeyLen+1)>>1) + memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.qP), 0, + ((dwKeyLen+1)>>1) - mp_unsigned_bin_size(&pKeyContext->rsa.qP)); pbDest += (dwKeyLen+1)>>1; mp_to_unsigned_bin(&pKeyContext->rsa.d, pbDest); - reverse_bytes(pbDest, dwKeyLen); + reverse_bytes(pbDest, mp_unsigned_bin_size(&pKeyContext->rsa.d)); + if (mp_unsigned_bin_size(&pKeyContext->rsa.d) < dwKeyLen) + memset(pbDest + mp_unsigned_bin_size(&pKeyContext->rsa.d), 0, + dwKeyLen - mp_unsigned_bin_size(&pKeyContext->rsa.d)); *pdwPubExp = (DWORD)mp_get_int(&pKeyContext->rsa.e); return TRUE; From f12b3f3e8da4a27b77b86c302febd73392516662 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Sun, 15 Nov 2009 23:44:20 +0000 Subject: [PATCH 061/140] sync mshtml to wine 1.1.33 svn path=/trunk/; revision=44189 --- reactos/dll/win32/mshtml/Bg.rc | 14 +- reactos/dll/win32/mshtml/Da.rc | 13 +- reactos/dll/win32/mshtml/De.rc | 8 +- reactos/dll/win32/mshtml/En.rc | 13 +- reactos/dll/win32/mshtml/Es.rc | 7 +- reactos/dll/win32/mshtml/Fr.rc | 7 +- reactos/dll/win32/mshtml/Ja.rc | 13 +- reactos/dll/win32/mshtml/Ko.rc | 13 +- reactos/dll/win32/mshtml/Lt.rc | 13 +- reactos/dll/win32/mshtml/Nl.rc | 8 +- reactos/dll/win32/mshtml/No.rc | 13 +- reactos/dll/win32/mshtml/Pl.rc | 13 +- reactos/dll/win32/mshtml/Pt.rc | 7 +- reactos/dll/win32/mshtml/Ro.rc | 5 +- reactos/dll/win32/mshtml/Ru.rc | 13 +- reactos/dll/win32/mshtml/Si.rc | 8 +- reactos/dll/win32/mshtml/Sv.rc | 13 +- reactos/dll/win32/mshtml/Tr.rc | 7 +- reactos/dll/win32/mshtml/Zh.rc | 13 +- reactos/dll/win32/mshtml/dispex.c | 58 +++- reactos/dll/win32/mshtml/editor.c | 55 ++-- reactos/dll/win32/mshtml/htmlanchor.c | 4 +- reactos/dll/win32/mshtml/htmlbody.c | 8 +- reactos/dll/win32/mshtml/htmlcomment.c | 6 +- reactos/dll/win32/mshtml/htmlcurstyle.c | 4 +- reactos/dll/win32/mshtml/htmldoc.c | 145 ++++----- reactos/dll/win32/mshtml/htmldoc3.c | 23 +- reactos/dll/win32/mshtml/htmldoc5.c | 142 ++++++++- reactos/dll/win32/mshtml/htmlelem.c | 87 ++++-- reactos/dll/win32/mshtml/htmlelem2.c | 11 +- reactos/dll/win32/mshtml/htmlelem3.c | 8 +- reactos/dll/win32/mshtml/htmlelemcol.c | 2 +- reactos/dll/win32/mshtml/htmlevent.c | 150 +++++++-- reactos/dll/win32/mshtml/htmlevent.h | 8 +- reactos/dll/win32/mshtml/htmlframebase.c | 326 ++++++++++++++++++++ reactos/dll/win32/mshtml/htmlgeneric.c | 4 +- reactos/dll/win32/mshtml/htmliframe.c | 148 ++++----- reactos/dll/win32/mshtml/htmlimg.c | 208 ++++++++++++- reactos/dll/win32/mshtml/htmlinput.c | 25 +- reactos/dll/win32/mshtml/htmllocation.c | 303 +++++++++++++++--- reactos/dll/win32/mshtml/htmlnode.c | 29 +- reactos/dll/win32/mshtml/htmloption.c | 28 +- reactos/dll/win32/mshtml/htmlscript.c | 4 +- reactos/dll/win32/mshtml/htmlselect.c | 5 +- reactos/dll/win32/mshtml/htmltable.c | 4 +- reactos/dll/win32/mshtml/htmltablerow.c | 4 +- reactos/dll/win32/mshtml/htmltextarea.c | 5 +- reactos/dll/win32/mshtml/htmltextcont.c | 5 +- reactos/dll/win32/mshtml/htmlwindow.c | 351 +++++++++++++++++---- reactos/dll/win32/mshtml/main.c | 11 +- reactos/dll/win32/mshtml/mshtml.inf | 81 ++++- reactos/dll/win32/mshtml/mshtml.rbuild | 1 + reactos/dll/win32/mshtml/mshtml_private.h | 218 ++++++++----- reactos/dll/win32/mshtml/mutation.c | 359 ++++++++++++++++------ reactos/dll/win32/mshtml/navigate.c | 143 ++++++--- reactos/dll/win32/mshtml/nsembed.c | 68 +--- reactos/dll/win32/mshtml/nsevents.c | 230 ++++++++++---- reactos/dll/win32/mshtml/nsiface.idl | 72 ++++- reactos/dll/win32/mshtml/nsio.c | 320 +++++++++++++------ reactos/dll/win32/mshtml/olecmd.c | 12 +- reactos/dll/win32/mshtml/persist.c | 161 +++++++--- reactos/dll/win32/mshtml/script.c | 9 +- reactos/dll/win32/mshtml/secmgr.c | 6 +- reactos/dll/win32/mshtml/selection.c | 4 +- reactos/dll/win32/mshtml/task.c | 194 +----------- reactos/dll/win32/mshtml/txtrange.c | 20 +- reactos/include/psdk/mshtmdid.h | 118 ++----- reactos/include/psdk/mshtml.idl | 101 +++++- 68 files changed, 3159 insertions(+), 1330 deletions(-) create mode 100644 reactos/dll/win32/mshtml/htmlframebase.c diff --git a/reactos/dll/win32/mshtml/Bg.rc b/reactos/dll/win32/mshtml/Bg.rc index a8fd605ab09..84d7e9ae235 100644 --- a/reactos/dll/win32/mshtml/Bg.rc +++ b/reactos/dll/win32/mshtml/Bg.rc @@ -28,16 +28,16 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "Číńňŕëčđŕíĺ..." } - -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Wine Gecko Installer" FONT 8, "MS Shell Dlg" { - LTEXT "Ďđčëîćĺíčĺňî ńĺ îďčňâŕ äŕ ďîęŕćĺ HTML ńňđŕíčöŕ. Çŕ äŕ áúäĺ ďîęŕçŕíŕ ńňđŕíčöŕňŕ, " \ - "ňđ˙áâŕ äŕ čěŕňĺ Gecko (HTML ěŕřčíŕňŕ íŕ Mozilla) číńňŕëčđŕí. Ćĺëŕĺňĺ ëč Gecko " \ - "äŕ áúäĺ čçňĺăëĺí č číńňŕëčđŕí?", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Íŕďđĺäúę", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "Číńňŕëčđŕé", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Îňęŕç", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "Číńňŕëčđŕé", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Îňęŕç", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } diff --git a/reactos/dll/win32/mshtml/Da.rc b/reactos/dll/win32/mshtml/Da.rc index 574ea093afe..4218b58bf73 100644 --- a/reactos/dll/win32/mshtml/Da.rc +++ b/reactos/dll/win32/mshtml/Da.rc @@ -30,17 +30,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "Installerer..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Installere Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "Dette program prřver at vise en HTML-side. Wine har brug for Gecko" \ - "(Mozillas HTML motor) for at vise denne siden. Vćlg Installer hvis " \ - "du vil have at Wine skal hente og installere Gecko automatisk.", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progress", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "&Installer", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Annuller", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Installer", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Annuller", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/De.rc b/reactos/dll/win32/mshtml/De.rc index dd55740ee0e..727d2614ecf 100644 --- a/reactos/dll/win32/mshtml/De.rc +++ b/reactos/dll/win32/mshtml/De.rc @@ -37,10 +37,10 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Wine-Gecko-Installation" FONT 8, "MS Shell Dlg" { - LTEXT "Diese Anwendung versucht, eine HTML-Seite anzuzeigen. Wine muss " \ - "Gecko (Mozilla HTML-Bibliothek) installieren um die Seite " \ - "anzuzeigen. Klicken Sie auf „Installieren“, um Gecko automatisch " \ - "herunterzuladen und zu installieren.", ID_DWL_STATUS, 10, 10, 240, 40, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Fortschritt", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Installieren", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Abbrechen", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/En.rc b/reactos/dll/win32/mshtml/En.rc index 41ee1197050..de9e99c1b54 100644 --- a/reactos/dll/win32/mshtml/En.rc +++ b/reactos/dll/win32/mshtml/En.rc @@ -28,17 +28,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "Installing..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Wine Gecko Installer" FONT 8, "MS Shell Dlg" { - LTEXT "This application is trying to show an HTML page. Wine needs Gecko (Mozilla HTML " \ - "engine) to be installed to show the page. Click install if you want Wine to " \ - "automatically download and install Gecko.", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progress", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "&Install", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Cancel", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Install", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Cancel", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/Es.rc b/reactos/dll/win32/mshtml/Es.rc index fb79f87852c..be8fe7d350b 100644 --- a/reactos/dll/win32/mshtml/Es.rc +++ b/reactos/dll/win32/mshtml/Es.rc @@ -35,9 +35,10 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Instalador de Gecko de Wine" FONT 8, "MS Shell Dlg" { - LTEXT "Está aplicación está intentando mostrar una página HTML. Wine necesita que Gecko (Motor HTML" \ - " de Mozilla) esté instalado para mostrar la página. Pulse Instalar si desea que Wine " \ - "descargue e instale automáticamente Gecko.", ID_DWL_STATUS, 10, 10, 240, 40, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progreso", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Instalar", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Cancelar", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/Fr.rc b/reactos/dll/win32/mshtml/Fr.rc index c7671d4aed4..0d14f452e8b 100644 --- a/reactos/dll/win32/mshtml/Fr.rc +++ b/reactos/dll/win32/mshtml/Fr.rc @@ -39,9 +39,10 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Programme d'installation de Gecko pour Wine" FONT 8, "MS Shell Dlg" { - LTEXT "Cette application essaie d'afficher une page HTML. Wine requiert la prĂ©sence du moteur de rendu Gecko de Mozilla " \ - "pour afficher cette page. Cliquez sur Installer si vous souhaitez que Wine " \ - "tĂ©lĂ©charge et installe automatiquement Gecko.", ID_DWL_STATUS, 10, 10, 240, 40, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progression", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Installer", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Annuler", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/Ja.rc b/reactos/dll/win32/mshtml/Ja.rc index 202bd43164c..04fc32e785b 100644 --- a/reactos/dll/win32/mshtml/Ja.rc +++ b/reactos/dll/win32/mshtml/Ja.rc @@ -31,17 +31,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "イăłă‚ąăăĽă«ă—ă¦ă„ăľă™..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Wine Gecko イăłă‚ąăăĽă©" FONT 9, "MS Shell Dlg" { - LTEXT "ă“ă®ă‚˘ă—ăŞă‚±ăĽă‚·ă§ăłăŻ HTML ăšăĽă‚¸ă‚’表示ă—ă‚ă†ă¨ă—ă¦ă„ăľă™ă€‚ăšăĽă‚¸ă‚’表示ă™ă‚‹ă«ăŻ Wine ă«" \ - "GeckoďĽMozilla ă® HTML エăłă‚¸ăłďĽ‰ă‚’イăłă‚ąăăĽă«ă™ă‚‹ĺż…č¦ăŚă‚りăľă™ă€‚Wine ăŚč‡Şĺ‹•的㫠Gecko ă‚’ă€ă‚¦ăłă­ăĽă‰ă—イăłă‚ąăăĽă«ă™ă‚‹ă‚ă†ă«ă—ăźă„ăŞă‚‰ă°" \ - " [イăłă‚ąăăĽă«] をクăŞăクă—ă¦ăŹă ă•ă„。", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progress", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "イăłă‚ąăăĽă«(&I)", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "ă‚­ăŁăłă‚»ă«(&C)", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "イăłă‚ąăăĽă«(&I)", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "ă‚­ăŁăłă‚»ă«(&C)", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/Ko.rc b/reactos/dll/win32/mshtml/Ko.rc index 01456e39d0d..8a980609def 100644 --- a/reactos/dll/win32/mshtml/Ko.rc +++ b/reactos/dll/win32/mshtml/Ko.rc @@ -29,17 +29,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "ĽłÄˇ Áß..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Wine Gecko ĽłÄˇ Ç®±×¸˛" FONT 9, "MS Shell Dlg" { - LTEXT "ŔĚ ľîÇø®ÄÉŔĚĽÇŔş HTML ĆäŔĚÁö¸¦ ş¸ż©ÁÖ·Á°í ÇŐ´Ď´Ů. WineŔş ŔĚ ĆäŔĚÁö¸¦ ş¸ż©ÁÖ±â Ŕ§Çظ¦ " \ - "Gecko (Mozilla HTML żŁÁř)¸¦ ĽłÄˇÇŇ °ÍŔÔ´Ď´Ů. WineŔĚ ŔÚµżŔ¸·Î Gecko¸¦ ´Ůżî·ÎµĺÇĎ°í ĽłÄˇÇϱ⸦ żřÇѴٸé " \ - "[ĽłÄˇ]ąöưŔ» Ŭ¸ŻÇϽʽÿŔ", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "ÁřÇŕÁß", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "ĽłÄˇ(&I)", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "ĂëĽŇ(&C)", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "ĽłÄˇ(&I)", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "ĂëĽŇ(&C)", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/Lt.rc b/reactos/dll/win32/mshtml/Lt.rc index 26167a9adc1..9883bb4cfb5 100644 --- a/reactos/dll/win32/mshtml/Lt.rc +++ b/reactos/dll/win32/mshtml/Lt.rc @@ -31,17 +31,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "Ä®diegiama..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Wine Gecko diegimo programa" FONT 8, "MS Shell Dlg" { - LTEXT "Ĺ i programa mÄ—gina parodyti HTML puslapÄŻ. Ĺ iam puslapiui parodyti reikia, kad bĹ«tĹł " \ - "ÄŻdiegtas Gecko (Mozilla HTML variklis). Spauskite ÄŻdiegti, jei norite, kad Wine " \ - "automatiškai atsiĹłstĹł ir ÄŻdiegtĹł Gecko.", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Eiga", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "&Ä®diegti", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Atsisakyti", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Ä®diegti", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Atsisakyti", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/Nl.rc b/reactos/dll/win32/mshtml/Nl.rc index 1aab09c79d6..33baf39b518 100644 --- a/reactos/dll/win32/mshtml/Nl.rc +++ b/reactos/dll/win32/mshtml/Nl.rc @@ -35,10 +35,10 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Wine-Gecko-Installatie" FONT 8, "MS Shell Dlg" { - LTEXT "Dit programma probeert een HTML-pagina weer te geven. Wine moet " \ - "Gecko (Mozilla HTML-Bibliotheek) installeren om de pagina " \ - "weer te kunnen geven. Klik op Installeren, om Gecko automatisch " \ - "te downloaden en te installeren.", ID_DWL_STATUS, 10, 10, 240, 40, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Voortgang", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Installeren", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Afbreken", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/No.rc b/reactos/dll/win32/mshtml/No.rc index 83989a0beab..4592599edf3 100644 --- a/reactos/dll/win32/mshtml/No.rc +++ b/reactos/dll/win32/mshtml/No.rc @@ -32,17 +32,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "Installerer..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Installere Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "Dette programmer prøver ĂĄ vise en HTML-side. Wine trenger Gecko " \ - "(Mozillas HTML-motor) for ĂĄ vise denne siden. Velg «Installer» hvis " \ - "du vil at Wine skal laste ned og installere Gecko automatisk.", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progress", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "&Installer", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Avbryt", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Installer", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Avbryt", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/Pl.rc b/reactos/dll/win32/mshtml/Pl.rc index 11659ee2297..8aa357e7e56 100644 --- a/reactos/dll/win32/mshtml/Pl.rc +++ b/reactos/dll/win32/mshtml/Pl.rc @@ -29,17 +29,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "Instalacja..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Instalator Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "Ta aplikacja próbuje wyświetlić stronę HTML. Wine potrzebuje w tym celu zainstalować " \ - "Gecko (silnik HTML przeglądarek Mozilla). Wybierz 'Instaluj' jeżeli chcesz automatycznie " \ - "pobrać z Internetu i zainstalować Gecko.", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progress", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "&Instaluj", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Anuluj", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Instaluj", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Anuluj", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/Pt.rc b/reactos/dll/win32/mshtml/Pt.rc index d9ebbb3126a..0620702e5c1 100644 --- a/reactos/dll/win32/mshtml/Pt.rc +++ b/reactos/dll/win32/mshtml/Pt.rc @@ -35,9 +35,10 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Instalador Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "Esta aplicação está a tentar mostrar uma página HTML. O Wine precisa que o Gecko " \ - "(Motor HTML Mozilla) seja instalado para mostrar a página. Clique em Instalar se deseja que o Wine " \ - "descarregue e instale o Gecko automaticamente.", ID_DWL_STATUS, 10, 10, 240, 40, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progresso", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Instalar", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Cancelar", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/Ro.rc b/reactos/dll/win32/mshtml/Ro.rc index 1bac21645d2..38cd580b94a 100644 --- a/reactos/dll/win32/mshtml/Ro.rc +++ b/reactos/dll/win32/mshtml/Ro.rc @@ -36,7 +36,10 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Instalator Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "AceastÄ aplicaČ›ie Ă®ncearcÄ sÄ afiČ™eze o paginÄ HTML. Wine are nevoie de Gecko (motorul de HTML Mozilla) pentru a afiČ™a aceastÄ paginÄ. ApÄsaČ›i „InstaleazÄ” dacÄ doriČ›i ca Wine sÄ descarce Č™i sÄ instaleze Gecko Ă®n mod automat.", ID_DWL_STATUS, 10, 10, 240, 40, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progres", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&InstaleazÄ", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&RenunČ›Ä", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/Ru.rc b/reactos/dll/win32/mshtml/Ru.rc index 7638d9b8e9d..02bc433c767 100644 --- a/reactos/dll/win32/mshtml/Ru.rc +++ b/reactos/dll/win32/mshtml/Ru.rc @@ -31,17 +31,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "ĐŁŃтановка..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 261, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 261, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "ĐŁŃтановка Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "Эта программа пытаетŃŃŹ отобразить HTML ŃтраницŃ. Для её отображения Wine необходимо " \ - "ŃŃтановить Gecko (Mozilla HTML engine). Нажмите ĐşĐ˝ĐľĐżĐşŃ ŃŃтановить еŃли вы хотите, что бы Wine " \ - "автоматичеŃки загрŃзил и ŃŃтановил Gecko.", ID_DWL_STATUS, 10, 10, 240, 33, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "ПрогреŃŃ", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 46, 240, 12 - DEFPUSHBUTTON "&ĐŁŃтановить", ID_DWL_INSTALL, 200, 63, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Отмена", IDCANCEL, 140, 63, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&ĐŁŃтановить", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Отмена", IDCANCEL, 140, 63, 70, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/Si.rc b/reactos/dll/win32/mshtml/Si.rc index 92721df350d..6881addcd5b 100644 --- a/reactos/dll/win32/mshtml/Si.rc +++ b/reactos/dll/win32/mshtml/Si.rc @@ -35,10 +35,10 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Namestitev Wine Gecko" FONT 8, "MS Shell Dlg" { - LTEXT "Ta program poskuša prikazati HTML stran. Wine za prikaz spletnih strani " \ - "potrebuje Gecko (Mozillin HTML prikazovalnik). Kliknite Namesti, ÄŤe " \ - "Ĺľelite, da Wine samodejno naloĹľi in namesti Gecko (potrebna je povezava " \ - "z internetom).", ID_DWL_STATUS, 10, 10, 240, 40, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Napredek", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Namesti", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&PrekliÄŤi", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/Sv.rc b/reactos/dll/win32/mshtml/Sv.rc index 041ff8b5dc7..e9ba10e7975 100644 --- a/reactos/dll/win32/mshtml/Sv.rc +++ b/reactos/dll/win32/mshtml/Sv.rc @@ -28,17 +28,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "Installerar..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Wine Gecko Installationsprogram" FONT 8, "MS Shell Dlg" { - LTEXT "Detta program försöker visa en HTML-sida. Wine behöver ha Gecko (Mozillas HTML-" \ - "programvara) installerad för att visa sidan. Välj Installera om du vill att Wine " \ - "automatiskt ska hämta och installera Gecko.", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Förlopp", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "&Installera", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Avbryt", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "&Installera", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Avbryt", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } diff --git a/reactos/dll/win32/mshtml/Tr.rc b/reactos/dll/win32/mshtml/Tr.rc index 7e85fc6b4a1..01a7931e8d4 100644 --- a/reactos/dll/win32/mshtml/Tr.rc +++ b/reactos/dll/win32/mshtml/Tr.rc @@ -33,9 +33,10 @@ STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMEN CAPTION "Wine Gecko Kurucusu" FONT 8, "MS Shell Dlg" { - LTEXT "Bu uygulama bir HTML sayfasý göstermeye çalýţýyor. Wine, sayfanýn gösterilmesi " \ - "için Gecko (Mozilla HTML motoru)'nun kurulu olmasýný gerektirir. Gecko motorunun " \ - "otomatik olarak indirilmesi ve kurulmasý için Kur'u týklayýn.", ID_DWL_STATUS, 10, 10, 240, 40, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Ýlerleme", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 50, 240, 12 DEFPUSHBUTTON "&Kur", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP PUSHBUTTON "&Ýptal", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP diff --git a/reactos/dll/win32/mshtml/Zh.rc b/reactos/dll/win32/mshtml/Zh.rc index 2365120e5bb..c904dbc06b3 100644 --- a/reactos/dll/win32/mshtml/Zh.rc +++ b/reactos/dll/win32/mshtml/Zh.rc @@ -33,17 +33,18 @@ STRINGTABLE DISCARDABLE IDS_INSTALLING "正在安装..." } -ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 85 +ID_DWL_DIALOG DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 260, 95 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "Wine Gecko 安装" FONT 9, "MS Shell Dlg" { - LTEXT "这个čżç”¨ç¨‹ĺşŹč¦ćľç¤şä¸€ä¸ŞHTML 网页. Wine 需č¦čŁ…ä¸Š Gecko (Mozilla HTML " \ - "engine)才č˝ćľç¤şHTML网页. 如果你ćłč‡ŞĺŠ¨ä¸‹č˝˝ĺ’Śĺ®‰čŁ…Gecko," \ - "请按'安装'.", ID_DWL_STATUS, 10, 10, 240, 30, SS_LEFT + LTEXT "Wine could not find a Gecko package which is needed for applications embedding HTML " \ + "to work correctly. Wine can automatically download and install it for you.\n\n" \ + "Note: it's recommended to use distro packages instead. See http://wiki.winehq.org/Gecko for details.", + ID_DWL_STATUS, 10, 10, 240, 50, SS_LEFT CONTROL "Progress", ID_DWL_PROGRESS, PROGRESS_CLASSA, WS_BORDER|PBS_SMOOTH, 10, 40, 240, 12 - DEFPUSHBUTTON "安装(&I)", ID_DWL_INSTALL, 200, 60, 50, 15, WS_GROUP | WS_TABSTOP - PUSHBUTTON "取ć¶(&C)", IDCANCEL, 140, 60, 50, 15, WS_GROUP | WS_TABSTOP + DEFPUSHBUTTON "安装(&I)", ID_DWL_INSTALL, 200, 70, 50, 15, WS_GROUP | WS_TABSTOP + PUSHBUTTON "取ć¶(&C)", IDCANCEL, 140, 70, 50, 15, WS_GROUP | WS_TABSTOP } IDD_HYPERLINK DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 250, 65 diff --git a/reactos/dll/win32/mshtml/dispex.c b/reactos/dll/win32/mshtml/dispex.c index 4092374bf67..980b13b1654 100644 --- a/reactos/dll/win32/mshtml/dispex.c +++ b/reactos/dll/win32/mshtml/dispex.c @@ -73,6 +73,8 @@ struct dispex_dynamic_data_t { #define DISPID_DYNPROP_0 0x50000000 #define DISPID_DYNPROP_MAX 0x5fffffff +#define FDEX_VERSION_MASK 0xf0000000 + static ITypeLib *typelib; static ITypeInfo *typeinfos[LAST_tid]; static struct list dispex_data_list = LIST_INIT(dispex_data_list); @@ -123,8 +125,10 @@ static REFIID tid_ids[] = { &IID_IHTMLElement4, &IID_IHTMLElementCollection, &IID_IHTMLEventObj, + &IID_IHTMLFrameBase, &IID_IHTMLFrameBase2, &IID_IHTMLGenericElement, + &IID_IHTMLImageElementFactory, &IID_IHTMLImgElement, &IID_IHTMLInputElement, &IID_IHTMLLocation, @@ -220,7 +224,7 @@ static void add_func_info(dispex_data_t *data, DWORD *size, tid_t tid, const FUN data->funcs[data->func_cnt].id = desc->memid; data->funcs[data->func_cnt].tid = tid; - data->funcs[data->func_cnt].func_disp_idx = desc->invkind == INVOKE_FUNC ? data->func_disp_cnt++ : -1; + data->funcs[data->func_cnt].func_disp_idx = (desc->invkind & DISPATCH_METHOD) ? data->func_disp_cnt++ : -1; data->func_cnt++; } @@ -364,11 +368,13 @@ static inline dispex_dynamic_data_t *get_dynamic_data(DispatchEx *This, BOOL all : (This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t))); } -static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, BOOL alloc, dynamic_prop_t **ret) +static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags, dynamic_prop_t **ret) { - dispex_dynamic_data_t *data = get_dynamic_data(This, alloc); + const BOOL alloc = flags & fdexNameEnsure; + dispex_dynamic_data_t *data; unsigned i; + data = get_dynamic_data(This, alloc); if(!data) { if(alloc) return E_OUTOFMEMORY; @@ -378,12 +384,15 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, BOOL alloc, } for(i=0; i < data->prop_cnt; i++) { - if(!strcmpW(data->props[i].name, name)) { + if(flags & fdexNameCaseInsensitive ? !strcmpiW(data->props[i].name, name) : !strcmpW(data->props[i].name, name)) { *ret = data->props+i; return S_OK; } } + if(!alloc) + return DISP_E_UNKNOWNNAME; + TRACE("creating dynamic prop %s\n", debugstr_w(name)); if(!data->buf_size) { @@ -414,7 +423,7 @@ HRESULT dispex_get_dprop_ref(DispatchEx *This, const WCHAR *name, BOOL alloc, VA dynamic_prop_t *prop; HRESULT hres; - hres = get_dynamic_prop(This, name, alloc, &prop); + hres = get_dynamic_prop(This, name, alloc ? fdexNameEnsure : 0, &prop); if(FAILED(hres)) return hres; @@ -514,6 +523,9 @@ static HRESULT function_value(IUnknown *iface, LCID lcid, WORD flags, DISPPARAMS HRESULT hres; switch(flags) { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + if(!res) + return E_INVALIDARG; case DISPATCH_METHOD: hres = typeinfo_invoke(This->obj, This->info, flags, params, res, ei); break; @@ -570,6 +582,9 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags, HRESULT hres; switch(flags) { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + if(!res) + return E_INVALIDARG; case DISPATCH_METHOD: hres = typeinfo_invoke(This, func, flags, dp, res, ei); break; @@ -736,7 +751,7 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid); - if(grfdex & ~(fdexNameCaseSensitive|fdexNameEnsure|fdexNameImplicit)) + if(grfdex & ~(fdexNameCaseSensitive|fdexNameCaseInsensitive|fdexNameEnsure|fdexNameImplicit|FDEX_VERSION_MASK)) FIXME("Unsupported grfdex %x\n", grfdex); data = get_dispex_data(This); @@ -772,7 +787,7 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW return hres; } - hres = get_dynamic_prop(This, bstrName, grfdex&fdexNameEnsure, &dprop); + hres = get_dynamic_prop(This, bstrName, grfdex, &dprop); if(FAILED(hres)) return hres; @@ -794,8 +809,16 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc return This->data->vtbl->invoke(This->outer, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller); if(wFlags == DISPATCH_CONSTRUCT) { - FIXME("DISPATCH_CONSTRUCT not implemented\n"); - return E_NOTIMPL; + if(id == DISPID_VALUE) { + if(This->data->vtbl && This->data->vtbl->value) { + return This->data->vtbl->value(This->outer, lcid, wFlags, pdp, + pvarRes, pei, pspCaller); + } + FIXME("DISPATCH_CONSTRUCT flag but missing value function\n"); + return E_FAIL; + } + FIXME("DISPATCH_CONSTRUCT flag without DISPID_VALUE\n"); + return E_FAIL; } if(is_dynamic_dispid(id)) { @@ -808,7 +831,10 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc var = &This->dynamic_data->props[idx].var; switch(wFlags) { - case INVOKE_FUNC: { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + if(!pvarRes) + return E_INVALIDARG; + case DISPATCH_METHOD: { DISPID named_arg = DISPID_THIS; DISPPARAMS dp = {NULL, &named_arg, 0, 1}; IDispatchEx *dispex; @@ -847,9 +873,17 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc heap_free(dp.rgvarg); return hres; } - case INVOKE_PROPERTYGET: + case DISPATCH_PROPERTYGET: return VariantCopy(pvarRes, var); - case INVOKE_PROPERTYPUT: + case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF: + case DISPATCH_PROPERTYPUT: + if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT) + || pdp->cNamedArgs > 1) { + FIXME("invalid args\n"); + return E_INVALIDARG; + } + + TRACE("put %s\n", debugstr_variant(pdp->rgvarg)); VariantClear(var); return VariantCopy(var, pdp->rgvarg); default: diff --git a/reactos/dll/win32/mshtml/editor.c b/reactos/dll/win32/mshtml/editor.c index d1d9aadae3d..568e127220f 100644 --- a/reactos/dll/win32/mshtml/editor.c +++ b/reactos/dll/win32/mshtml/editor.c @@ -93,8 +93,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define DOM_VK_HOME VK_HOME #define DOM_VK_END VK_END -static const WCHAR wszFont[] = {'f','o','n','t',0}; -static const WCHAR wszSize[] = {'s','i','z','e',0}; +static const WCHAR fontW[] = {'f','o','n','t',0}; +static const WCHAR sizeW[] = {'s','i','z','e',0}; void set_dirty(HTMLDocument *This, VARIANT_BOOL dirty) { @@ -150,7 +150,7 @@ static DWORD query_ns_edit_status(HTMLDocument *This, const char *nscmd) nsICommandParams *nsparam; PRBool b = FALSE; - if(This->doc_obj->usermode != EDITMODE || This->doc_obj->readystate < READYSTATE_INTERACTIVE) + if(This->doc_obj->usermode != EDITMODE || This->window->readystate < READYSTATE_INTERACTIVE) return OLECMDF_SUPPORTED; if(This->doc_obj->nscontainer && nscmd) { @@ -185,7 +185,7 @@ static DWORD query_align_status(HTMLDocument *This, const char *align_str) nsICommandParams *nsparam; char *align = NULL; - if(This->doc_obj->usermode != EDITMODE || This->doc_obj->readystate < READYSTATE_INTERACTIVE) + if(This->doc_obj->usermode != EDITMODE || This->window->readystate < READYSTATE_INTERACTIVE) return OLECMDF_SUPPORTED; if(This->doc_obj->nscontainer) { @@ -292,13 +292,13 @@ static void get_font_size(HTMLDocument *This, WCHAR *ret) nsIDOMElement_GetTagName(elem, &tag_str); nsAString_GetData(&tag_str, &tag); - if(!strcmpiW(tag, wszFont)) { + if(!strcmpiW(tag, fontW)) { nsAString size_str, val_str; LPCWSTR val; TRACE("found font tag %p\n", elem); - nsAString_Init(&size_str, wszSize); + nsAString_Init(&size_str, sizeW); nsAString_Init(&val_str, NULL); nsIDOMElement_GetAttribute(elem, &size_str, &val_str); @@ -334,14 +334,13 @@ static void set_font_size(HTMLDocument *This, LPCWSTR size) { nsISelection *nsselection; PRBool collapsed; - nsIDOMElement *elem; + nsIDOMHTMLElement *elem; nsIDOMRange *range; PRInt32 range_cnt = 0; - nsAString font_str; nsAString size_str; nsAString val_str; - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return; } @@ -359,11 +358,11 @@ static void set_font_size(HTMLDocument *This, LPCWSTR size) } } - nsAString_Init(&font_str, wszFont); - nsAString_Init(&size_str, wszSize); + create_nselem(This->doc_node, fontW, &elem); + + nsAString_Init(&size_str, sizeW); nsAString_Init(&val_str, size); - nsIDOMDocument_CreateElement(This->nsdoc, &font_str, &elem); nsIDOMElement_SetAttribute(elem, &size_str, &val_str); nsISelection_GetRangeAt(nsselection, 0, &range); @@ -376,7 +375,7 @@ static void set_font_size(HTMLDocument *This, LPCWSTR size) nsISelection_Collapse(nsselection, (nsIDOMNode*)elem, 0); }else { /* Remove all size attributes from the range */ - remove_child_attr(elem, wszFont, &size_str); + remove_child_attr((nsIDOMElement*)elem, fontW, &size_str); nsISelection_SelectAllChildren(nsselection, (nsIDOMNode*)elem); } @@ -384,7 +383,6 @@ static void set_font_size(HTMLDocument *This, LPCWSTR size) nsIDOMRange_Release(range); nsIDOMElement_Release(elem); - nsAString_Finish(&font_str); nsAString_Finish(&size_str); nsAString_Finish(&val_str); @@ -715,7 +713,7 @@ static HRESULT query_justify(HTMLDocument *This, OLECMD *cmd) case IDM_JUSTIFYLEFT: TRACE("(%p) IDM_JUSTIFYLEFT\n", This); /* FIXME: We should set OLECMDF_LATCHED only if it's set explicitly. */ - if(This->doc_obj->usermode != EDITMODE || This->doc_obj->readystate < READYSTATE_INTERACTIVE) + if(This->doc_obj->usermode != EDITMODE || This->window->readystate < READYSTATE_INTERACTIVE) cmd->cmdf = OLECMDF_SUPPORTED; else cmd->cmdf = OLECMDF_SUPPORTED | OLECMDF_ENABLED; @@ -1127,17 +1125,17 @@ static INT_PTR CALLBACK hyperlink_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LP static HRESULT exec_hyperlink(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, VARIANT *out) { - nsAString a_str, href_str, ns_url; + nsAString href_str, ns_url; nsIHTMLEditor *html_editor; - nsIDOMElement *anchor_elem; + nsIDOMHTMLElement *anchor_elem; PRBool insert_link_at_caret; nsISelection *nsselection; BSTR url = NULL; INT ret; HRESULT hres = E_FAIL; - static const WCHAR wszA[] = {'a',0}; - static const WCHAR wszHref[] = {'h','r','e','f',0}; + static const WCHAR aW[] = {'a',0}; + static const WCHAR hrefW[] = {'h','r','e','f',0}; TRACE("%p, 0x%x, %p, %p\n", This, cmdexecopt, in, out); @@ -1157,7 +1155,7 @@ static HRESULT exec_hyperlink(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, return OLECMDERR_E_CANCELED; } - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } @@ -1166,16 +1164,13 @@ static HRESULT exec_hyperlink(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, if (!nsselection) return E_FAIL; - nsAString_Init(&a_str, wszA); - nsAString_Init(&href_str, wszHref); - nsAString_Init(&ns_url, url); - /* create an element for the link */ - nsIDOMDocument_CreateElement(This->nsdoc, &a_str, &anchor_elem); - nsIDOMElement_SetAttribute(anchor_elem, &href_str, &ns_url); + create_nselem(This->doc_node, aW, &anchor_elem); + nsAString_Init(&href_str, hrefW); + nsAString_Init(&ns_url, url); + nsIDOMElement_SetAttribute(anchor_elem, &href_str, &ns_url); nsAString_Finish(&href_str); - nsAString_Finish(&a_str); nsISelection_GetIsCollapsed(nsselection, &insert_link_at_caret); @@ -1183,7 +1178,7 @@ static HRESULT exec_hyperlink(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, if (insert_link_at_caret) { nsIDOMNode *text_node, *unused_node; - nsIDOMDocument_CreateTextNode(This->nsdoc, &ns_url, (nsIDOMText **)&text_node); + nsIDOMDocument_CreateTextNode(This->doc_node->nsdoc, &ns_url, (nsIDOMText **)&text_node); /* wrap the tags around the text element */ nsIDOMElement_AppendChild(anchor_elem, text_node, &unused_node); @@ -1199,10 +1194,10 @@ static HRESULT exec_hyperlink(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, if (insert_link_at_caret) { /* add them to the document at the caret position */ - nsres = nsIHTMLEditor_InsertElementAtSelection(html_editor, anchor_elem, FALSE); + nsres = nsIHTMLEditor_InsertElementAtSelection(html_editor, (nsIDOMElement*)anchor_elem, FALSE); nsISelection_SelectAllChildren(nsselection, (nsIDOMNode*)anchor_elem); }else /* add them around the selection using the magic provided to us by nsIHTMLEditor */ - nsres = nsIHTMLEditor_InsertLinkAroundSelection(html_editor, anchor_elem); + nsres = nsIHTMLEditor_InsertLinkAroundSelection(html_editor, (nsIDOMElement*)anchor_elem); nsIHTMLEditor_Release(html_editor); hres = NS_SUCCEEDED(nsres) ? S_OK : E_FAIL; diff --git a/reactos/dll/win32/mshtml/htmlanchor.c b/reactos/dll/win32/mshtml/htmlanchor.c index 09c7eda8d0b..04960d90337 100644 --- a/reactos/dll/win32/mshtml/htmlanchor.c +++ b/reactos/dll/win32/mshtml/htmlanchor.c @@ -518,7 +518,7 @@ static dispex_static_data_t HTMLAnchorElement_dispex = { HTMLAnchorElement_iface_tids }; -HTMLElement *HTMLAnchorElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLAnchorElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLAnchorElement *ret = heap_alloc_zero(sizeof(HTMLAnchorElement)); nsresult nsres; @@ -526,7 +526,7 @@ HTMLElement *HTMLAnchorElement_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLAnchorElementVtbl = &HTMLAnchorElementVtbl; ret->element.node.vtbl = &HTMLAnchorElementImplVtbl; - HTMLElement_Init(&ret->element, &HTMLAnchorElement_dispex); + HTMLElement_Init(&ret->element, doc, nselem, &HTMLAnchorElement_dispex); nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLAnchorElement, (void**)&ret->nsanchor); if(NS_FAILED(nsres)) diff --git a/reactos/dll/win32/mshtml/htmlbody.c b/reactos/dll/win32/mshtml/htmlbody.c index 5e0a68665c3..4da3373eba1 100644 --- a/reactos/dll/win32/mshtml/htmlbody.c +++ b/reactos/dll/win32/mshtml/htmlbody.c @@ -606,12 +606,12 @@ static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, I TRACE("(%p)->(%p)\n", This, range); - if(!This->textcont.element.node.doc->basedoc.nsdoc) { + if(!This->textcont.element.node.doc->nsdoc) { WARN("No nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMDocument_QueryInterface(This->textcont.element.node.doc->basedoc.nsdoc, &IID_nsIDOMDocumentRange, + nsres = nsIDOMDocument_QueryInterface(This->textcont.element.node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void**)&nsdocrange); if(NS_FAILED(nsres)) { ERR("Could not get nsIDOMDocumentRabge iface: %08x\n", nsres); @@ -759,7 +759,7 @@ static dispex_static_data_t HTMLBodyElement_dispex = { HTMLBodyElement_iface_tids }; -HTMLElement *HTMLBodyElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLBodyElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLBodyElement *ret = heap_alloc_zero(sizeof(HTMLBodyElement)); nsresult nsres; @@ -769,7 +769,7 @@ HTMLElement *HTMLBodyElement_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLBodyElementVtbl = &HTMLBodyElementVtbl; ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl; - HTMLTextContainer_Init(&ret->textcont, &HTMLBodyElement_dispex); + HTMLTextContainer_Init(&ret->textcont, doc, nselem, &HTMLBodyElement_dispex); ConnectionPoint_Init(&ret->cp_propnotif, &ret->textcont.element.cp_container, &IID_IPropertyNotifySink); diff --git a/reactos/dll/win32/mshtml/htmlcomment.c b/reactos/dll/win32/mshtml/htmlcomment.c index a191c8e3465..e38432c4a67 100644 --- a/reactos/dll/win32/mshtml/htmlcomment.c +++ b/reactos/dll/win32/mshtml/htmlcomment.c @@ -193,8 +193,10 @@ HTMLElement *HTMLCommentElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode ret->element.node.vtbl = &HTMLCommentElementImplVtbl; ret->lpIHTMLCommentElementVtbl = &HTMLCommentElementVtbl; - HTMLElement_Init(&ret->element, &HTMLCommentElement_dispex); - HTMLDOMNode_Init(doc, &ret->element.node, nsnode); + HTMLElement_Init(&ret->element, doc, NULL, &HTMLCommentElement_dispex); + + nsIDOMNode_AddRef(nsnode); + ret->element.node.nsnode = nsnode; return &ret->element; } diff --git a/reactos/dll/win32/mshtml/htmlcurstyle.c b/reactos/dll/win32/mshtml/htmlcurstyle.c index dc23e8ca857..4f56e87e428 100644 --- a/reactos/dll/win32/mshtml/htmlcurstyle.c +++ b/reactos/dll/win32/mshtml/htmlcurstyle.c @@ -899,12 +899,12 @@ HRESULT HTMLCurrentStyle_Create(HTMLElement *elem, IHTMLCurrentStyle **p) HTMLCurrentStyle *ret; nsresult nsres; - if(!elem->node.doc->basedoc.nsdoc) { + if(!elem->node.doc->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_QueryInterface(elem->node.doc->basedoc.nsdoc, &IID_nsIDOMDocumentView, (void**)&nsdocview); + nsres = nsIDOMHTMLDocument_QueryInterface(elem->node.doc->nsdoc, &IID_nsIDOMDocumentView, (void**)&nsdocview); if(NS_FAILED(nsres)) { ERR("Could not get nsIDOMDocumentView: %08x\n", nsres); return E_FAIL; diff --git a/reactos/dll/win32/mshtml/htmldoc.c b/reactos/dll/win32/mshtml/htmldoc.c index bb5d968994e..836f1aee4b3 100644 --- a/reactos/dll/win32/mshtml/htmldoc.c +++ b/reactos/dll/win32/mshtml/htmldoc.c @@ -113,12 +113,12 @@ static HRESULT WINAPI HTMLDocument_get_all(IHTMLDocument2 *iface, IHTMLElementCo TRACE("(%p)->(%p)\n", This, p); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetDocumentElement(This->nsdoc, &nselem); + nsres = nsIDOMHTMLDocument_GetDocumentElement(This->doc_node->nsdoc, &nselem); if(NS_FAILED(nsres)) { ERR("GetDocumentElement failed: %08x\n", nsres); return E_FAIL; @@ -143,12 +143,12 @@ static HRESULT WINAPI HTMLDocument_get_body(IHTMLDocument2 *iface, IHTMLElement TRACE("(%p)->(%p)\n", This, p); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetBody(This->nsdoc, &nsbody); + nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody); if(NS_FAILED(nsres)) { TRACE("Could not get body: %08x\n", nsres); return E_UNEXPECTED; @@ -187,12 +187,12 @@ static HRESULT WINAPI HTMLDocument_get_images(IHTMLDocument2 *iface, IHTMLElemen *p = NULL; - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetImages(This->nsdoc, &nscoll); + nsres = nsIDOMHTMLDocument_GetImages(This->doc_node->nsdoc, &nscoll); if(NS_FAILED(nsres)) { ERR("GetImages failed: %08x\n", nsres); return E_FAIL; @@ -219,12 +219,12 @@ static HRESULT WINAPI HTMLDocument_get_applets(IHTMLDocument2 *iface, IHTMLEleme *p = NULL; - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetApplets(This->nsdoc, &nscoll); + nsres = nsIDOMHTMLDocument_GetApplets(This->doc_node->nsdoc, &nscoll); if(NS_FAILED(nsres)) { ERR("GetApplets failed: %08x\n", nsres); return E_FAIL; @@ -251,12 +251,12 @@ static HRESULT WINAPI HTMLDocument_get_links(IHTMLDocument2 *iface, IHTMLElement *p = NULL; - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetLinks(This->nsdoc, &nscoll); + nsres = nsIDOMHTMLDocument_GetLinks(This->doc_node->nsdoc, &nscoll); if(NS_FAILED(nsres)) { ERR("GetLinks failed: %08x\n", nsres); return E_FAIL; @@ -283,12 +283,12 @@ static HRESULT WINAPI HTMLDocument_get_forms(IHTMLDocument2 *iface, IHTMLElement *p = NULL; - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetForms(This->nsdoc, &nscoll); + nsres = nsIDOMHTMLDocument_GetForms(This->doc_node->nsdoc, &nscoll); if(NS_FAILED(nsres)) { ERR("GetForms failed: %08x\n", nsres); return E_FAIL; @@ -315,12 +315,12 @@ static HRESULT WINAPI HTMLDocument_get_anchors(IHTMLDocument2 *iface, IHTMLEleme *p = NULL; - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetAnchors(This->nsdoc, &nscoll); + nsres = nsIDOMHTMLDocument_GetAnchors(This->doc_node->nsdoc, &nscoll); if(NS_FAILED(nsres)) { ERR("GetAnchors failed: %08x\n", nsres); return E_FAIL; @@ -342,13 +342,13 @@ static HRESULT WINAPI HTMLDocument_put_title(IHTMLDocument2 *iface, BSTR v) TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_Init(&nsstr, v); - nsres = nsIDOMHTMLDocument_SetTitle(This->nsdoc, &nsstr); + nsres = nsIDOMHTMLDocument_SetTitle(This->doc_node->nsdoc, &nsstr); nsAString_Finish(&nsstr); if(NS_FAILED(nsres)) ERR("SetTitle failed: %08x\n", nsres); @@ -365,14 +365,14 @@ static HRESULT WINAPI HTMLDocument_get_title(IHTMLDocument2 *iface, BSTR *p) TRACE("(%p)->(%p)\n", This, p); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_Init(&nsstr, NULL); - nsres = nsIDOMHTMLDocument_GetTitle(This->nsdoc, &nsstr); + nsres = nsIDOMHTMLDocument_GetTitle(This->doc_node->nsdoc, &nsstr); if (NS_SUCCEEDED(nsres)) { nsAString_GetData(&nsstr, &ret); *p = SysAllocString(ret); @@ -455,7 +455,7 @@ static HRESULT WINAPI HTMLDocument_get_readyState(IHTMLDocument2 *iface, BSTR *p if(!p) return E_POINTER; - *p = SysAllocString(readystate_str[This->doc_obj->readystate]); + *p = SysAllocString(readystate_str[This->window->readystate]); return S_OK; } @@ -589,7 +589,7 @@ static HRESULT WINAPI HTMLDocument_get_URL(IHTMLDocument2 *iface, BSTR *p) TRACE("(%p)->(%p)\n", iface, p); - *p = SysAllocString(This->doc_obj->url ? This->doc_obj->url : about_blank_url); + *p = SysAllocString(This->window->url ? This->window->url : about_blank_url); return *p ? S_OK : E_OUTOFMEMORY; } @@ -727,7 +727,7 @@ static HRESULT document_write(HTMLDocument *This, SAFEARRAY *psarray, BOOL ln) nsresult nsres; HRESULT hres; - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } @@ -750,9 +750,9 @@ static HRESULT document_write(HTMLDocument *This, SAFEARRAY *psarray, BOOL ln) if(V_VT(var+i) == VT_BSTR) { nsAString_SetData(&nsstr, V_BSTR(var+i)); if(!ln || i != argc-1) - nsres = nsIDOMHTMLDocument_Write(This->nsdoc, &nsstr); + nsres = nsIDOMHTMLDocument_Write(This->doc_node->nsdoc, &nsstr); else - nsres = nsIDOMHTMLDocument_Writeln(This->nsdoc, &nsstr); + nsres = nsIDOMHTMLDocument_Writeln(This->doc_node->nsdoc, &nsstr); if(NS_FAILED(nsres)) ERR("Write failed: %08x\n", nsres); }else { @@ -795,7 +795,7 @@ static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT TRACE("(%p)->(%s %s %s %s %p)\n", This, debugstr_w(url), debugstr_variant(&name), debugstr_variant(&features), debugstr_variant(&replace), pomWindowResult); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { ERR("!nsdoc\n"); return E_NOTIMPL; } @@ -804,7 +804,7 @@ static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT || V_VT(&features) != VT_ERROR || V_VT(&replace) != VT_ERROR) FIXME("unsupported args\n"); - nsres = nsIDOMHTMLDocument_Open(This->nsdoc); + nsres = nsIDOMHTMLDocument_Open(This->doc_node->nsdoc); if(NS_FAILED(nsres)) { ERR("Open failed: %08x\n", nsres); return E_FAIL; @@ -822,12 +822,12 @@ static HRESULT WINAPI HTMLDocument_close(IHTMLDocument2 *iface) TRACE("(%p)\n", This); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { ERR("!nsdoc\n"); return E_NOTIMPL; } - nsres = nsIDOMHTMLDocument_Close(This->nsdoc); + nsres = nsIDOMHTMLDocument_Close(This->doc_node->nsdoc); if(NS_FAILED(nsres)) { ERR("Close failed: %08x\n", nsres); return E_FAIL; @@ -911,28 +911,18 @@ static HRESULT WINAPI HTMLDocument_createElement(IHTMLDocument2 *iface, BSTR eTa IHTMLElement **newElem) { HTMLDocument *This = HTMLDOC_THIS(iface); - nsIDOMElement *nselem; + nsIDOMHTMLElement *nselem; HTMLElement *elem; - nsAString tag_str; - nsresult nsres; + HRESULT hres; TRACE("(%p)->(%s %p)\n", This, debugstr_w(eTag), newElem); - if(!This->nsdoc) { - WARN("NULL nsdoc\n"); - return E_UNEXPECTED; - } - - nsAString_Init(&tag_str, eTag); - nsres = nsIDOMDocument_CreateElement(This->nsdoc, &tag_str, &nselem); - nsAString_Finish(&tag_str); - if(NS_FAILED(nsres)) { - ERR("CreateElement failed: %08x\n", nsres); - return E_FAIL; - } + hres = create_nselem(This->doc_node, eTag, &nselem); + if(FAILED(hres)) + return hres; elem = HTMLElement_Create(This->doc_node, (nsIDOMNode*)nselem, TRUE); - nsIDOMElement_Release(nselem); + nsIDOMHTMLElement_Release(nselem); *newElem = HTMLELEM(elem); IHTMLElement_AddRef(HTMLELEM(elem)); @@ -1232,12 +1222,12 @@ static HRESULT WINAPI HTMLDocument_get_styleSheets(IHTMLDocument2 *iface, *p = NULL; - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsIDOMHTMLDocument_QueryInterface(This->nsdoc, &IID_nsIDOMDocumentStyle, (void**)&nsdocstyle); + nsIDOMHTMLDocument_QueryInterface(This->doc_node->nsdoc, &IID_nsIDOMDocumentStyle, (void**)&nsdocstyle); nsres = nsIDOMDocumentStyle_GetStyleSheets(nsdocstyle, &nsstylelist); nsIDOMDocumentStyle_Release(nsdocstyle); if(NS_FAILED(nsres)) { @@ -1513,7 +1503,7 @@ static HRESULT WINAPI DocDispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMemb return E_INVALIDARG; V_VT(pVarResult) = VT_I4; - V_I4(pVarResult) = This->doc_obj->readystate; + V_I4(pVarResult) = This->window->readystate; return S_OK; } @@ -1626,6 +1616,9 @@ static BOOL htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv) }else if(IsEqualGUID(&IID_IHTMLDocument5, riid)) { TRACE("(%p)->(IID_IHTMLDocument5, %p)\n", This, ppv); *ppv = HTMLDOC5(This); + }else if(IsEqualGUID(&IID_IHTMLDocument6, riid)) { + TRACE("(%p)->(IID_IHTMLDocument6, %p)\n", This, ppv); + *ppv = HTMLDOC6(This); }else if(IsEqualGUID(&IID_IPersist, riid)) { TRACE("(%p)->(IID_IPersist, %p)\n", This, ppv); *ppv = PERSIST(This); @@ -1721,6 +1714,7 @@ static void init_doc(HTMLDocument *doc, IUnknown *unk_impl, IDispatchEx *dispex) doc->unk_impl = unk_impl; doc->dispex = dispex; + doc->task_magic = get_task_target_magic(); HTMLDocument_HTMLDocument3_Init(doc); HTMLDocument_HTMLDocument5_Init(doc); @@ -1740,12 +1734,9 @@ static void init_doc(HTMLDocument *doc, IUnknown *unk_impl, IDispatchEx *dispex) static void destroy_htmldoc(HTMLDocument *This) { - remove_doc_tasks(This); + remove_target_tasks(This->task_magic); ConnectionPointContainer_Destroy(&This->cp_container); - - if(This->nsdoc) - nsIDOMHTMLDocument_Release(This->nsdoc); } #define HTMLDOCNODE_NODE_THIS(iface) DEFINE_THIS2(HTMLDocumentNode, node, iface) @@ -1772,12 +1763,21 @@ static void HTMLDocumentNode_destructor(HTMLDOMNode *iface) { HTMLDocumentNode *This = HTMLDOCNODE_NODE_THIS(iface); + if(This->nsevent_listener) + release_nsevents(This); if(This->secmgr) IInternetSecurityManager_Release(This->secmgr); detach_selection(This); detach_ranges(This); release_nodes(This); + + if(This->nsdoc) { + release_mutation(This); + nsIDOMHTMLDocument_Release(This->nsdoc); + } + + heap_free(This->event_vector); destroy_htmldoc(&This->basedoc); } @@ -1822,11 +1822,14 @@ HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_ob HTMLDocumentNode_SecMgr_Init(doc); doc->ref = 1; - nsIDOMHTMLDocument_AddRef(nsdoc); - doc->basedoc.nsdoc = nsdoc; - doc->basedoc.window = window; + nsIDOMHTMLDocument_AddRef(nsdoc); + doc->nsdoc = nsdoc; + init_mutation(doc); + init_nsevents(doc); + + list_init(&doc->bindings); list_init(&doc->selection_list); list_init(&doc->range_list); @@ -1889,8 +1892,6 @@ static ULONG WINAPI CustomDoc_Release(ICustomDoc *iface) TRACE("(%p) ref = %u\n", This, ref); if(!ref) { - set_document_bscallback(&This->basedoc, NULL); - set_current_mon(&This->basedoc, NULL); if(This->basedoc.doc_node) { This->basedoc.doc_node->basedoc.doc_obj = NULL; IHTMLDocument2_Release(HTMLDOC(&This->basedoc.doc_node->basedoc)); @@ -1918,8 +1919,6 @@ static ULONG WINAPI CustomDoc_Release(ICustomDoc *iface) destroy_htmldoc(&This->basedoc); release_dispex(&This->dispex); - if(This->basedoc.nsdoc) - remove_mutation_observer(This->nscontainer, This->basedoc.nsdoc); if(This->nscontainer) NSContainer_Release(This->nscontainer); heap_free(This); @@ -1962,6 +1961,7 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject) { HTMLDocumentObj *doc; nsIDOMWindow *nswindow = NULL; + nsresult nsres; HRESULT hres; TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppvObject); @@ -1977,25 +1977,26 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject) doc->ref = 1; doc->basedoc.doc_obj = doc; + doc->usermode = UNKNOWN_USERMODE; + + doc->nscontainer = NSContainer_Create(doc, NULL); + if(!doc->nscontainer) { + ERR("Failed to init Gecko, returning CLASS_E_CLASSNOTAVAILABLE\n"); + htmldoc_release(&doc->basedoc); + return CLASS_E_CLASSNOTAVAILABLE; + } + hres = htmldoc_query_interface(&doc->basedoc, riid, ppvObject); htmldoc_release(&doc->basedoc); if(FAILED(hres)) return hres; - doc->nscontainer = NSContainer_Create(doc, NULL); - list_init(&doc->bindings); - doc->usermode = UNKNOWN_USERMODE; - doc->readystate = READYSTATE_UNINITIALIZED; - if(doc->nscontainer) { - nsresult nsres; + nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &nswindow); + if(NS_FAILED(nsres)) + ERR("GetContentDOMWindow failed: %08x\n", nsres); - nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &nswindow); - if(NS_FAILED(nsres)) - ERR("GetContentDOMWindow failed: %08x\n", nsres); - } - - hres = HTMLWindow_Create(doc, nswindow, &doc->basedoc.window); + hres = HTMLWindow_Create(doc, nswindow, NULL /* FIXME */, &doc->basedoc.window); if(nswindow) nsIDOMWindow_Release(nswindow); if(FAILED(hres)) { @@ -2003,7 +2004,11 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject) return hres; } - update_nsdocument(doc); + if(!doc->basedoc.doc_node && doc->basedoc.window->doc) { + doc->basedoc.doc_node = doc->basedoc.window->doc; + htmldoc_addref(&doc->basedoc.doc_node->basedoc); + } + get_thread_hwnd(); return S_OK; diff --git a/reactos/dll/win32/mshtml/htmldoc3.c b/reactos/dll/win32/mshtml/htmldoc3.c index f4f923f3d27..a00fa95b21b 100644 --- a/reactos/dll/win32/mshtml/htmldoc3.c +++ b/reactos/dll/win32/mshtml/htmldoc3.c @@ -111,13 +111,13 @@ static HRESULT WINAPI HTMLDocument3_createTextNode(IHTMLDocument3 *iface, BSTR t TRACE("(%p)->(%s %p)\n", This, debugstr_w(text), newTextNode); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_Init(&text_str, text); - nsres = nsIDOMHTMLDocument_CreateTextNode(This->nsdoc, &text_str, &nstext); + nsres = nsIDOMHTMLDocument_CreateTextNode(This->doc_node->nsdoc, &text_str, &nstext); nsAString_Finish(&text_str); if(NS_FAILED(nsres)) { ERR("CreateTextNode failed: %08x\n", nsres); @@ -141,12 +141,17 @@ static HRESULT WINAPI HTMLDocument3_get_documentElement(IHTMLDocument3 *iface, I TRACE("(%p)->(%p)\n", This, p); - if(!This->nsdoc) { + if(This->window->readystate == READYSTATE_UNINITIALIZED) { + *p = NULL; + return S_OK; + } + + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetDocumentElement(This->nsdoc, &nselem); + nsres = nsIDOMHTMLDocument_GetDocumentElement(This->doc_node->nsdoc, &nselem); if(NS_FAILED(nsres)) { ERR("GetDocumentElement failed: %08x\n", nsres); return E_FAIL; @@ -431,13 +436,13 @@ static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pel); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_Init(&id_str, v); - nsres = nsIDOMHTMLDocument_GetElementById(This->nsdoc, &id_str, &nselem); + nsres = nsIDOMHTMLDocument_GetElementById(This->doc_node->nsdoc, &id_str, &nselem); nsAString_Finish(&id_str); if(FAILED(nsres)) { ERR("GetElementById failed: %08x\n", nsres); @@ -468,14 +473,14 @@ static HRESULT WINAPI HTMLDocument3_getElementsByTagName(IHTMLDocument3 *iface, TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pelColl); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_Init(&id_str, v); nsAString_Init(&ns_str, str); - nsres = nsIDOMHTMLDocument_GetElementsByTagNameNS(This->nsdoc, &ns_str, &id_str, &nslist); + nsres = nsIDOMHTMLDocument_GetElementsByTagNameNS(This->doc_node->nsdoc, &ns_str, &id_str, &nslist); nsAString_Finish(&id_str); nsAString_Finish(&ns_str); if(FAILED(nsres)) { @@ -602,7 +607,7 @@ static HRESULT WINAPI HTMLDocument4_focus(IHTMLDocument4 *iface) TRACE("(%p)->()\n", This); - nsres = nsIDOMHTMLDocument_GetBody(This->nsdoc, &nsbody); + nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody); if(NS_FAILED(nsres) || !nsbody) { ERR("GetBody failed: %08x\n", nsres); return E_FAIL; diff --git a/reactos/dll/win32/mshtml/htmldoc5.c b/reactos/dll/win32/mshtml/htmldoc5.c index 59b223b55ef..e3b14231e69 100644 --- a/reactos/dll/win32/mshtml/htmldoc5.c +++ b/reactos/dll/win32/mshtml/htmldoc5.c @@ -131,13 +131,13 @@ static HRESULT WINAPI HTMLDocument5_createComment(IHTMLDocument5 *iface, BSTR bs TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrdata), ppRetNode); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_Init(&str, bstrdata); - nsres = nsIDOMHTMLDocument_CreateComment(This->nsdoc, &str, &nscomment); + nsres = nsIDOMHTMLDocument_CreateComment(This->doc_node->nsdoc, &str, &nscomment); nsAString_Finish(&str); if(NS_FAILED(nsres)) { ERR("CreateTextNode failed: %08x\n", nsres); @@ -246,12 +246,12 @@ static HRESULT WINAPI HTMLDocument5_get_compatMode(IHTMLDocument5 *iface, BSTR * TRACE("(%p)->(%p)\n", This, p); - if(!This->nsdoc) { + if(!This->doc_node->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_QueryInterface(This->nsdoc, &IID_nsIDOMNSHTMLDocument, (void**)&nshtmldoc); + nsres = nsIDOMHTMLDocument_QueryInterface(This->doc_node->nsdoc, &IID_nsIDOMNSHTMLDocument, (void**)&nshtmldoc); if(NS_FAILED(nsres)) { ERR("Could not get nsIDOMNSHTMLDocument: %08x\n", nsres); return S_OK; @@ -299,7 +299,141 @@ static const IHTMLDocument5Vtbl HTMLDocument5Vtbl = { HTMLDocument5_get_compatMode }; +#define HTMLDOC6_THIS(iface) DEFINE_THIS(HTMLDocument, HTMLDocument6, iface) + +static HRESULT WINAPI HTMLDocument6_QueryInterface(IHTMLDocument6 *iface, + REFIID riid, void **ppv) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv); +} + +static ULONG WINAPI HTMLDocument6_AddRef(IHTMLDocument6 *iface) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + return IHTMLDocument2_AddRef(HTMLDOC(This)); +} + +static ULONG WINAPI HTMLDocument6_Release(IHTMLDocument6 *iface) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + return IHTMLDocument2_Release(HTMLDOC(This)); +} + +static HRESULT WINAPI HTMLDocument6_GetTypeInfoCount(IHTMLDocument6 *iface, UINT *pctinfo) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo); +} + +static HRESULT WINAPI HTMLDocument6_GetTypeInfo(IHTMLDocument6 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLDocument6_GetIDsOfNames(IHTMLDocument6 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId); +} + +static HRESULT WINAPI HTMLDocument6_Invoke(IHTMLDocument6 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams, + pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLDocument6_get_compatible(IHTMLDocument6 *iface, + IHTMLDocumentCompatibleInfoCollection **p) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_get_documentMode(IHTMLDocument6 *iface, + VARIANT *p) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_get_onstorage(IHTMLDocument6 *iface, + VARIANT *p) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_put_onstorage(IHTMLDocument6 *iface, + VARIANT p) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + FIXME("(%p)->(v)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_get_onstoragecommit(IHTMLDocument6 *iface, + VARIANT *p) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_put_onstoragecommit(IHTMLDocument6 *iface, + VARIANT p) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + FIXME("(%p)->(v)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_getElementById(IHTMLDocument6 *iface, + BSTR bstrId, IHTMLElement2 **p) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrId), p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_updateSettings(IHTMLDocument6 *iface) +{ + HTMLDocument *This = HTMLDOC6_THIS(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +#undef HTMLDOC6_THIS + +static const IHTMLDocument6Vtbl HTMLDocument6Vtbl = { + HTMLDocument6_QueryInterface, + HTMLDocument6_AddRef, + HTMLDocument6_Release, + HTMLDocument6_GetTypeInfoCount, + HTMLDocument6_GetTypeInfo, + HTMLDocument6_GetIDsOfNames, + HTMLDocument6_Invoke, + HTMLDocument6_get_compatible, + HTMLDocument6_get_documentMode, + HTMLDocument6_put_onstorage, + HTMLDocument6_get_onstorage, + HTMLDocument6_put_onstoragecommit, + HTMLDocument6_get_onstoragecommit, + HTMLDocument6_getElementById, + HTMLDocument6_updateSettings +}; + void HTMLDocument_HTMLDocument5_Init(HTMLDocument *This) { This->lpHTMLDocument5Vtbl = &HTMLDocument5Vtbl; + This->lpHTMLDocument6Vtbl = &HTMLDocument6Vtbl; } diff --git a/reactos/dll/win32/mshtml/htmlelem.c b/reactos/dll/win32/mshtml/htmlelem.c index 28421bba07f..b794b73288a 100644 --- a/reactos/dll/win32/mshtml/htmlelem.c +++ b/reactos/dll/win32/mshtml/htmlelem.c @@ -38,6 +38,35 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define HTMLELEM_THIS(iface) DEFINE_THIS(HTMLElement, HTMLElement, iface) +HRESULT create_nselem(HTMLDocumentNode *doc, const WCHAR *tag, nsIDOMHTMLElement **ret) +{ + nsIDOMElement *nselem; + nsAString tag_str; + nsresult nsres; + + if(!doc->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + nsAString_Init(&tag_str, tag); + nsres = nsIDOMDocument_CreateElement(doc->nsdoc, &tag_str, &nselem); + nsAString_Finish(&tag_str); + if(NS_FAILED(nsres)) { + ERR("CreateElement failed: %08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLElement, (void**)ret); + nsIDOMElement_Release(nselem); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMHTMLElement iface: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; +} + #define HTMLELEM_NODE_THIS(iface) DEFINE_THIS2(HTMLElement, node, iface) static HRESULT WINAPI HTMLElement_QueryInterface(IHTMLElement *iface, @@ -850,7 +879,7 @@ static HRESULT WINAPI HTMLElement_put_innerText(IHTMLElement *iface, BSTR v) } nsAString_Init(&text_str, v); - nsres = nsIDOMHTMLDocument_CreateTextNode(This->node.doc->basedoc.nsdoc, &text_str, &text_node); + nsres = nsIDOMHTMLDocument_CreateTextNode(This->node.doc->nsdoc, &text_str, &text_node); nsAString_Finish(&text_str); if(NS_FAILED(nsres)) { ERR("CreateTextNode failed: %08x\n", nsres); @@ -1006,12 +1035,12 @@ static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR w TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html)); - if(!This->node.doc->basedoc.nsdoc) { + if(!This->node.doc->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } - nsres = nsIDOMDocument_QueryInterface(This->node.doc->basedoc.nsdoc, &IID_nsIDOMDocumentRange, (void **)&nsdocrange); + nsres = nsIDOMDocument_QueryInterface(This->node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void **)&nsdocrange); if(NS_FAILED(nsres)) { ERR("getting nsIDOMDocumentRange failed: %08x\n", nsres); @@ -1064,14 +1093,14 @@ static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR w TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text)); - if(!This->node.doc->basedoc.nsdoc) { + if(!This->node.doc->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } nsAString_Init(&ns_text, text); - nsres = nsIDOMDocument_CreateTextNode(This->node.doc->basedoc.nsdoc, &ns_text, (nsIDOMText **)&nsnode); + nsres = nsIDOMDocument_CreateTextNode(This->node.doc->nsdoc, &ns_text, (nsIDOMText **)&nsnode); nsAString_Finish(&ns_text); if(NS_FAILED(nsres) || !nsnode) @@ -1103,8 +1132,10 @@ static HRESULT WINAPI HTMLElement_get_isTextEdit(IHTMLElement *iface, VARIANT_BO static HRESULT WINAPI HTMLElement_click(IHTMLElement *iface) { HTMLElement *This = HTMLELEM_THIS(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + + TRACE("(%p)\n", This); + + return call_event(&This->node, EVENTID_CLICK); } static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface, @@ -1458,16 +1489,22 @@ static dispex_static_data_t HTMLElement_dispex = { HTMLElement_iface_tids }; -void HTMLElement_Init(HTMLElement *This, dispex_static_data_t *dispex_data) +void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, dispex_static_data_t *dispex_data) { This->lpHTMLElementVtbl = &HTMLElementVtbl; - ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)HTMLELEM(This)); - HTMLElement2_Init(This); HTMLElement3_Init(This); init_dispex(&This->node.dispex, (IUnknown*)HTMLELEM(This), dispex_data ? dispex_data : &HTMLElement_dispex); + + if(nselem) + nsIDOMHTMLElement_AddRef(nselem); + This->nselem = nselem; + + HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem); + + ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)HTMLELEM(This)); } HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_generic) @@ -1500,42 +1537,40 @@ HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL nsAString_GetData(&class_name_str, &class_name); if(!strcmpW(class_name, wszA)) - ret = HTMLAnchorElement_Create(nselem); + ret = HTMLAnchorElement_Create(doc, nselem); else if(!strcmpW(class_name, wszBODY)) - ret = HTMLBodyElement_Create(nselem); + ret = HTMLBodyElement_Create(doc, nselem); else if(!strcmpW(class_name, wszIFRAME)) - ret = HTMLIFrame_Create(nselem); + ret = HTMLIFrame_Create(doc, nselem, NULL); else if(!strcmpW(class_name, wszIMG)) - ret = HTMLImgElement_Create(nselem); + ret = HTMLImgElement_Create(doc, nselem); else if(!strcmpW(class_name, wszINPUT)) - ret = HTMLInputElement_Create(nselem); + ret = HTMLInputElement_Create(doc, nselem); else if(!strcmpW(class_name, wszOPTION)) - ret = HTMLOptionElement_Create(nselem); + ret = HTMLOptionElement_Create(doc, nselem); else if(!strcmpW(class_name, wszSCRIPT)) - ret = HTMLScriptElement_Create(nselem); + ret = HTMLScriptElement_Create(doc, nselem); else if(!strcmpW(class_name, wszSELECT)) - ret = HTMLSelectElement_Create(nselem); + ret = HTMLSelectElement_Create(doc, nselem); else if(!strcmpW(class_name, wszTABLE)) - ret = HTMLTable_Create(nselem); + ret = HTMLTable_Create(doc, nselem); else if(!strcmpW(class_name, wszTR)) - ret = HTMLTableRow_Create(nselem); + ret = HTMLTableRow_Create(doc, nselem); else if(!strcmpW(class_name, wszTEXTAREA)) - ret = HTMLTextAreaElement_Create(nselem); + ret = HTMLTextAreaElement_Create(doc, nselem); else if(use_generic) - ret = HTMLGenericElement_Create(nselem); + ret = HTMLGenericElement_Create(doc, nselem); if(!ret) { ret = heap_alloc_zero(sizeof(HTMLElement)); - HTMLElement_Init(ret, NULL); + HTMLElement_Init(ret, doc, nselem, NULL); ret->node.vtbl = &HTMLElementImplVtbl; } TRACE("%s ret %p\n", debugstr_w(class_name), ret); + nsIDOMElement_Release(nselem); nsAString_Finish(&class_name_str); - ret->nselem = nselem; - HTMLDOMNode_Init(doc, &ret->node, (nsIDOMNode*)nselem); - return ret; } diff --git a/reactos/dll/win32/mshtml/htmlelem2.c b/reactos/dll/win32/mshtml/htmlelem2.c index fd7cb69f46d..d001eaa82f6 100644 --- a/reactos/dll/win32/mshtml/htmlelem2.c +++ b/reactos/dll/win32/mshtml/htmlelem2.c @@ -130,8 +130,15 @@ static HRESULT WINAPI HTMLElement2_componentFromPoint(IHTMLElement2 *iface, static HRESULT WINAPI HTMLElement2_doScroll(IHTMLElement2 *iface, VARIANT component) { HTMLElement *This = HTMLELEM2_THIS(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&component)); + + if(!This->node.doc->content_ready + || !This->node.doc->basedoc.doc_obj->in_place_active) + return E_PENDING; + + WARN("stub\n"); + return S_OK; } static HRESULT WINAPI HTMLElement2_put_onscroll(IHTMLElement2 *iface, VARIANT v) diff --git a/reactos/dll/win32/mshtml/htmlelem3.c b/reactos/dll/win32/mshtml/htmlelem3.c index 22c93a948a1..30c854637d1 100644 --- a/reactos/dll/win32/mshtml/htmlelem3.c +++ b/reactos/dll/win32/mshtml/htmlelem3.c @@ -29,6 +29,7 @@ #include "wine/unicode.h" #include "mshtml_private.h" +#include "htmlevent.h" WINE_DEFAULT_DEBUG_CHANNEL(mshtml); @@ -292,8 +293,11 @@ static HRESULT WINAPI HTMLElement3_fireEvent(IHTMLElement3 *iface, BSTR bstrEven VARIANT *pvarEventObject, VARIANT_BOOL *pfCancelled) { HTMLElement *This = HTMLELEM3_THIS(iface); - FIXME("(%p)->(%s %p %p)\n", This, debugstr_w(bstrEventName), pvarEventObject, pfCancelled); - return E_NOTIMPL; + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(bstrEventName), debugstr_variant(pvarEventObject), + pfCancelled); + + return dispatch_event(&This->node, bstrEventName, pvarEventObject, pfCancelled); } static HRESULT WINAPI HTMLElement3_put_onresizestart(IHTMLElement3 *iface, VARIANT v) diff --git a/reactos/dll/win32/mshtml/htmlelemcol.c b/reactos/dll/win32/mshtml/htmlelemcol.c index 743cc061900..70827bcd8e9 100644 --- a/reactos/dll/win32/mshtml/htmlelemcol.c +++ b/reactos/dll/win32/mshtml/htmlelemcol.c @@ -397,7 +397,7 @@ static HRESULT HTMLElementCollection_invoke(IUnknown *iface, DISPID id, LCID lci return DISP_E_UNKNOWNNAME; switch(flags) { - case INVOKE_PROPERTYGET: + case DISPATCH_PROPERTYGET: V_VT(res) = VT_DISPATCH; V_DISPATCH(res) = (IDispatch*)HTMLELEM(This->elems[idx]); IHTMLElement_AddRef(HTMLELEM(This->elems[idx])); diff --git a/reactos/dll/win32/mshtml/htmlevent.c b/reactos/dll/win32/mshtml/htmlevent.c index 8c0104fa85b..345fd839aac 100644 --- a/reactos/dll/win32/mshtml/htmlevent.c +++ b/reactos/dll/win32/mshtml/htmlevent.c @@ -96,9 +96,28 @@ static const WCHAR onreadystatechangeW[] = {'o','n','r','e','a','d','y','s','t', static const WCHAR selectstartW[] = {'s','e','l','e','c','t','s','t','a','r','t',0}; static const WCHAR onselectstartW[] = {'o','n','s','e','l','e','c','t','s','t','a','r','t',0}; +static const WCHAR HTMLEventsW[] = {'H','T','M','L','E','v','e','n','t','s',0}; +static const WCHAR KeyboardEventW[] = {'K','e','y','b','o','a','r','d','E','v','e','n','t',0}; +static const WCHAR MouseEventW[] = {'M','o','u','s','e','E','v','e','n','t',0}; + +enum { + EVENTT_NONE, + EVENTT_HTML, + EVENTT_KEY, + EVENTT_MOUSE +}; + +static const WCHAR *event_types[] = { + NULL, + HTMLEventsW, + KeyboardEventW, + MouseEventW +}; + typedef struct { LPCWSTR name; LPCWSTR attr_name; + DWORD type; DWORD flags; } event_info_t; @@ -107,24 +126,24 @@ typedef struct { #define EVENT_FORWARDBODY 0x0004 static const event_info_t event_info[] = { - {beforeunloadW, onbeforeunloadW, EVENT_DEFAULTLISTENER|EVENT_FORWARDBODY}, - {blurW, onblurW, EVENT_DEFAULTLISTENER}, - {changeW, onchangeW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {clickW, onclickW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {dblclickW, ondblclickW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {dragW, ondragW, 0}, - {dragstartW, ondragstartW, 0}, - {focusW, onfocusW, EVENT_DEFAULTLISTENER}, - {keydownW, onkeydownW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {keyupW, onkeyupW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {loadW, onloadW, 0}, - {mousedownW, onmousedownW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {mouseoutW, onmouseoutW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {mouseoverW, onmouseoverW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {mouseupW, onmouseupW, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, - {pasteW, onpasteW, 0}, - {readystatechangeW, onreadystatechangeW, 0}, - {selectstartW, onselectstartW, 0} + {beforeunloadW, onbeforeunloadW, EVENTT_NONE, EVENT_DEFAULTLISTENER|EVENT_FORWARDBODY}, + {blurW, onblurW, EVENTT_HTML, EVENT_DEFAULTLISTENER}, + {changeW, onchangeW, EVENTT_HTML, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {clickW, onclickW, EVENTT_MOUSE, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {dblclickW, ondblclickW, EVENTT_MOUSE, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {dragW, ondragW, EVENTT_MOUSE, 0}, + {dragstartW, ondragstartW, EVENTT_MOUSE, 0}, + {focusW, onfocusW, EVENTT_HTML, EVENT_DEFAULTLISTENER}, + {keydownW, onkeydownW, EVENTT_KEY, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {keyupW, onkeyupW, EVENTT_KEY, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {loadW, onloadW, EVENTT_HTML, 0}, + {mousedownW, onmousedownW, EVENTT_MOUSE, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {mouseoutW, onmouseoutW, EVENTT_MOUSE, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {mouseoverW, onmouseoverW, EVENTT_MOUSE, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {mouseupW, onmouseupW, EVENTT_MOUSE, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, + {pasteW, onpasteW, EVENTT_NONE, 0}, + {readystatechangeW, onreadystatechangeW, EVENTT_NONE, 0}, + {selectstartW, onselectstartW, EVENTT_MOUSE, 0} }; eventid_t str_to_eid(LPCWSTR str) @@ -680,15 +699,39 @@ static IHTMLEventObj *create_event(HTMLDOMNode *target, eventid_t eid, nsIDOMEve HTMLEventObj *ret; ret = heap_alloc(sizeof(*ret)); + if(!ret) + return NULL; + ret->lpIHTMLEventObjVtbl = &HTMLEventObjVtbl; ret->ref = 1; ret->type = event_info+eid; - ret->target = target; - IHTMLDOMNode_AddRef(HTMLDOMNODE(target)); ret->nsevent = nsevent; - if(nsevent) + if(nsevent) { nsIDOMEvent_AddRef(nsevent); + }else if(event_types[event_info[eid].type]) { + nsIDOMDocumentEvent *doc_event; + nsresult nsres; + + nsres = nsIDOMHTMLDocument_QueryInterface(target->doc->nsdoc, &IID_nsIDOMDocumentEvent, + (void**)&doc_event); + if(NS_SUCCEEDED(nsres)) { + nsAString type_str; + + nsAString_Init(&type_str, event_types[event_info[eid].type]); + nsres = nsIDOMDocumentEvent_CreateEvent(doc_event, &type_str, &ret->nsevent); + nsAString_Finish(&type_str); + nsIDOMDocumentEvent_Release(doc_event); + } + if(NS_FAILED(nsres)) { + ERR("Could not create event: %08x\n", nsres); + IHTMLEventObj_Release(HTMLEVENTOBJ(ret)); + return NULL; + } + } + + ret->target = target; + IHTMLDOMNode_AddRef(HTMLDOMNODE(target)); init_dispex(&ret->dispex, (IUnknown*)HTMLEVENTOBJ(ret), &HTMLEventObj_dispex); @@ -784,7 +827,7 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, nsIDOMNode *target, nsIDOM nsIDOMHTMLElement *nsbody; nsresult nsres; - nsres = nsIDOMHTMLDocument_GetBody(doc->basedoc.nsdoc, &nsbody); + nsres = nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody); if(NS_SUCCEEDED(nsres) && nsbody) { node = get_node(doc, (nsIDOMNode*)nsbody, FALSE); if(node) @@ -810,6 +853,46 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, nsIDOMNode *target, nsIDOM doc->basedoc.window->event = prev_event; } +HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *event_obj, VARIANT_BOOL *cancelled) +{ + eventid_t eid; + + eid = attr_to_eid(event_name); + if(eid == EVENTID_LAST) { + WARN("unknown event %s\n", debugstr_w(event_name)); + return E_INVALIDARG; + } + + if(event_obj && V_VT(event_obj) != VT_EMPTY && V_VT(event_obj) != VT_ERROR) + FIXME("event_obj not implemented\n"); + + if(!(event_info[eid].flags & EVENT_DEFAULTLISTENER)) { + FIXME("not EVENT_DEFAULTEVENTHANDLER\n"); + return E_NOTIMPL; + } + + fire_event(node->doc, eid, node->nsnode, NULL); + + *cancelled = VARIANT_TRUE; /* FIXME */ + return S_OK; +} + +HRESULT call_event(HTMLDOMNode *node, eventid_t eid) +{ + HRESULT hres; + + if(node->vtbl->call_event) { + BOOL handled = FALSE; + + hres = node->vtbl->call_event(node, eid, &handled); + if(handled) + return hres; + } + + fire_event(node->doc, eid, node->nsnode, NULL); + return S_OK; +} + static inline event_target_t *get_event_target(event_target_t **event_target_ptr) { if(!*event_target_ptr) @@ -838,7 +921,8 @@ static BOOL alloc_handler_vector(event_target_t *event_target, eventid_t eid, in return TRUE; } -static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLWindow *window, eventid_t eid, IDispatch *disp) +static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDocumentNode *doc, + eventid_t eid, IDispatch *disp) { event_target_t *event_target; @@ -857,23 +941,23 @@ static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLWin return S_OK; IDispatch_AddRef(disp); - if(window->nswindow && (event_info[eid].flags & EVENT_DEFAULTLISTENER)) { - if(!window->event_vector) { - window->event_vector = heap_alloc_zero(EVENTID_LAST*sizeof(BOOL)); - if(!window->event_vector) + if(doc->nsdoc && (event_info[eid].flags & EVENT_DEFAULTLISTENER)) { + if(!doc->event_vector) { + doc->event_vector = heap_alloc_zero(EVENTID_LAST*sizeof(BOOL)); + if(!doc->event_vector) return E_OUTOFMEMORY; } - if(!window->event_vector[eid]) { - window->event_vector[eid] = TRUE; - add_nsevent_listener(window, event_info[eid].name); + if(!doc->event_vector[eid]) { + doc->event_vector[eid] = TRUE; + add_nsevent_listener(doc, event_info[eid].name); } } return S_OK; } -HRESULT set_event_handler(event_target_t **event_target, HTMLDocument *doc, eventid_t eid, VARIANT *var) +HRESULT set_event_handler(event_target_t **event_target, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var) { switch(V_VT(var)) { case VT_NULL: @@ -884,7 +968,7 @@ HRESULT set_event_handler(event_target_t **event_target, HTMLDocument *doc, even break; case VT_DISPATCH: - return set_event_handler_disp(event_target, doc->window, eid, V_DISPATCH(var)); + return set_event_handler_disp(event_target, doc, eid, V_DISPATCH(var)); default: FIXME("not supported vt=%d\n", V_VT(var)); @@ -965,7 +1049,7 @@ void check_event_attr(HTMLDocumentNode *doc, nsIDOMElement *nselem) disp = script_parse_event(doc->basedoc.window, attr_value); if(disp) { node = get_node(doc, (nsIDOMNode*)nselem, TRUE); - set_event_handler_disp(get_node_event_target(node), node->doc->basedoc.window, i, disp); + set_event_handler_disp(get_node_event_target(node), node->doc, i, disp); IDispatch_Release(disp); } } diff --git a/reactos/dll/win32/mshtml/htmlevent.h b/reactos/dll/win32/mshtml/htmlevent.h index 4446aa96fba..d0332eef30c 100644 --- a/reactos/dll/win32/mshtml/htmlevent.h +++ b/reactos/dll/win32/mshtml/htmlevent.h @@ -42,9 +42,11 @@ eventid_t str_to_eid(LPCWSTR); void check_event_attr(HTMLDocumentNode*,nsIDOMElement*); void release_event_target(event_target_t*); void fire_event(HTMLDocumentNode*,eventid_t,nsIDOMNode*,nsIDOMEvent*); -HRESULT set_event_handler(event_target_t**,HTMLDocument*,eventid_t,VARIANT*); +HRESULT set_event_handler(event_target_t**,HTMLDocumentNode*,eventid_t,VARIANT*); HRESULT get_event_handler(event_target_t**,eventid_t,VARIANT*); HRESULT attach_event(event_target_t**,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*); +HRESULT dispatch_event(HTMLDOMNode*,const WCHAR*,VARIANT*,VARIANT_BOOL*); +HRESULT call_event(HTMLDOMNode*,eventid_t); static inline event_target_t **get_node_event_target(HTMLDOMNode *node) { @@ -53,7 +55,7 @@ static inline event_target_t **get_node_event_target(HTMLDOMNode *node) static inline HRESULT set_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var) { - return set_event_handler(get_node_event_target(node), &node->doc->basedoc, eid, var); + return set_event_handler(get_node_event_target(node), node->doc, eid, var); } static inline HRESULT get_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var) @@ -73,7 +75,7 @@ static inline HRESULT get_doc_event(HTMLDocument *doc, eventid_t eid, VARIANT *v static inline HRESULT set_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var) { - return set_event_handler(&window->event_target, &window->doc_obj->basedoc, eid, var); + return set_event_handler(&window->event_target, window->doc, eid, var); } static inline HRESULT get_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var) diff --git a/reactos/dll/win32/mshtml/htmlframebase.c b/reactos/dll/win32/mshtml/htmlframebase.c new file mode 100644 index 00000000000..6c0dd40a5e8 --- /dev/null +++ b/reactos/dll/win32/mshtml/htmlframebase.c @@ -0,0 +1,326 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * 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 + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "ole2.h" + +#include "mshtml_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mshtml); + +#define HTMLFRAMEBASE_THIS(iface) DEFINE_THIS(HTMLFrameBase, IHTMLFrameBase, iface) + +static HRESULT WINAPI HTMLFrameBase_QueryInterface(IHTMLFrameBase *iface, REFIID riid, void **ppv) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + + return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->element.node), riid, ppv); +} + +static ULONG WINAPI HTMLFrameBase_AddRef(IHTMLFrameBase *iface) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + + return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->element.node)); +} + +static ULONG WINAPI HTMLFrameBase_Release(IHTMLFrameBase *iface) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + + return IHTMLDOMNode_Release(HTMLDOMNODE(&This->element.node)); +} + +static HRESULT WINAPI HTMLFrameBase_GetTypeInfoCount(IHTMLFrameBase *iface, UINT *pctinfo) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo); +} + +static HRESULT WINAPI HTMLFrameBase_GetTypeInfo(IHTMLFrameBase *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLFrameBase_GetIDsOfNames(IHTMLFrameBase *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, + cNames, lcid, rgDispId); +} + +static HRESULT WINAPI HTMLFrameBase_Invoke(IHTMLFrameBase *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + + return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLFrameBase_put_src(IHTMLFrameBase *iface, BSTR v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_src(IHTMLFrameBase *iface, BSTR *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_put_name(IHTMLFrameBase *iface, BSTR v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_name(IHTMLFrameBase *iface, BSTR *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_put_border(IHTMLFrameBase *iface, VARIANT v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_border(IHTMLFrameBase *iface, VARIANT *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_put_frameBorder(IHTMLFrameBase *iface, BSTR v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_frameBorder(IHTMLFrameBase *iface, BSTR *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_put_frameSpacing(IHTMLFrameBase *iface, VARIANT v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_frameSpacing(IHTMLFrameBase *iface, VARIANT *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_put_marginWidth(IHTMLFrameBase *iface, VARIANT v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_marginWidth(IHTMLFrameBase *iface, VARIANT *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_put_marginHeight(IHTMLFrameBase *iface, VARIANT v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_marginHeight(IHTMLFrameBase *iface, VARIANT *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_put_noResize(IHTMLFrameBase *iface, VARIANT_BOOL v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%x)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_noResize(IHTMLFrameBase *iface, VARIANT_BOOL *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_put_scrolling(IHTMLFrameBase *iface, BSTR v) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFrameBase_get_scrolling(IHTMLFrameBase *iface, BSTR *p) +{ + HTMLFrameBase *This = HTMLFRAMEBASE_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const IHTMLFrameBaseVtbl HTMLFrameBaseVtbl = { + HTMLFrameBase_QueryInterface, + HTMLFrameBase_AddRef, + HTMLFrameBase_Release, + HTMLFrameBase_GetTypeInfoCount, + HTMLFrameBase_GetTypeInfo, + HTMLFrameBase_GetIDsOfNames, + HTMLFrameBase_Invoke, + HTMLFrameBase_put_src, + HTMLFrameBase_get_src, + HTMLFrameBase_put_name, + HTMLFrameBase_get_name, + HTMLFrameBase_put_border, + HTMLFrameBase_get_border, + HTMLFrameBase_put_frameBorder, + HTMLFrameBase_get_frameBorder, + HTMLFrameBase_put_frameSpacing, + HTMLFrameBase_get_frameSpacing, + HTMLFrameBase_put_marginWidth, + HTMLFrameBase_get_marginWidth, + HTMLFrameBase_put_marginHeight, + HTMLFrameBase_get_marginHeight, + HTMLFrameBase_put_noResize, + HTMLFrameBase_get_noResize, + HTMLFrameBase_put_scrolling, + HTMLFrameBase_get_scrolling +}; + +HRESULT HTMLFrameBase_QI(HTMLFrameBase *This, REFIID riid, void **ppv) +{ + if(IsEqualGUID(&IID_IHTMLFrameBase, riid)) { + TRACE("(%p)->(IID_IHTMLFrameBase %p)\n", This, ppv); + *ppv = HTMLFRAMEBASE(This); + }else { + return HTMLElement_QI(&This->element.node, riid, ppv); + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +void HTMLFrameBase_destructor(HTMLFrameBase *This) +{ + if(This->content_window) { + This->content_window->frame_element = NULL; + IHTMLWindow2_Release(HTMLWINDOW2(This->content_window)); + } + + HTMLElement_destructor(&This->element.node); +} + +void HTMLFrameBase_Init(HTMLFrameBase *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, + HTMLWindow *content_window, dispex_static_data_t *dispex_data) +{ + This->lpIHTMLFrameBaseVtbl = &HTMLFrameBaseVtbl; + + HTMLElement_Init(&This->element, doc, nselem, dispex_data); + + if(content_window) { + IHTMLWindow2_AddRef(HTMLWINDOW2(content_window)); + content_window->frame_element = This; + } + This->content_window = content_window; +} + +typedef struct { + HTMLFrameBase framebase; +} HTMLFrameElement; + +#define HTMLFRAME_NODE_THIS(iface) DEFINE_THIS2(HTMLFrameElement, framebase.element.node, iface) + +static HRESULT HTMLFrameElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) +{ + HTMLFrameElement *This = HTMLFRAME_NODE_THIS(iface); + + return HTMLFrameBase_QI(&This->framebase, riid, ppv); +} + +static void HTMLFrameElement_destructor(HTMLDOMNode *iface) +{ + HTMLFrameElement *This = HTMLFRAME_NODE_THIS(iface); + + HTMLFrameBase_destructor(&This->framebase); +} + +#undef HTMLFRAME_NODE_THIS + +static const NodeImplVtbl HTMLFrameElementImplVtbl = { + HTMLFrameElement_QI, + HTMLFrameElement_destructor +}; + +HTMLElement *HTMLFrameElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLWindow *content_window) +{ + nsIDOMHTMLFrameElement *nsframe; + HTMLFrameElement *ret; + nsresult nsres; + + ret = heap_alloc_zero(sizeof(HTMLFrameElement)); + + ret->framebase.element.node.vtbl = &HTMLFrameElementImplVtbl; + + nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe); + if(NS_FAILED(nsres)) + ERR("Could not get nsIDOMHTMLFrameElement iface: %08x\n", nsres); + + HTMLFrameBase_Init(&ret->framebase, doc, nselem, content_window, NULL); + + return &ret->framebase.element; +} diff --git a/reactos/dll/win32/mshtml/htmlgeneric.c b/reactos/dll/win32/mshtml/htmlgeneric.c index 142caa69e5a..8b753164f00 100644 --- a/reactos/dll/win32/mshtml/htmlgeneric.c +++ b/reactos/dll/win32/mshtml/htmlgeneric.c @@ -169,7 +169,7 @@ static dispex_static_data_t HTMLGenericElement_dispex = { HTMLGenericElement_iface_tids }; -HTMLElement *HTMLGenericElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLGenericElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLGenericElement *ret; @@ -178,7 +178,7 @@ HTMLElement *HTMLGenericElement_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLGenericElementVtbl = &HTMLGenericElementVtbl; ret->element.node.vtbl = &HTMLGenericElementImplVtbl; - HTMLElement_Init(&ret->element, &HTMLGenericElement_dispex); + HTMLElement_Init(&ret->element, doc, nselem, &HTMLGenericElement_dispex); return &ret->element; } diff --git a/reactos/dll/win32/mshtml/htmliframe.c b/reactos/dll/win32/mshtml/htmliframe.c index a482a5b05ae..daef946c94d 100644 --- a/reactos/dll/win32/mshtml/htmliframe.c +++ b/reactos/dll/win32/mshtml/htmliframe.c @@ -32,72 +32,37 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); typedef struct { - HTMLElement element; + HTMLFrameBase framebase; const IHTMLFrameBase2Vtbl *lpIHTMLFrameBase2Vtbl; LONG ref; nsIDOMHTMLIFrameElement *nsiframe; - HTMLWindow *content_window; } HTMLIFrame; #define HTMLFRAMEBASE2(x) (&(x)->lpIHTMLFrameBase2Vtbl) -static HRESULT create_content_window(HTMLIFrame *This, nsIDOMHTMLDocument *nsdoc, HTMLWindow **ret) -{ - nsIDOMDocumentView *nsdocview; - nsIDOMAbstractView *nsview; - nsIDOMWindow *nswindow; - nsresult nsres; - HRESULT hres; - - nsres = nsIDOMHTMLDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentView, (void**)&nsdocview); - if(NS_FAILED(nsres)) { - ERR("Could not get nsIDOMDocumentView: %08x\n", nsres); - return E_FAIL; - } - - nsres = nsIDOMDocumentView_GetDefaultView(nsdocview, &nsview); - nsIDOMDocumentView_Release(nsdocview); - if(NS_FAILED(nsres)) { - ERR("GetDefaultView failed: %08x\n", nsres); - return E_FAIL; - } - - nsres = nsIDOMAbstractView_QueryInterface(nsview, &IID_nsIDOMWindow, (void**)&nswindow); - nsIDOMAbstractView_Release(nsview); - if(NS_FAILED(nsres)) { - ERR("Coult not get nsIDOMWindow iface: %08x\n", nsres); - return E_FAIL; - } - - hres = HTMLWindow_Create(This->element.node.doc->basedoc.doc_obj, nswindow, ret); - - nsIDOMWindow_Release(nswindow); - return hres; -} - #define HTMLFRAMEBASE2_THIS(iface) DEFINE_THIS(HTMLIFrame, IHTMLFrameBase2, iface) static HRESULT WINAPI HTMLIFrameBase2_QueryInterface(IHTMLFrameBase2 *iface, REFIID riid, void **ppv) { HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface); - return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->element.node), riid, ppv); + return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->framebase.element.node), riid, ppv); } static ULONG WINAPI HTMLIFrameBase2_AddRef(IHTMLFrameBase2 *iface) { HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface); - return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->element.node)); + return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->framebase.element.node)); } static ULONG WINAPI HTMLIFrameBase2_Release(IHTMLFrameBase2 *iface) { HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface); - return IHTMLDOMNode_Release(HTMLDOMNODE(&This->element.node)); + return IHTMLDOMNode_Release(HTMLDOMNODE(&This->framebase.element.node)); } static HRESULT WINAPI HTMLIFrameBase2_GetTypeInfoCount(IHTMLFrameBase2 *iface, UINT *pctinfo) @@ -138,53 +103,13 @@ static HRESULT WINAPI HTMLIFrameBase2_get_contentWindow(IHTMLFrameBase2 *iface, TRACE("(%p)->(%p)\n", This, p); - if(!This->content_window) { - nsIDOMHTMLDocument *nshtmldoc; - HTMLDocumentNode *content_doc; - nsIDOMDocument *nsdoc; - HTMLWindow *window; - nsresult nsres; - HRESULT hres; - - nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->nsiframe, &nsdoc); - if(NS_FAILED(nsres)) { - ERR("GetContentDocument failed: %08x\n", nsres); - return E_FAIL; - } - - if(!nsdoc) { - FIXME("NULL contentDocument\n"); - return E_FAIL; - } - - nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc); - nsIDOMDocument_Release(nsdoc); - if(NS_FAILED(nsres)) { - ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres); - return E_FAIL; - } - - hres = create_content_window(This, nshtmldoc, &window); - if(FAILED(hres)) { - nsIDOMHTMLDocument_Release(nshtmldoc); - return E_FAIL; - } - - hres = create_doc_from_nsdoc(nshtmldoc, This->element.node.doc->basedoc.doc_obj, window, &content_doc); - nsIDOMHTMLDocument_Release(nshtmldoc); - if(SUCCEEDED(hres)) - window_set_docnode(window, content_doc); - else - IHTMLWindow2_Release(HTMLWINDOW2(window)); - htmldoc_release(&content_doc->basedoc); - if(FAILED(hres)) - return hres; - - This->content_window = window; + if(This->framebase.content_window) { + IHTMLWindow2_AddRef(HTMLWINDOW2(This->framebase.content_window)); + *p = HTMLWINDOW2(This->framebase.content_window); + }else { + WARN("NULL content window\n"); + *p = NULL; } - - IHTMLWindow2_AddRef(HTMLWINDOW2(This->content_window)); - *p = HTMLWINDOW2(This->content_window); return S_OK; } @@ -257,7 +182,7 @@ static const IHTMLFrameBase2Vtbl HTMLIFrameBase2Vtbl = { HTMLIFrameBase2_get_allowTransparency }; -#define HTMLIFRAME_NODE_THIS(iface) DEFINE_THIS2(HTMLIFrame, element.node, iface) +#define HTMLIFRAME_NODE_THIS(iface) DEFINE_THIS2(HTMLIFrame, framebase.element.node, iface) static HRESULT HTMLIFrame_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) { @@ -269,7 +194,7 @@ static HRESULT HTMLIFrame_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) TRACE("(%p)->(IID_IHTMLFrameBase2 %p)\n", This, ppv); *ppv = HTMLFRAMEBASE2(This); }else { - return HTMLElement_QI(&This->element.node, riid, ppv); + return HTMLFrameBase_QI(&This->framebase, riid, ppv); } IUnknown_AddRef((IUnknown*)*ppv); @@ -280,12 +205,10 @@ static void HTMLIFrame_destructor(HTMLDOMNode *iface) { HTMLIFrame *This = HTMLIFRAME_NODE_THIS(iface); - if(This->content_window) - IHTMLWindow2_Release(HTMLWINDOW2(This->content_window)); if(This->nsiframe) nsIDOMHTMLIFrameElement_Release(This->nsiframe); - HTMLElement_destructor(&This->element.node); + HTMLFrameBase_destructor(&This->framebase); } #undef HTMLIFRAME_NODE_THIS @@ -301,6 +224,7 @@ static const tid_t HTMLIFrame_iface_tids[] = { IHTMLElement_tid, IHTMLElement2_tid, IHTMLElement3_tid, + IHTMLFrameBase_tid, IHTMLFrameBase2_tid, 0 }; @@ -312,7 +236,38 @@ static dispex_static_data_t HTMLIFrame_dispex = { HTMLIFrame_iface_tids }; -HTMLElement *HTMLIFrame_Create(nsIDOMHTMLElement *nselem) +static HTMLWindow *get_content_window(nsIDOMHTMLIFrameElement *nsiframe) +{ + HTMLWindow *ret; + nsIDOMWindow *nswindow; + nsIDOMDocument *nsdoc; + nsresult nsres; + + nsres = nsIDOMHTMLIFrameElement_GetContentDocument(nsiframe, &nsdoc); + if(NS_FAILED(nsres)) { + ERR("GetContentDocument failed: %08x\n", nsres); + return NULL; + } + + if(!nsdoc) { + FIXME("NULL contentDocument\n"); + return NULL; + } + + nswindow = get_nsdoc_window(nsdoc); + nsIDOMDocument_Release(nsdoc); + if(!nswindow) + return NULL; + + ret = nswindow_to_window(nswindow); + nsIDOMWindow_Release(nswindow); + if(!ret) + ERR("Could not get window object\n"); + + return ret; +} + +HTMLElement *HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLWindow *content_window) { HTMLIFrame *ret; nsresult nsres; @@ -320,13 +275,16 @@ HTMLElement *HTMLIFrame_Create(nsIDOMHTMLElement *nselem) ret = heap_alloc_zero(sizeof(HTMLIFrame)); ret->lpIHTMLFrameBase2Vtbl = &HTMLIFrameBase2Vtbl; - ret->element.node.vtbl = &HTMLIFrameImplVtbl; - - HTMLElement_Init(&ret->element, &HTMLIFrame_dispex); + ret->framebase.element.node.vtbl = &HTMLIFrameImplVtbl; nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLIFrameElement, (void**)&ret->nsiframe); if(NS_FAILED(nsres)) ERR("Could not get nsIDOMHTMLIFrameElement iface: %08x\n", nsres); - return &ret->element; + if(!content_window) + content_window = get_content_window(ret->nsiframe); + + HTMLFrameBase_Init(&ret->framebase, doc, nselem, content_window, &HTMLIFrame_dispex); + + return &ret->framebase.element; } diff --git a/reactos/dll/win32/mshtml/htmlimg.c b/reactos/dll/win32/mshtml/htmlimg.c index a29cd76ba65..bfccdd57b63 100644 --- a/reactos/dll/win32/mshtml/htmlimg.c +++ b/reactos/dll/win32/mshtml/htmlimg.c @@ -595,7 +595,7 @@ static dispex_static_data_t HTMLImgElement_dispex = { HTMLImgElement_iface_tids }; -HTMLElement *HTMLImgElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLImgElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLImgElement *ret = heap_alloc_zero(sizeof(HTMLImgElement)); nsresult nsres; @@ -607,7 +607,211 @@ HTMLElement *HTMLImgElement_Create(nsIDOMHTMLElement *nselem) if(NS_FAILED(nsres)) ERR("Could not get nsIDOMHTMLImageElement: %08x\n", nsres); - HTMLElement_Init(&ret->element, &HTMLImgElement_dispex); + HTMLElement_Init(&ret->element, doc, nselem, &HTMLImgElement_dispex); return &ret->element; } + +#define HTMLIMGFACTORY_THIS(iface) DEFINE_THIS(HTMLImageElementFactory, HTMLImageElementFactory, iface) + +static HRESULT WINAPI HTMLImageElementFactory_QueryInterface(IHTMLImageElementFactory *iface, + REFIID riid, void **ppv) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_Unknown %p)\n", This, ppv); + *ppv = HTMLIMGFACTORY(This); + }else if(IsEqualGUID(&IID_IHTMLImageElementFactory, riid)) { + TRACE("(%p)->(IID_IHTMLImageElementFactory %p)\n", This, ppv); + *ppv = HTMLIMGFACTORY(This); + }else if(dispex_query_interface(&This->dispex, riid, ppv)) + return *ppv ? S_OK : E_NOINTERFACE; + + if(*ppv) { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI HTMLImageElementFactory_AddRef(IHTMLImageElementFactory *iface) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI HTMLImageElementFactory_Release(IHTMLImageElementFactory *iface) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfoCount(IHTMLImageElementFactory *iface, + UINT *pctinfo) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLImageElementFactory_GetTypeInfo(IHTMLImageElementFactory *iface, + UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLImageElementFactory_GetIDsOfNames(IHTMLImageElementFactory *iface, + REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, + DISPID *rgDispId) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, + cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLImageElementFactory_Invoke(IHTMLImageElementFactory *iface, + DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, + DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLImageElementFactory_create(IHTMLImageElementFactory *iface, + VARIANT width, VARIANT height, IHTMLImgElement **img_elem) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + HTMLElement *elem; + nsIDOMHTMLElement *nselem; + HRESULT hres; + + static const PRUnichar imgW[] = {'I','M','G',0}; + + TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&width), + debugstr_variant(&height), img_elem); + + if(!This->window || !This->window->doc) { + WARN("NULL doc\n"); + return E_UNEXPECTED; + } + + *img_elem = NULL; + + hres = create_nselem(This->window->doc, imgW, &nselem); + if(FAILED(hres)) + return hres; + + elem = HTMLElement_Create(This->window->doc, (nsIDOMNode*)nselem, FALSE); + if(!elem) { + ERR("HTMLElement_Create failed\n"); + return E_FAIL; + } + + hres = IHTMLElement_QueryInterface(HTMLELEM(elem), &IID_IHTMLImgElement, (void**)img_elem); + if(FAILED(hres)) { + ERR("IHTMLElement_QueryInterface failed: 0x%08x\n", hres); + return hres; + } + + nsIDOMHTMLElement_Release(nselem); + + if(V_VT(&width) != VT_EMPTY || V_VT(&height) != VT_EMPTY) + FIXME("Not setting image dimensions\n"); + + return S_OK; +} + +static HRESULT HTMLImageElementFactory_value(IUnknown *iface, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, + IServiceProvider *caller) +{ + HTMLImageElementFactory *This = HTMLIMGFACTORY_THIS(iface); + IHTMLImgElement *img; + VARIANT empty, *width, *height; + HRESULT hres; + int argc = params->cArgs - params->cNamedArgs; + + V_VT(res) = VT_NULL; + + V_VT(&empty) = VT_EMPTY; + + width = argc >= 1 ? params->rgvarg + (params->cArgs - 1) : ∅ + height = argc >= 2 ? params->rgvarg + (params->cArgs - 2) : ∅ + + hres = IHTMLImageElementFactory_create(HTMLIMGFACTORY(This), *width, *height, &img); + if(FAILED(hres)) + return hres; + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)img; + + return S_OK; +} + +#undef HTMLIMGFACTORY_THIS + +static const IHTMLImageElementFactoryVtbl HTMLImageElementFactoryVtbl = { + HTMLImageElementFactory_QueryInterface, + HTMLImageElementFactory_AddRef, + HTMLImageElementFactory_Release, + HTMLImageElementFactory_GetTypeInfoCount, + HTMLImageElementFactory_GetTypeInfo, + HTMLImageElementFactory_GetIDsOfNames, + HTMLImageElementFactory_Invoke, + HTMLImageElementFactory_create +}; + +static const tid_t HTMLImageElementFactory_iface_tids[] = { + IHTMLImageElementFactory_tid, + 0 +}; + +static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = { + HTMLImageElementFactory_value, + NULL, + NULL +}; + +static dispex_static_data_t HTMLImageElementFactory_dispex = { + &HTMLImageElementFactory_dispex_vtbl, + IHTMLImageElementFactory_tid, + NULL, + HTMLImageElementFactory_iface_tids +}; + +HTMLImageElementFactory *HTMLImageElementFactory_Create(HTMLWindow *window) +{ + HTMLImageElementFactory *ret; + + ret = heap_alloc(sizeof(HTMLImageElementFactory)); + + ret->lpHTMLImageElementFactoryVtbl = &HTMLImageElementFactoryVtbl; + ret->ref = 1; + ret->window = window; + + init_dispex(&ret->dispex, (IUnknown*)HTMLIMGFACTORY(ret), &HTMLImageElementFactory_dispex); + + return ret; +} diff --git a/reactos/dll/win32/mshtml/htmlinput.c b/reactos/dll/win32/mshtml/htmlinput.c index 7db777c14f5..ae7994a291b 100644 --- a/reactos/dll/win32/mshtml/htmlinput.c +++ b/reactos/dll/win32/mshtml/htmlinput.c @@ -28,6 +28,7 @@ #include "wine/debug.h" #include "mshtml_private.h" +#include "htmlevent.h" WINE_DEFAULT_DEBUG_CHANNEL(mshtml); @@ -1129,6 +1130,25 @@ static void HTMLInputElement_destructor(HTMLDOMNode *iface) HTMLElement_destructor(&This->element.node); } +static HRESULT HTMLInputElementImpl_call_event(HTMLDOMNode *iface, eventid_t eid, BOOL *handled) +{ + HTMLInputElement *This = HTMLINPUT_NODE_THIS(iface); + + if(eid == EVENTID_CLICK) { + nsresult nsres; + + *handled = TRUE; + + nsres = nsIDOMHTMLInputElement_Click(This->nsinput); + if(NS_FAILED(nsres)) { + ERR("Click failed: %08x\n", nsres); + return E_FAIL; + } + } + + return S_OK; +} + static HRESULT HTMLInputElementImpl_put_disabled(HTMLDOMNode *iface, VARIANT_BOOL v) { HTMLInputElement *This = HTMLINPUT_NODE_THIS(iface); @@ -1147,6 +1167,7 @@ static const NodeImplVtbl HTMLInputElementImplVtbl = { HTMLInputElement_QI, HTMLInputElement_destructor, NULL, + HTMLInputElementImpl_call_event, HTMLInputElementImpl_put_disabled, HTMLInputElementImpl_get_disabled, }; @@ -1167,7 +1188,7 @@ static dispex_static_data_t HTMLInputElement_dispex = { HTMLInputElement_iface_tids }; -HTMLElement *HTMLInputElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLInputElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLInputElement *ret = heap_alloc_zero(sizeof(HTMLInputElement)); nsresult nsres; @@ -1176,7 +1197,7 @@ HTMLElement *HTMLInputElement_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLInputTextElementVtbl = &HTMLInputTextElementVtbl; ret->element.node.vtbl = &HTMLInputElementImplVtbl; - HTMLElement_Init(&ret->element, &HTMLInputElement_dispex); + HTMLElement_Init(&ret->element, doc, nselem, &HTMLInputElement_dispex); nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLInputElement, (void**)&ret->nsinput); diff --git a/reactos/dll/win32/mshtml/htmllocation.c b/reactos/dll/win32/mshtml/htmllocation.c index 45899b43379..3b91429bdb9 100644 --- a/reactos/dll/win32/mshtml/htmllocation.c +++ b/reactos/dll/win32/mshtml/htmllocation.c @@ -37,15 +37,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); static HRESULT get_url(HTMLLocation *This, const WCHAR **ret) { - if(!This->window || !This->window->doc_obj || !This->window->doc_obj->url) { + if(!This->window || !This->window->url) { FIXME("No current URL\n"); return E_NOTIMPL; } - *ret = This->window->doc_obj->url; + *ret = This->window->url; return S_OK; } +static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url) +{ + const WCHAR *doc_url; + HRESULT hres; + + hres = get_url(This, &doc_url); + if(FAILED(hres)) + return hres; + + if(!InternetCrackUrlW(doc_url, 0, 0, url)) { + FIXME("InternetCrackUrlW failed: 0x%08x\n", GetLastError()); + SetLastError(0); + return E_FAIL; + } + + return S_OK; +} #define HTMLLOCATION_THIS(iface) DEFINE_THIS(HTMLLocation, HTMLLocation, iface) @@ -134,27 +151,115 @@ static HRESULT WINAPI HTMLLocation_Invoke(IHTMLLocation *iface, DISPID dispIdMem static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + if(!This->window || !This->window->doc) { + FIXME("No document available\n"); + return E_FAIL; + } + + return navigate_url(This->window->doc, v); } static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - const WCHAR *url; - HRESULT hres; + URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)}; + WCHAR *buf = NULL, *url_path = NULL; + HRESULT hres, ret; + DWORD len = 0; + int i; TRACE("(%p)->(%p)\n", This, p); if(!p) return E_POINTER; - hres = get_url(This, &url); + url.dwSchemeLength = 1; + url.dwHostNameLength = 1; + url.dwUrlPathLength = 1; + url.dwExtraInfoLength = 1; + hres = get_url_components(This, &url); if(FAILED(hres)) return hres; - *p = SysAllocString(url); - return *p ? S_OK : E_OUTOFMEMORY; + switch(url.nScheme) { + case INTERNET_SCHEME_FILE: + { + /* prepend a slash */ + url_path = HeapAlloc(GetProcessHeap(), 0, (url.dwUrlPathLength + 1) * sizeof(WCHAR)); + if(!url_path) + return E_OUTOFMEMORY; + url_path[0] = '/'; + memcpy(url_path + 1, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR)); + url.lpszUrlPath = url_path; + url.dwUrlPathLength = url.dwUrlPathLength + 1; + } + break; + + case INTERNET_SCHEME_HTTP: + case INTERNET_SCHEME_HTTPS: + case INTERNET_SCHEME_FTP: + if(!url.dwUrlPathLength) { + /* add a slash if it's blank */ + url_path = url.lpszUrlPath = HeapAlloc(GetProcessHeap(), 0, 1 * sizeof(WCHAR)); + if(!url.lpszUrlPath) + return E_OUTOFMEMORY; + url.lpszUrlPath[0] = '/'; + url.dwUrlPathLength = 1; + } + break; + + default: + break; + } + + /* replace \ with / */ + for(i = 0; i < url.dwUrlPathLength; ++i) + if(url.lpszUrlPath[i] == '\\') + url.lpszUrlPath[i] = '/'; + + if(InternetCreateUrlW(&url, ICU_ESCAPE, NULL, &len)) { + FIXME("InternetCreateUrl succeeded with NULL buffer?\n"); + ret = E_FAIL; + goto cleanup; + } + + if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError()); + SetLastError(0); + ret = E_FAIL; + goto cleanup; + } + SetLastError(0); + + buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if(!buf) { + ret = E_OUTOFMEMORY; + goto cleanup; + } + + if(!InternetCreateUrlW(&url, ICU_ESCAPE, buf, &len)) { + FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError()); + SetLastError(0); + ret = E_FAIL; + goto cleanup; + } + + *p = SysAllocStringLen(buf, len); + if(!*p) { + ret = E_OUTOFMEMORY; + goto cleanup; + } + + ret = S_OK; + +cleanup: + HeapFree(GetProcessHeap(), 0, buf); + HeapFree(GetProcessHeap(), 0, url_path); + + return ret; } static HRESULT WINAPI HTMLLocation_put_protocol(IHTMLLocation *iface, BSTR v) @@ -167,12 +272,31 @@ static HRESULT WINAPI HTMLLocation_put_protocol(IHTMLLocation *iface, BSTR v) static HRESULT WINAPI HTMLLocation_get_protocol(IHTMLLocation *iface, BSTR *p) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); + URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)}; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); if(!p) return E_POINTER; - return E_NOTIMPL; + url.dwSchemeLength = 1; + hres = get_url_components(This, &url); + if(FAILED(hres)) + return hres; + + if(!url.dwSchemeLength) { + FIXME("Unexpected blank protocol\n"); + return E_NOTIMPL; + }else { + WCHAR buf[url.dwSchemeLength + 1]; + memcpy(buf, url.lpszScheme, url.dwSchemeLength * sizeof(WCHAR)); + buf[url.dwSchemeLength] = ':'; + *p = SysAllocStringLen(buf, url.dwSchemeLength + 1); + } + if(!*p) + return E_OUTOFMEMORY; + return S_OK; } static HRESULT WINAPI HTMLLocation_put_host(IHTMLLocation *iface, BSTR v) @@ -185,12 +309,40 @@ static HRESULT WINAPI HTMLLocation_put_host(IHTMLLocation *iface, BSTR v) static HRESULT WINAPI HTMLLocation_get_host(IHTMLLocation *iface, BSTR *p) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); + URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)}; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); if(!p) return E_POINTER; - return E_NOTIMPL; + url.dwHostNameLength = 1; + hres = get_url_components(This, &url); + if(FAILED(hres)) + return hres; + + if(!url.dwHostNameLength){ + *p = NULL; + return S_OK; + } + + if(url.nPort) { + /* : */ + const WCHAR format[] = {'%','d',0}; + DWORD len = url.dwHostNameLength + 1 + 5 + 1; + WCHAR buf[len]; + + memcpy(buf, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR)); + buf[url.dwHostNameLength] = ':'; + snprintfW(buf + url.dwHostNameLength + 1, 6, format, url.nPort); + *p = SysAllocString(buf); + }else + *p = SysAllocStringLen(url.lpszHostName, url.dwHostNameLength); + + if(!*p) + return E_OUTOFMEMORY; + return S_OK; } static HRESULT WINAPI HTMLLocation_put_hostname(IHTMLLocation *iface, BSTR v) @@ -203,12 +355,28 @@ static HRESULT WINAPI HTMLLocation_put_hostname(IHTMLLocation *iface, BSTR v) static HRESULT WINAPI HTMLLocation_get_hostname(IHTMLLocation *iface, BSTR *p) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); + URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)}; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); if(!p) return E_POINTER; - return E_NOTIMPL; + url.dwHostNameLength = 1; + hres = get_url_components(This, &url); + if(FAILED(hres)) + return hres; + + if(!url.dwHostNameLength){ + *p = NULL; + return S_OK; + } + + *p = SysAllocStringLen(url.lpszHostName, url.dwHostNameLength); + if(!*p) + return E_OUTOFMEMORY; + return S_OK; } static HRESULT WINAPI HTMLLocation_put_port(IHTMLLocation *iface, BSTR v) @@ -221,12 +389,31 @@ static HRESULT WINAPI HTMLLocation_put_port(IHTMLLocation *iface, BSTR v) static HRESULT WINAPI HTMLLocation_get_port(IHTMLLocation *iface, BSTR *p) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); + URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)}; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); if(!p) return E_POINTER; - return E_NOTIMPL; + hres = get_url_components(This, &url); + if(FAILED(hres)) + return hres; + + if(url.nPort) { + const WCHAR format[] = {'%','d',0}; + WCHAR buf[6]; + snprintfW(buf, 6, format, url.nPort); + *p = SysAllocString(buf); + }else { + const WCHAR empty[] = {0}; + *p = SysAllocString(empty); + } + + if(!*p) + return E_OUTOFMEMORY; + return S_OK; } static HRESULT WINAPI HTMLLocation_put_pathname(IHTMLLocation *iface, BSTR v) @@ -239,10 +426,7 @@ static HRESULT WINAPI HTMLLocation_put_pathname(IHTMLLocation *iface, BSTR v) static HRESULT WINAPI HTMLLocation_get_pathname(IHTMLLocation *iface, BSTR *p) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - WCHAR buf[INTERNET_MAX_PATH_LENGTH]; - URL_COMPONENTSW url = {sizeof(url)}; - const WCHAR *doc_url; - DWORD size = 0; + URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)}; HRESULT hres; TRACE("(%p)->(%p)\n", This, p); @@ -250,30 +434,17 @@ static HRESULT WINAPI HTMLLocation_get_pathname(IHTMLLocation *iface, BSTR *p) if(!p) return E_POINTER; - hres = get_url(This, &doc_url); + url.dwUrlPathLength = 1; + url.dwExtraInfoLength = 1; + hres = get_url_components(This, &url); if(FAILED(hres)) return hres; - hres = CoInternetParseUrl(doc_url, PARSE_PATH_FROM_URL, 0, buf, sizeof(buf), &size, 0); - if(SUCCEEDED(hres)) { - *p = SysAllocString(buf); - if(!*p) - return E_OUTOFMEMORY; - return S_OK; - } + if(url.dwUrlPathLength && url.lpszUrlPath[0] == '/') + *p = SysAllocStringLen(url.lpszUrlPath + 1, url.dwUrlPathLength - 1); + else + *p = SysAllocStringLen(url.lpszUrlPath, url.dwUrlPathLength); - url.dwUrlPathLength = 1; - if(!InternetCrackUrlW(doc_url, 0, 0, &url)) { - FIXME("InternetCrackUrl failed\n"); - return E_FAIL; - } - - if(!url.dwUrlPathLength) { - *p = NULL; - return S_OK; - } - - *p = SysAllocStringLen(url.lpszUrlPath, url.dwUrlPathLength); if(!*p) return E_OUTOFMEMORY; return S_OK; @@ -289,12 +460,32 @@ static HRESULT WINAPI HTMLLocation_put_search(IHTMLLocation *iface, BSTR v) static HRESULT WINAPI HTMLLocation_get_search(IHTMLLocation *iface, BSTR *p) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); + URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)}; + HRESULT hres; + const WCHAR hash[] = {'#',0}; + + TRACE("(%p)->(%p)\n", This, p); if(!p) return E_POINTER; - return E_NOTIMPL; + url.dwExtraInfoLength = 1; + hres = get_url_components(This, &url); + if(FAILED(hres)) + return hres; + + if(!url.dwExtraInfoLength){ + *p = NULL; + return S_OK; + } + + url.dwExtraInfoLength = strcspnW(url.lpszExtraInfo, hash); + + *p = SysAllocStringLen(url.lpszExtraInfo, url.dwExtraInfoLength); + + if(!*p) + return E_OUTOFMEMORY; + return S_OK; } static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) @@ -307,12 +498,34 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) static HRESULT WINAPI HTMLLocation_get_hash(IHTMLLocation *iface, BSTR *p) { HTMLLocation *This = HTMLLOCATION_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); + URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)}; + const WCHAR hash[] = {'#',0}; + DWORD hash_pos = 0; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); if(!p) return E_POINTER; - return E_NOTIMPL; + url.dwExtraInfoLength = 1; + hres = get_url_components(This, &url); + if(FAILED(hres)) + return hres; + + if(!url.dwExtraInfoLength){ + *p = NULL; + return S_OK; + } + + hash_pos = strcspnW(url.lpszExtraInfo, hash); + url.dwExtraInfoLength -= hash_pos; + + *p = SysAllocStringLen(url.lpszExtraInfo + hash_pos, url.dwExtraInfoLength); + + if(!*p) + return E_OUTOFMEMORY; + return S_OK; } static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL flag) diff --git a/reactos/dll/win32/mshtml/htmlnode.c b/reactos/dll/win32/mshtml/htmlnode.c index 1c7b7cb441c..b8cecf0629e 100644 --- a/reactos/dll/win32/mshtml/htmlnode.c +++ b/reactos/dll/win32/mshtml/htmlnode.c @@ -208,7 +208,7 @@ static HRESULT HTMLDOMChildrenCollection_invoke(IUnknown *iface, DISPID id, LCID TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller); switch(flags) { - case INVOKE_PROPERTYGET: { + case DISPATCH_PROPERTYGET: { IDispatch *disp = NULL; HRESULT hres; @@ -729,8 +729,19 @@ static HRESULT WINAPI HTMLDOMNode_get_previousSibling(IHTMLDOMNode *iface, IHTML static HRESULT WINAPI HTMLDOMNode_get_nextSibling(IHTMLDOMNode *iface, IHTMLDOMNode **p) { HTMLDOMNode *This = HTMLDOMNODE_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsIDOMNode *nssibling = NULL; + + TRACE("(%p)->(%p)\n", This, p); + + nsIDOMNode_GetNextSibling(This->nsnode, &nssibling); + if(nssibling) { + *p = HTMLDOMNODE(get_node(This->doc, nssibling, TRUE)); + IHTMLDOMNode_AddRef(*p); + }else { + *p = NULL; + } + + return S_OK; } #undef HTMLDOMNODE_THIS @@ -825,8 +836,13 @@ static HRESULT WINAPI HTMLDOMNode2_get_ownerDocument(IHTMLDOMNode2 *iface, IDisp TRACE("(%p)->(%p)\n", This, p); - *p = (IDispatch*)HTMLDOC(&This->doc->basedoc); - IDispatch_AddRef(*p); + /* FIXME: Better check for document node */ + if(This == &This->doc->node) { + *p = NULL; + }else { + *p = (IDispatch*)HTMLDOC(&This->doc->basedoc); + IDispatch_AddRef(*p); + } return S_OK; } @@ -900,7 +916,8 @@ void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsno node->ref = 1; node->doc = doc; - nsIDOMNode_AddRef(nsnode); + if(nsnode) + nsIDOMNode_AddRef(nsnode); node->nsnode = nsnode; node->next = doc->nodes; diff --git a/reactos/dll/win32/mshtml/htmloption.c b/reactos/dll/win32/mshtml/htmloption.c index 877eef2ebc1..4701c577de5 100644 --- a/reactos/dll/win32/mshtml/htmloption.c +++ b/reactos/dll/win32/mshtml/htmloption.c @@ -187,7 +187,7 @@ static HRESULT WINAPI HTMLOptionElement_put_text(IHTMLOptionElement *iface, BSTR TRACE("(%p)->(%s)\n", This, debugstr_w(v)); - if(!This->element.node.doc->basedoc.nsdoc) { + if(!This->element.node.doc->nsdoc) { WARN("NULL nsdoc\n"); return E_UNEXPECTED; } @@ -210,7 +210,7 @@ static HRESULT WINAPI HTMLOptionElement_put_text(IHTMLOptionElement *iface, BSTR } nsAString_Init(&text_str, v); - nsres = nsIDOMHTMLDocument_CreateTextNode(This->element.node.doc->basedoc.nsdoc, &text_str, &text_node); + nsres = nsIDOMHTMLDocument_CreateTextNode(This->element.node.doc->nsdoc, &text_str, &text_node); nsAString_Finish(&text_str); if(NS_FAILED(nsres)) { ERR("CreateTextNode failed: %08x\n", nsres); @@ -339,7 +339,7 @@ static dispex_static_data_t HTMLOptionElement_dispex = { HTMLOptionElement_iface_tids }; -HTMLElement *HTMLOptionElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLOptionElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLOptionElement *ret = heap_alloc_zero(sizeof(HTMLOptionElement)); nsresult nsres; @@ -347,7 +347,7 @@ HTMLElement *HTMLOptionElement_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLOptionElementVtbl = &HTMLOptionElementVtbl; ret->element.node.vtbl = &HTMLOptionElementImplVtbl; - HTMLElement_Init(&ret->element, &HTMLOptionElement_dispex); + HTMLElement_Init(&ret->element, doc, nselem, &HTMLOptionElement_dispex); nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLOptionElement, (void**)&ret->nsoption); if(NS_FAILED(nsres)) @@ -448,9 +448,7 @@ static HRESULT WINAPI HTMLOptionElementFactory_create(IHTMLOptionElementFactory IHTMLOptionElement **optelem) { HTMLOptionElementFactory *This = HTMLOPTFACTORY_THIS(iface); - nsIDOMElement *nselem; - nsAString option_str; - nsresult nsres; + nsIDOMHTMLElement *nselem; HRESULT hres; static const PRUnichar optionW[] = {'O','P','T','I','O','N',0}; @@ -458,24 +456,20 @@ static HRESULT WINAPI HTMLOptionElementFactory_create(IHTMLOptionElementFactory TRACE("(%p)->(%s %s %s %s %p)\n", This, debugstr_variant(&text), debugstr_variant(&value), debugstr_variant(&defaultselected), debugstr_variant(&selected), optelem); - if(!This->window || !This->window->doc || !This->window->doc->basedoc.nsdoc) { - WARN("NULL nsdoc\n"); + if(!This->window || !This->window->doc) { + WARN("NULL doc\n"); return E_UNEXPECTED; } *optelem = NULL; - nsAString_Init(&option_str, optionW); - nsres = nsIDOMHTMLDocument_CreateElement(This->window->doc->basedoc.nsdoc, &option_str, &nselem); - nsAString_Finish(&option_str); - if(NS_FAILED(nsres)) { - ERR("CreateElement failed: %08x\n", nsres); - return E_FAIL; - } + hres = create_nselem(This->window->doc, optionW, &nselem); + if(FAILED(hres)) + return hres; hres = IHTMLDOMNode_QueryInterface(HTMLDOMNODE(get_node(This->window->doc, (nsIDOMNode*)nselem, TRUE)), &IID_IHTMLOptionElement, (void**)optelem); - nsIDOMElement_Release(nselem); + nsIDOMHTMLElement_Release(nselem); if(V_VT(&text) == VT_BSTR) IHTMLOptionElement_put_text(*optelem, V_BSTR(&text)); diff --git a/reactos/dll/win32/mshtml/htmlscript.c b/reactos/dll/win32/mshtml/htmlscript.c index 5c0c6009962..a038c556d94 100644 --- a/reactos/dll/win32/mshtml/htmlscript.c +++ b/reactos/dll/win32/mshtml/htmlscript.c @@ -306,7 +306,7 @@ static const NodeImplVtbl HTMLScriptElementImplVtbl = { HTMLScriptElement_destructor }; -HTMLElement *HTMLScriptElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLScriptElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLScriptElement *ret = heap_alloc_zero(sizeof(HTMLScriptElement)); nsresult nsres; @@ -314,7 +314,7 @@ HTMLElement *HTMLScriptElement_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLScriptElementVtbl = &HTMLScriptElementVtbl; ret->element.node.vtbl = &HTMLScriptElementImplVtbl; - HTMLElement_Init(&ret->element, NULL); + HTMLElement_Init(&ret->element, doc, nselem, NULL); nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLScriptElement, (void**)&ret->nsscript); if(NS_FAILED(nsres)) diff --git a/reactos/dll/win32/mshtml/htmlselect.c b/reactos/dll/win32/mshtml/htmlselect.c index f3dd75797fa..f9b71826600 100644 --- a/reactos/dll/win32/mshtml/htmlselect.c +++ b/reactos/dll/win32/mshtml/htmlselect.c @@ -481,6 +481,7 @@ static const NodeImplVtbl HTMLSelectElementImplVtbl = { HTMLSelectElement_QI, HTMLSelectElement_destructor, NULL, + NULL, HTMLSelectElementImpl_put_disabled, HTMLSelectElementImpl_get_disabled }; @@ -502,7 +503,7 @@ static dispex_static_data_t HTMLSelectElement_dispex = { HTMLSelectElement_tids }; -HTMLElement *HTMLSelectElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLSelectElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLSelectElement *ret = heap_alloc_zero(sizeof(HTMLSelectElement)); nsresult nsres; @@ -510,7 +511,7 @@ HTMLElement *HTMLSelectElement_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLSelectElementVtbl = &HTMLSelectElementVtbl; ret->element.node.vtbl = &HTMLSelectElementImplVtbl; - HTMLElement_Init(&ret->element, &HTMLSelectElement_dispex); + HTMLElement_Init(&ret->element, doc, nselem, &HTMLSelectElement_dispex); nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLSelectElement, (void**)&ret->nsselect); diff --git a/reactos/dll/win32/mshtml/htmltable.c b/reactos/dll/win32/mshtml/htmltable.c index fabc3808481..76997486117 100644 --- a/reactos/dll/win32/mshtml/htmltable.c +++ b/reactos/dll/win32/mshtml/htmltable.c @@ -574,7 +574,7 @@ static dispex_static_data_t HTMLTable_dispex = { HTMLTable_iface_tids }; -HTMLElement *HTMLTable_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLTable_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLTable *ret = heap_alloc_zero(sizeof(HTMLTable)); nsresult nsres; @@ -582,7 +582,7 @@ HTMLElement *HTMLTable_Create(nsIDOMHTMLElement *nselem) ret->element.node.vtbl = &HTMLTableImplVtbl; ret->lpHTMLTableVtbl = &HTMLTableVtbl; - HTMLElement_Init(&ret->element, &HTMLTable_dispex); + HTMLElement_Init(&ret->element, doc, nselem, &HTMLTable_dispex); ConnectionPoint_Init(&ret->cp, &ret->element.cp_container, &DIID_HTMLTableEvents); diff --git a/reactos/dll/win32/mshtml/htmltablerow.c b/reactos/dll/win32/mshtml/htmltablerow.c index aaae2eb502f..862ed75318c 100644 --- a/reactos/dll/win32/mshtml/htmltablerow.c +++ b/reactos/dll/win32/mshtml/htmltablerow.c @@ -317,7 +317,7 @@ static dispex_static_data_t HTMLTableRow_dispex = { HTMLTableRow_iface_tids }; -HTMLElement *HTMLTableRow_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLTableRow_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLTableRow *ret = heap_alloc_zero(sizeof(HTMLTableRow)); nsresult nsres; @@ -325,7 +325,7 @@ HTMLElement *HTMLTableRow_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLTableRowVtbl = &HTMLTableRowVtbl; ret->element.node.vtbl = &HTMLTableRowImplVtbl; - HTMLElement_Init(&ret->element, &HTMLTableRow_dispex); + HTMLElement_Init(&ret->element, doc, nselem, &HTMLTableRow_dispex); nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLTableRowElement, (void**)&ret->nsrow); if(NS_FAILED(nsres)) diff --git a/reactos/dll/win32/mshtml/htmltextarea.c b/reactos/dll/win32/mshtml/htmltextarea.c index 2ff5c25a677..0a07379871b 100644 --- a/reactos/dll/win32/mshtml/htmltextarea.c +++ b/reactos/dll/win32/mshtml/htmltextarea.c @@ -406,11 +406,12 @@ static const NodeImplVtbl HTMLTextAreaElementImplVtbl = { HTMLTextAreaElement_QI, HTMLTextAreaElement_destructor, NULL, + NULL, HTMLTextAreaElementImpl_put_disabled, HTMLTextAreaElementImpl_get_disabled }; -HTMLElement *HTMLTextAreaElement_Create(nsIDOMHTMLElement *nselem) +HTMLElement *HTMLTextAreaElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLTextAreaElement *ret = heap_alloc_zero(sizeof(HTMLTextAreaElement)); nsresult nsres; @@ -418,7 +419,7 @@ HTMLElement *HTMLTextAreaElement_Create(nsIDOMHTMLElement *nselem) ret->lpHTMLTextAreaElementVtbl = &HTMLTextAreaElementVtbl; ret->element.node.vtbl = &HTMLTextAreaElementImplVtbl; - HTMLElement_Init(&ret->element, NULL); + HTMLElement_Init(&ret->element, doc, nselem, NULL); nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLTextAreaElement, (void**)&ret->nstextarea); diff --git a/reactos/dll/win32/mshtml/htmltextcont.c b/reactos/dll/win32/mshtml/htmltextcont.c index 69f1ef4c3a5..35fa01b1f83 100644 --- a/reactos/dll/win32/mshtml/htmltextcont.c +++ b/reactos/dll/win32/mshtml/htmltextcont.c @@ -182,11 +182,12 @@ static const IHTMLTextContainerVtbl HTMLTextContainerVtbl = { HTMLTextContainer_get_onscroll }; -void HTMLTextContainer_Init(HTMLTextContainer *This, dispex_static_data_t *dispex_data) +void HTMLTextContainer_Init(HTMLTextContainer *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, + dispex_static_data_t *dispex_data) { This->lpHTMLTextContainerVtbl = &HTMLTextContainerVtbl; - HTMLElement_Init(&This->element, dispex_data); + HTMLElement_Init(&This->element, doc, nselem, dispex_data); ConnectionPoint_Init(&This->cp, &This->element.cp_container, &DIID_HTMLTextContainerEvents); } diff --git a/reactos/dll/win32/mshtml/htmlwindow.c b/reactos/dll/win32/mshtml/htmlwindow.c index f8d62a37a02..9f3b3e7f0c0 100644 --- a/reactos/dll/win32/mshtml/htmlwindow.c +++ b/reactos/dll/win32/mshtml/htmlwindow.c @@ -36,15 +36,68 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); static struct list window_list = LIST_INIT(window_list); -void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node) +static void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node) { if(window->doc) { + abort_document_bindings(window->doc); window->doc->basedoc.window = NULL; htmldoc_release(&window->doc->basedoc); } window->doc = doc_node; if(doc_node) htmldoc_addref(&doc_node->basedoc); + + if(window->doc_obj && window->doc_obj->basedoc.window == window) { + if(window->doc_obj->basedoc.doc_node) + htmldoc_release(&window->doc_obj->basedoc.doc_node->basedoc); + window->doc_obj->basedoc.doc_node = doc_node; + if(doc_node) + htmldoc_addref(&doc_node->basedoc); + } +} + +nsIDOMWindow *get_nsdoc_window(nsIDOMDocument *nsdoc) +{ + nsIDOMDocumentView *nsdocview; + nsIDOMAbstractView *nsview; + nsIDOMWindow *nswindow; + nsresult nsres; + + nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentView, (void**)&nsdocview); + nsIDOMDocument_Release(nsdoc); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMDocumentView iface: %08x\n", nsres); + return NULL; + } + + nsres = nsIDOMDocumentView_GetDefaultView(nsdocview, &nsview); + nsIDOMDocumentView_Release(nsview); + if(NS_FAILED(nsres)) { + ERR("GetDefaultView failed: %08x\n", nsres); + return NULL; + } + + nsres = nsIDOMAbstractView_QueryInterface(nsview, &IID_nsIDOMWindow, (void**)&nswindow); + nsIDOMAbstractView_Release(nsview); + if(NS_FAILED(nsres)) { + ERR("Coult not get nsIDOMWindow iface: %08x\n", nsres); + return NULL; + } + + return nswindow; +} + +static void release_children(HTMLWindow *This) +{ + HTMLWindow *child; + + while(!list_empty(&This->children)) { + child = LIST_ENTRY(list_tail(&This->children), HTMLWindow, sibling_entry); + + list_remove(&child->sibling_entry); + child->parent = NULL; + IHTMLWindow2_Release(HTMLWINDOW2(child)); + } } #define HTMLWINDOW2_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow2, iface) @@ -71,7 +124,7 @@ static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID rii TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv); *ppv = HTMLWINDOW2(This); }else if(IsEqualGUID(&IID_IHTMLWindow3, riid)) { - TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv); + TRACE("(%p)->(IID_IHTMLWindow3 %p)\n", This, ppv); *ppv = HTMLWINDOW3(This); }else if(dispex_query_interface(&This->dispex, riid, ppv)) { return *ppv ? S_OK : E_NOINTERFACE; @@ -106,13 +159,22 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface) if(!ref) { DWORD i; + remove_target_tasks(This->task_magic); + set_window_bscallback(This, NULL); + set_current_mon(This, NULL); window_set_docnode(This, NULL); + release_children(This); if(This->option_factory) { This->option_factory->window = NULL; IHTMLOptionElementFactory_Release(HTMLOPTFACTORY(This->option_factory)); } + if(This->image_factory) { + This->image_factory->window = NULL; + IHTMLImageElementFactory_Release(HTMLIMGFACTORY(This->image_factory)); + } + if(This->location) { This->location->window = NULL; IHTMLLocation_Release(HTMLLOCATION(This->location)); @@ -122,8 +184,11 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface) release_event_target(This->event_target); for(i=0; i < This->global_prop_cnt; i++) heap_free(This->global_props[i].name); + + This->window_ref->window = NULL; + windowref_release(This->window_ref); + heap_free(This->global_props); - heap_free(This->event_vector); release_script_hosts(This); list_remove(&This->entry); release_dispex(&This->dispex); @@ -177,8 +242,27 @@ static HRESULT WINAPI HTMLWindow2_item(IHTMLWindow2 *iface, VARIANT *pvarIndex, static HRESULT WINAPI HTMLWindow2_get_length(IHTMLWindow2 *iface, LONG *p) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsIDOMWindowCollection *nscollection; + PRUint32 length; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMWindow_GetFrames(This->nswindow, &nscollection); + if(NS_FAILED(nsres)) { + ERR("GetFrames failed: %08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMWindowCollection_GetLength(nscollection, &length); + nsIDOMWindowCollection_Release(nscollection); + if(NS_FAILED(nsres)) { + ERR("GetLength failed: %08x\n", nsres); + return E_FAIL; + } + + *p = length; + return S_OK; } static HRESULT WINAPI HTMLWindow2_get_frames(IHTMLWindow2 *iface, IHTMLFramesCollection2 **p) @@ -373,8 +457,16 @@ static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message, static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageElementFactory **p) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->image_factory) + This->image_factory = HTMLImageElementFactory_Create(This); + + *p = HTMLIMGFACTORY(This->image_factory); + IHTMLImageElementFactory_AddRef(*p); + + return S_OK; } static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p) @@ -438,15 +530,49 @@ static HRESULT WINAPI HTMLWindow2_get_navigator(IHTMLWindow2 *iface, IOmNavigato static HRESULT WINAPI HTMLWindow2_put_name(IHTMLWindow2 *iface, BSTR v) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString name_str; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_Init(&name_str, v); + nsres = nsIDOMWindow_SetName(This->nswindow, &name_str); + nsAString_Finish(&name_str); + if(NS_FAILED(nsres)) + ERR("SetName failed: %08x\n", nsres); + + return S_OK; } static HRESULT WINAPI HTMLWindow2_get_name(IHTMLWindow2 *iface, BSTR *p) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString name_str; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&name_str, NULL); + nsres = nsIDOMWindow_GetName(This->nswindow, &name_str); + if(NS_SUCCEEDED(nsres)) { + const PRUnichar *name; + + nsAString_GetData(&name_str, &name); + if(*name) { + *p = SysAllocString(name); + hres = *p ? S_OK : E_OUTOFMEMORY; + }else { + *p = NULL; + hres = S_OK; + } + }else { + ERR("GetName failed: %08x\n", nsres); + hres = E_FAIL; + } + nsAString_Finish(&name_str); + + return hres; } static HRESULT WINAPI HTMLWindow2_get_parent(IHTMLWindow2 *iface, IHTMLWindow2 **p) @@ -879,8 +1005,7 @@ static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fla VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { HTMLWindow *This = HTMLWINDOW2_THIS(iface); - IDispatchEx *dispex; - IDispatch *disp; + global_prop_t *prop; DWORD idx; HRESULT hres; @@ -888,24 +1013,51 @@ static HRESULT HTMLWindow_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD fla if(idx >= This->global_prop_cnt) return DISP_E_MEMBERNOTFOUND; - disp = get_script_disp(This->global_props[idx].script_host); - if(!disp) - return E_UNEXPECTED; + prop = This->global_props+idx; - hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); - if(SUCCEEDED(hres)) { - TRACE("%s >>>\n", debugstr_w(This->global_props[idx].name)); - hres = IDispatchEx_InvokeEx(dispex, This->global_props[idx].id, lcid, flags, params, res, ei, caller); - if(hres == S_OK) - TRACE("%s <<<\n", debugstr_w(This->global_props[idx].name)); - else - WARN("%s <<< %08x\n", debugstr_w(This->global_props[idx].name), hres); - IDispatchEx_Release(dispex); - }else { - FIXME("No IDispatchEx\n"); + switch(prop->type) { + case GLOBAL_SCRIPTVAR: { + IDispatchEx *dispex; + IDispatch *disp; + + disp = get_script_disp(prop->script_host); + if(!disp) + return E_UNEXPECTED; + + hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex); + if(SUCCEEDED(hres)) { + TRACE("%s >>>\n", debugstr_w(prop->name)); + hres = IDispatchEx_InvokeEx(dispex, prop->id, lcid, flags, params, res, ei, caller); + if(hres == S_OK) + TRACE("%s <<<\n", debugstr_w(prop->name)); + else + WARN("%s <<< %08x\n", debugstr_w(prop->name), hres); + IDispatchEx_Release(dispex); + }else { + FIXME("No IDispatchEx\n"); + } + IDispatch_Release(disp); + break; + } + case GLOBAL_ELEMENTVAR: { + IHTMLElement *elem; + + hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), prop->name, &elem); + if(FAILED(hres)) + return hres; + + if(!elem) + return DISP_E_MEMBERNOTFOUND; + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)elem; + break; + } + default: + ERR("invalid type %d\n", prop->type); + hres = DISP_E_MEMBERNOTFOUND; } - IDispatch_Release(disp); return hres; } @@ -1273,12 +1425,45 @@ static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMembe pVarResult, pExcepInfo, puArgErr); } +static global_prop_t *alloc_global_prop(HTMLWindow *This, global_prop_type_t type, BSTR name) +{ + if(This->global_prop_cnt == This->global_prop_size) { + global_prop_t *new_props; + DWORD new_size; + + if(This->global_props) { + new_size = This->global_prop_size*2; + new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t)); + }else { + new_size = 16; + new_props = heap_alloc(new_size*sizeof(global_prop_t)); + } + if(!new_props) + return NULL; + This->global_props = new_props; + This->global_prop_size = new_size; + } + + This->global_props[This->global_prop_cnt].name = heap_strdupW(name); + if(!This->global_props[This->global_prop_cnt].name) + return NULL; + + This->global_props[This->global_prop_cnt].type = type; + return This->global_props + This->global_prop_cnt++; +} + +static inline DWORD prop_to_dispid(HTMLWindow *This, global_prop_t *prop) +{ + return MSHTML_DISPID_CUSTOM_MIN + (prop-This->global_props); +} + static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid) { HTMLWindow *This = DISPEX_THIS(iface); ScriptHost *script_host; DISPID id; DWORD i; + HRESULT hres; TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid); @@ -1291,35 +1476,41 @@ static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, } if(find_global_prop(This, bstrName, grfdex, &script_host, &id)) { - if(This->global_prop_cnt == This->global_prop_size) { - global_prop_t *new_props; - DWORD new_size; + global_prop_t *prop; - if(This->global_props) { - new_size = This->global_prop_size*2; - new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t)); - }else { - new_size = 16; - new_props = heap_alloc(new_size*sizeof(global_prop_t)); - } - if(!new_props) - return E_OUTOFMEMORY; - This->global_props = new_props; - This->global_prop_size = new_size; - } - - This->global_props[This->global_prop_cnt].name = heap_strdupW(bstrName); - if(!This->global_props[This->global_prop_cnt].name) + prop = alloc_global_prop(This, GLOBAL_SCRIPTVAR, bstrName); + if(!prop) return E_OUTOFMEMORY; - This->global_props[This->global_prop_cnt].script_host = script_host; - This->global_props[This->global_prop_cnt].id = id; + prop->script_host = script_host; + prop->id = id; - *pid = MSHTML_DISPID_CUSTOM_MIN + (This->global_prop_cnt++); + *pid = prop_to_dispid(This, prop); return S_OK; } - return IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid); + hres = IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid); + if(hres != DISP_E_UNKNOWNNAME) + return hres; + + if(This->doc) { + global_prop_t *prop; + IHTMLElement *elem; + + hres = IHTMLDocument3_getElementById(HTMLDOC3(&This->doc->basedoc), bstrName, &elem); + if(SUCCEEDED(hres) && elem) { + IHTMLElement_Release(elem); + + prop = alloc_global_prop(This, GLOBAL_ELEMENTVAR, bstrName); + if(!prop) + return E_OUTOFMEMORY; + + *pid = prop_to_dispid(This, prop); + return S_OK; + } + } + + return DISP_E_UNKNOWNNAME; } static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, @@ -1426,7 +1617,7 @@ static dispex_static_data_t HTMLWindow_dispex = { HTMLWindow_iface_tids }; -HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTMLWindow **ret) +HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTMLWindow *parent, HTMLWindow **ret) { HTMLWindow *window; @@ -1434,12 +1625,21 @@ HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTML if(!window) return E_OUTOFMEMORY; + window->window_ref = heap_alloc(sizeof(windowref_t)); + if(!window->window_ref) { + heap_free(window); + return E_OUTOFMEMORY; + } + window->lpHTMLWindow2Vtbl = &HTMLWindow2Vtbl; window->lpHTMLWindow3Vtbl = &HTMLWindow3Vtbl; window->lpIDispatchExVtbl = &WindowDispExVtbl; window->ref = 1; window->doc_obj = doc_obj; + window->window_ref->window = window; + window->window_ref->ref = 1; + init_dispex(&window->dispex, (IUnknown*)HTMLWINDOW2(window), &HTMLWindow_dispex); if(nswindow) { @@ -1447,15 +1647,62 @@ HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTML window->nswindow = nswindow; } - window->scriptmode = SCRIPTMODE_GECKO; + window->scriptmode = parent ? parent->scriptmode : SCRIPTMODE_GECKO; + window->readystate = READYSTATE_UNINITIALIZED; list_init(&window->script_hosts); + window->task_magic = get_task_target_magic(); + update_window_doc(window); + + list_init(&window->children); list_add_head(&window_list, &window->entry); + if(parent) { + IHTMLWindow2_AddRef(HTMLWINDOW2(window)); + + window->parent = parent; + list_add_tail(&parent->children, &window->sibling_entry); + } + *ret = window; return S_OK; } +void update_window_doc(HTMLWindow *window) +{ + nsIDOMHTMLDocument *nshtmldoc; + nsIDOMDocument *nsdoc; + nsresult nsres; + + nsres = nsIDOMWindow_GetDocument(window->nswindow, &nsdoc); + if(NS_FAILED(nsres) || !nsdoc) { + ERR("GetDocument failed: %08x\n", nsres); + return; + } + + nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc); + nsIDOMDocument_Release(nsdoc); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres); + return; + } + + if(!window->doc || window->doc->nsdoc != nshtmldoc) { + HTMLDocumentNode *doc; + HRESULT hres; + + hres = create_doc_from_nsdoc(nshtmldoc, window->doc_obj, window, &doc); + if(SUCCEEDED(hres)) { + window_set_docnode(window, doc); + htmldoc_release(&doc->basedoc); + }else { + ERR("create_doc_from_nsdoc failed: %08x\n", hres); + } + } + + nsIDOMHTMLDocument_Release(nshtmldoc); +} + HTMLWindow *nswindow_to_window(const nsIDOMWindow *nswindow) { HTMLWindow *iter; diff --git a/reactos/dll/win32/mshtml/main.c b/reactos/dll/win32/mshtml/main.c index 548c50ca966..6a358e5492a 100644 --- a/reactos/dll/win32/mshtml/main.c +++ b/reactos/dll/win32/mshtml/main.c @@ -391,9 +391,6 @@ static HRESULT register_server(BOOL do_register) if(FAILED(hres)) ERR("typelib registration failed: %08x\n", hres); - if(do_register && SUCCEEDED(hres)) - load_gecko(TRUE); - return hres; } @@ -405,7 +402,13 @@ static HRESULT register_server(BOOL do_register) */ HRESULT WINAPI DllRegisterServer(void) { - return register_server(TRUE); + HRESULT hres; + + hres = register_server(TRUE); + if(SUCCEEDED(hres)) + load_gecko(FALSE); + + return hres; } /*********************************************************************** diff --git a/reactos/dll/win32/mshtml/mshtml.inf b/reactos/dll/win32/mshtml/mshtml.inf index f2882362054..f493a3b5df9 100644 --- a/reactos/dll/win32/mshtml/mshtml.inf +++ b/reactos/dll/win32/mshtml/mshtml.inf @@ -3,7 +3,7 @@ Signature="$CHICAGO$" [RegisterDll] -AddReg=Classes.Reg, Protocols.Reg, IE.Reg, FileAssoc.Reg +AddReg=Classes.Reg, Protocols.Reg, IE.Reg, FileAssoc.Reg, WineGecko.Reg [UnregisterDll] @@ -270,8 +270,18 @@ HKLM,"Software\Microsoft\Internet Explorer\AboutURLs","mozilla",2,"res://mshtml. HKLM,"Software\Microsoft\Internet Explorer\Default Behaviors","VML",, "CLSID:10072CEC-8CC1-11D1-986E-00A0C955B42E" HKLM,"Software\Microsoft\Internet Explorer\Default Behaviors","TIME",, "CLSID:476C391C-3E0D-11D2-B948-00C04FA32195" + +[WineGecko.Reg] +HKCU,Software\Wine\MSHTML,"GeckoUrl",,"http://source.winehq.org/winegecko.php" + + [FileAssoc.Reg] +;; AVI +HKCR,"MIME\Database\Content Type\video/avi","CLSID",,"{CD3AFA88-B84F-48F0-9393-7EDC34128127}" +HKCR,"MIME\Database\Content Type\video/avi","Extension",,".avi" +HKCR,".avi","Content Type",,"video/avi" + ;; BMP HKCR,"MIME\Database\Content Type\image/bmp","Extension",,".bmp" HKCR,"MIME\Database\Content Type\image/bmp","Image Filter CLSID",,"%CLSID_IImageDecodeFilter%" @@ -285,6 +295,14 @@ HKCR,".css","Content Type",,"text/css" ;; DIB HKCR,".dib","Content Type",,"image/bmp" +;; DLL +HKCR,".dll","Content Type",,"application/x-msdownload" +HKCR,".dll",,,"dllfile" + +;; EXE +HKCR,".exe","Content Type",,"application/x-msdownload" +HKCR,".exe",,,"exefile" + ;; GIF HKCR,"MIME\Database\Content Type\image/gif","CLSID",,"%CLSID_HTMLDocument%" HKCR,"MIME\Database\Content Type\image/gif","Extension",,".gif" @@ -300,6 +318,10 @@ HKCR,"giffile\shell\open\ddeexec",,,"""file:%%1"",,-1,,,,," HKCR,"giffile\shell\open\ddeexec\Topic",,,"WWW_OpenURL" ;; HKCR,"giffile\DefaultIcon",,,"%IEXPLORE%,9" +;; GZIP +HKCR,"MIME\Database\Content Type\application/x-gzip","Extension",,".gz" +HKCR,".gz","Content Type",,"application/x-gzip" + ;; HTC HKCR,"MIME\Database\Content Type\text/x-component","CLSID",,"%CLSID_CHtmlComponentConstructor%" HKCR,"MIME\Database\Content Type\text/x-component","Extension",,".htc" @@ -321,6 +343,10 @@ HKCR,"htmlfile\CLSID",,,"%CLSID_HTMLDocument%" HKCR,"htmlfile_FullWindowEmbed",,,"HTML Plugin Document" HKCR,"htmlfile_FullWindowEmbed\BrowseInPlace",,,"" HKCR,"htmlfile_FullWindowEmbed\CLSID",,,"%CLSID_HTMLPluginDocument%" +HKCR,".htm",,,"htmlfile" +HKCR,".htm","Content Type",,"text/html" +HKCR,".html",,,"htmlfile" +HKCR,".html","Content Type",,"text/html" ;; ICO HKCR,"MIME\Database\Content Type\image/x-icon","CLSID",,"%CLSID_HTMLDocument%" @@ -375,6 +401,18 @@ HKCR,"mhtmlfile",,,"MHTML Document" HKCR,"mhtmlfile\BrowseInPlace",,,"" HKCR,"mhtmlfile\CLSID",,,"%CLSID_MHTMLDocument%" +;; MPEG +HKCR,"MIME\Database\Content Type\audio/mpeg","CLSID",,"{CD3AFA76-B84F-48F0-9393-7EDC34128127}" +HKCR,"MIME\Database\Content Type\audio/mpeg","Extension",,".mp3" +HKCR,"MIME\Database\Content Type\audio/mpg","CLSID",,"{CD3AFA76-B84F-48F0-9393-7EDC34128127}" +HKCR,"MIME\Database\Content Type\audio/mpg","Extension",,".mp3" +HKCR,"MIME\Database\Content Type\video/mpeg","CLSID",,"{CD3AFA89-B84F-48F0-9393-7EDC34128127}" +HKCR,"MIME\Database\Content Type\video/mpeg","Extension",,".mpeg" +HKCR,".mp3","Content Type",,"audio/mpeg" +HKCR,".mpe","Content Type",,"video/mpeg" +HKCR,".mpeg","Content Type",,"video/mpeg" +HKCR,".mpg","Content Type",,"video/mpeg" + ;; PJPG HKCR,"MIME\Database\Content Type\image/pjpeg","CLSID",,"%CLSID_HTMLDocument%" HKCR,"MIME\Database\Content Type\image/pjpeg","Extension",,".jpg" @@ -403,12 +441,37 @@ HKCR,"pngfile\shell\open\ddeexec",,,"""file:%%1"",,-1,,,,," HKCR,"pngfile\shell\open\ddeexec\Topic",,,"WWW_OpenURL" ;; HKCR,"pngfile\DefaultIcon",,,"%IEXPLORE%,9" +;; PS +HKCR,"MIME\Database\Content Type\application/postscript","Extension",,".ps" +HKCR,".ai","Content Type",,"application/postscript" +HKCR,".eps","Content Type",,"application/postscript" +HKCR,".ps","Content Type",,"application/postscript" + +;; TAR +HKCR,"MIME\Database\Content Type\application/x-tar","Extension",,".tar" +HKCR,".tar","Content Type",,"application/x-tar" + +;; TGZ +HKCR,"MIME\Database\Content Type\application/x-compressed","Extension",,".tgz" +HKCR,".tgz","Content Type",,"application/x-compressed" + +;; TIFF +HKCR,"MIME\Database\Content Type\image/tiff","Extension",,".tiff" +HKCR,".tif","Content Type",,"image/tiff" +HKCR,".tiff","Content Type",,"image/tiff" + ;; TXT HKCR,"MIME\Database\Content Type\text/plain","CLSID",,"%CLSID_HTMLDocument%" HKCR,"MIME\Database\Content Type\text/plain","Extension",,".txt" HKCR,"MIME\Database\Content Type\text/plain","Encoding",1,07,00,00,00 +HKCR,".txt",,,"txtfile" HKCR,".txt","Content Type",,"text/plain" +;; WAV +HKCR,"MIME\Database\Content Type\audio/wav","CLSID",,"{CD3AFA7B-B84F-48F0-9393-7EDC34128127}" +HKCR,"MIME\Database\Content Type\audio/wav","Extension",,".wav" +HKCR,".wav","Content Type",,"audio/wav" + ;; XBM HKCR,"MIME\Database\Content Type\image/xbm","Extension",,".xbm" HKCR,"MIME\Database\Content Type\image/x-xbitmap","CLSID",,"%CLSID_HTMLDocument%" @@ -420,3 +483,19 @@ HKCR,"xbmfile\shell\open\ddeexec",,,"""file:%%1"",,-1,,,,," ;; HKCR,"xbmfile\shell\open\ddeexec\Application",,,"IExplore" HKCR,"xbmfile\shell\open\ddeexec\Topic",,,"WWW_OpenURL" ;; HKCR,"xbmfile\DefaultIcon",,,"%IEXPLORE%,9" + +;; XML +HKCR,"MIME\Database\Content Type\application/xml","CLSID",,"{48123BC4-99D9-11D1-A6B3-00C04FD91555}" +HKCR,"MIME\Database\Content Type\application/xml","Extension",,".xml" +HKCR,"MIME\Database\Content Type\application/xml","Encoding",1,08,00,00,00 +HKCR,"MIME\Database\Content Type\text/xml","CLSID",,"{48123BC4-99D9-11D1-A6B3-00C04FD91555}" +HKCR,"MIME\Database\Content Type\text/xml","Extension",,".xml" +HKCR,"MIME\Database\Content Type\text/xml","Encoding",1,08,00,00,00 +HKCR,".xml",,,"xmlfile" +HKCR,".xml","Content Type",,"text/xml" +HKCR,".xsl",,,"xslfile" +HKCR,".xsl","Content Type",,"text/xml" + +;; ZIP +HKCR,"MIME\Database\Content Type\application/x-zip-compressed","Extension",,".zip" +HKCR,".zip","Content Type",,"application/x-zip-compressed" diff --git a/reactos/dll/win32/mshtml/mshtml.rbuild b/reactos/dll/win32/mshtml/mshtml.rbuild index 240d54817b3..d7f11ac1d00 100644 --- a/reactos/dll/win32/mshtml/mshtml.rbuild +++ b/reactos/dll/win32/mshtml/mshtml.rbuild @@ -29,6 +29,7 @@ htmlelem3.c htmlelemcol.c htmlevent.c + htmlframebase.c htmlgeneric.c htmliframe.c htmlimg.c diff --git a/reactos/dll/win32/mshtml/mshtml_private.h b/reactos/dll/win32/mshtml/mshtml_private.h index 18719fe89b9..43601ae9ddf 100644 --- a/reactos/dll/win32/mshtml/mshtml_private.h +++ b/reactos/dll/win32/mshtml/mshtml_private.h @@ -101,8 +101,10 @@ typedef enum { IHTMLElement4_tid, IHTMLElementCollection_tid, IHTMLEventObj_tid, + IHTMLFrameBase_tid, IHTMLFrameBase2_tid, IHTMLGenericElement_tid, + IHTMLImageElementFactory_tid, IHTMLImgElement_tid, IHTMLInputElement_tid, IHTMLLocation_tid, @@ -155,9 +157,9 @@ void release_dispex(DispatchEx*); BOOL dispex_query_interface(DispatchEx*,REFIID,void**); HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**); -typedef struct HTMLWindow HTMLWindow; typedef struct HTMLDocumentNode HTMLDocumentNode; typedef struct HTMLDocumentObj HTMLDocumentObj; +typedef struct HTMLFrameBase HTMLFrameBase; typedef enum { SCRIPTMODE_GECKO, @@ -166,7 +168,13 @@ typedef enum { typedef struct ScriptHost ScriptHost; +typedef enum { + GLOBAL_SCRIPTVAR, + GLOBAL_ELEMENTVAR +} global_prop_type_t; + typedef struct { + global_prop_type_t type; WCHAR *name; ScriptHost *script_host; DISPID id; @@ -180,6 +188,15 @@ typedef struct { HTMLWindow *window; } HTMLOptionElementFactory; +typedef struct { + DispatchEx dispex; + const IHTMLImageElementFactoryVtbl *lpHTMLImageElementFactoryVtbl; + + LONG ref; + + HTMLWindow *window; +} HTMLImageElementFactory; + struct HTMLLocation { DispatchEx dispex; const IHTMLLocationVtbl *lpHTMLLocationVtbl; @@ -189,6 +206,11 @@ struct HTMLLocation { HTMLWindow *window; }; +typedef struct { + HTMLWindow *window; + LONG ref; +} windowref_t; + struct HTMLWindow { DispatchEx dispex; const IHTMLWindow2Vtbl *lpHTMLWindow2Vtbl; @@ -197,24 +219,36 @@ struct HTMLWindow { LONG ref; + windowref_t *window_ref; + LONG task_magic; + HTMLDocumentNode *doc; HTMLDocumentObj *doc_obj; nsIDOMWindow *nswindow; + HTMLWindow *parent; + HTMLFrameBase *frame_element; + READYSTATE readystate; + + nsChannelBSC *bscallback; + IMoniker *mon; + LPOLESTR url; event_target_t *event_target; IHTMLEventObj *event; - BOOL *event_vector; SCRIPTMODE scriptmode; struct list script_hosts; HTMLOptionElementFactory *option_factory; + HTMLImageElementFactory *image_factory; HTMLLocation *location; global_prop_t *global_props; DWORD global_prop_cnt; DWORD global_prop_size; + struct list children; + struct list sibling_entry; struct list entry; }; @@ -253,6 +287,7 @@ struct HTMLDocument { const IHTMLDocument3Vtbl *lpHTMLDocument3Vtbl; const IHTMLDocument4Vtbl *lpHTMLDocument4Vtbl; const IHTMLDocument5Vtbl *lpHTMLDocument5Vtbl; + const IHTMLDocument6Vtbl *lpHTMLDocument6Vtbl; const IPersistMonikerVtbl *lpPersistMonikerVtbl; const IPersistFileVtbl *lpPersistFileVtbl; const IPersistHistoryVtbl *lpPersistHistoryVtbl; @@ -278,7 +313,8 @@ struct HTMLDocument { HTMLDocumentNode *doc_node; HTMLWindow *window; - nsIDOMHTMLDocument *nsdoc; + + LONG task_magic; ConnectionPointContainer cp_container; ConnectionPoint cp_htmldocevents; @@ -331,30 +367,11 @@ struct HTMLDocumentObj { BOOL focus; USERMODE usermode; - READYSTATE readystate; LPWSTR mime; DWORD update; - - /* FIXME: probably should be in document node object */ - nsChannelBSC *bscallback; - IMoniker *mon; - LPOLESTR url; - struct list bindings; }; -typedef struct { - const nsIDOMEventListenerVtbl *lpDOMEventListenerVtbl; - NSContainer *This; -} nsEventListener; - -typedef struct _mutation_queue_t { - DWORD type; - nsISupports *nsiface; - - struct _mutation_queue_t *next; -} mutation_queue_t; - struct NSContainer { const nsIWebBrowserChromeVtbl *lpWebBrowserChromeVtbl; const nsIContextMenuListenerVtbl *lpContextMenuListenerVtbl; @@ -365,16 +382,6 @@ struct NSContainer { const nsIWeakReferenceVtbl *lpWeakReferenceVtbl; const nsISupportsWeakReferenceVtbl *lpSupportsWeakReferenceVtbl; - const nsIDocumentObserverVtbl *lpDocumentObserverVtbl; - - const nsIRunnableVtbl *lpRunnableVtbl; - - nsEventListener blur_listener; - nsEventListener focus_listener; - nsEventListener keypress_listener; - nsEventListener load_listener; - nsEventListener htmlevent_listener; - nsIWebBrowser *webbrowser; nsIWebNavigation *navigation; nsIBaseWindow *window; @@ -392,9 +399,6 @@ struct NSContainer { HWND hwnd; - mutation_queue_t *mutation_queue; - mutation_queue_t *mutation_queue_tail; - nsChannelBSC *bscallback; /* hack */ HWND reset_focus; /* hack */ }; @@ -425,6 +429,7 @@ typedef struct { HRESULT (*qi)(HTMLDOMNode*,REFIID,void**); void (*destructor)(HTMLDOMNode*); event_target_t **(*get_event_target)(HTMLDOMNode*); + HRESULT (*call_event)(HTMLDOMNode*,DWORD,BOOL*); HRESULT (*put_disabled)(HTMLDOMNode*,VARIANT_BOOL); HRESULT (*get_disabled)(HTMLDOMNode*,VARIANT_BOOL*); } NodeImplVtbl; @@ -463,18 +468,46 @@ typedef struct { ConnectionPoint cp; } HTMLTextContainer; +struct HTMLFrameBase { + HTMLElement element; + + const IHTMLFrameBaseVtbl *lpIHTMLFrameBaseVtbl; + + HTMLWindow *content_window; +}; + +typedef struct _mutation_queue_t { + DWORD type; + nsISupports *nsiface; + + struct _mutation_queue_t *next; +} mutation_queue_t; + +typedef struct nsDocumentEventListener nsDocumentEventListener; + struct HTMLDocumentNode { HTMLDOMNode node; HTMLDocument basedoc; const IInternetHostSecurityManagerVtbl *lpIInternetHostSecurityManagerVtbl; + const nsIDocumentObserverVtbl *lpIDocumentObserverVtbl; + const nsIRunnableVtbl *lpIRunnableVtbl; + LONG ref; + nsIDOMHTMLDocument *nsdoc; HTMLDOMNode *nodes; + BOOL content_ready; IInternetSecurityManager *secmgr; + nsDocumentEventListener *nsevent_listener; + BOOL *event_vector; + mutation_queue_t *mutation_queue; + mutation_queue_t *mutation_queue_tail; + + struct list bindings; struct list selection_list; struct list range_list; }; @@ -486,6 +519,7 @@ struct HTMLDocumentNode { #define HTMLDOC3(x) ((IHTMLDocument3*) &(x)->lpHTMLDocument3Vtbl) #define HTMLDOC4(x) ((IHTMLDocument4*) &(x)->lpHTMLDocument4Vtbl) #define HTMLDOC5(x) ((IHTMLDocument5*) &(x)->lpHTMLDocument5Vtbl) +#define HTMLDOC6(x) ((IHTMLDocument6*) &(x)->lpHTMLDocument6Vtbl) #define PERSIST(x) ((IPersist*) &(x)->lpPersistFileVtbl) #define PERSISTMON(x) ((IPersistMoniker*) &(x)->lpPersistMonikerVtbl) #define PERSISTFILE(x) ((IPersistFile*) &(x)->lpPersistFileVtbl) @@ -518,9 +552,9 @@ struct HTMLDocumentNode { #define NSWEAKREF(x) ((nsIWeakReference*) &(x)->lpWeakReferenceVtbl) #define NSSUPWEAKREF(x) ((nsISupportsWeakReference*) &(x)->lpSupportsWeakReferenceVtbl) -#define NSDOCOBS(x) ((nsIDocumentObserver*) &(x)->lpDocumentObserverVtbl) +#define NSDOCOBS(x) ((nsIDocumentObserver*) &(x)->lpIDocumentObserverVtbl) -#define NSRUNNABLE(x) ((nsIRunnable*) &(x)->lpRunnableVtbl) +#define NSRUNNABLE(x) ((nsIRunnable*) &(x)->lpIRunnableVtbl) #define NSCHANNEL(x) ((nsIChannel*) &(x)->lpHttpChannelVtbl) #define NSHTTPCHANNEL(x) ((nsIHttpChannel*) &(x)->lpHttpChannelVtbl) @@ -538,8 +572,10 @@ struct HTMLDocumentNode { #define HTMLDOMNODE2(x) ((IHTMLDOMNode2*) &(x)->lpHTMLDOMNode2Vtbl) #define HTMLTEXTCONT(x) ((IHTMLTextContainer*) &(x)->lpHTMLTextContainerVtbl) +#define HTMLFRAMEBASE(x) ((IHTMLFrameBase*) &(x)->lpIHTMLFrameBaseVtbl) #define HTMLOPTFACTORY(x) ((IHTMLOptionElementFactory*) &(x)->lpHTMLOptionElementFactoryVtbl) +#define HTMLIMGFACTORY(x) ((IHTMLImageElementFactory*) &(x)->lpHTMLImageElementFactoryVtbl) #define HTMLLOCATION(x) ((IHTMLLocation*) &(x)->lpHTMLLocationVtbl) #define DISPATCHEX(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl) @@ -555,10 +591,12 @@ HRESULT HTMLDocument_Create(IUnknown*,REFIID,void**); HRESULT HTMLLoadOptions_Create(IUnknown*,REFIID,void**); HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument*,HTMLDocumentObj*,HTMLWindow*,HTMLDocumentNode**); -HRESULT HTMLWindow_Create(HTMLDocumentObj*,nsIDOMWindow*,HTMLWindow**); -void window_set_docnode(HTMLWindow*,HTMLDocumentNode*); +HRESULT HTMLWindow_Create(HTMLDocumentObj*,nsIDOMWindow*,HTMLWindow*,HTMLWindow**); +void update_window_doc(HTMLWindow*); HTMLWindow *nswindow_to_window(const nsIDOMWindow*); +nsIDOMWindow *get_nsdoc_window(nsIDOMDocument*); HTMLOptionElementFactory *HTMLOptionElementFactory_Create(HTMLWindow*); +HTMLImageElementFactory *HTMLImageElementFactory_Create(HTMLWindow*); HRESULT HTMLLocation_Create(HTMLWindow*,HTMLLocation**); IOmNavigator *OmNavigator_Create(void); @@ -583,9 +621,8 @@ void ConnectionPointContainer_Destroy(ConnectionPointContainer*); NSContainer *NSContainer_Create(HTMLDocumentObj*,NSContainer*); void NSContainer_Release(NSContainer*); -void init_mutation(NSContainer*); -void set_mutation_observer(NSContainer*,nsIDOMHTMLDocument*); -void remove_mutation_observer(NSContainer*,nsIDOMHTMLDocument*); +void init_mutation(HTMLDocumentNode*); +void release_mutation(HTMLDocumentNode*); void HTMLDocument_LockContainer(HTMLDocumentObj*,BOOL); void show_context_menu(HTMLDocumentObj*,DWORD,POINT*,IDispatch*); @@ -606,7 +643,8 @@ BOOL install_wine_gecko(BOOL); HRESULT nsuri_to_url(LPCWSTR,BOOL,BSTR*); -void hlink_frame_navigate(HTMLDocument*,IHlinkFrame*,LPCWSTR,nsIInputStream*,DWORD); +HRESULT hlink_frame_navigate(HTMLDocument*,LPCWSTR,nsIInputStream*,DWORD); +HRESULT navigate_url(HTMLDocumentNode*,OLECHAR*); void call_property_onchanged(ConnectionPoint*,DISPID); HRESULT call_set_active_object(IOleInPlaceUIWindow*,IOleInPlaceActiveObject*); @@ -627,22 +665,26 @@ void nsAString_Finish(nsAString*); nsICommandParams *create_nscommand_params(void); HRESULT nsnode_to_nsstring(nsIDOMNode*,nsAString*); void get_editor_controller(NSContainer*); -void init_nsevents(NSContainer*); -void add_nsevent_listener(HTMLWindow*,LPCWSTR); nsresult get_nsinterface(nsISupports*,REFIID,void**); -void update_nsdocument(HTMLDocumentObj*); -void set_document_bscallback(HTMLDocument*,nsChannelBSC*); -void set_current_mon(HTMLDocument*,IMoniker*); -HRESULT start_binding(HTMLDocument*,BSCallback*,IBindCtx*); +void init_nsevents(HTMLDocumentNode*); +void release_nsevents(HTMLDocumentNode*); +void add_nsevent_listener(HTMLDocumentNode*,LPCWSTR); -HRESULT bind_mon_to_buffer(HTMLDocument*,IMoniker*,void**,DWORD*); +void set_window_bscallback(HTMLWindow*,nsChannelBSC*); +void set_current_mon(HTMLWindow*,IMoniker*); +HRESULT start_binding(HTMLWindow*,HTMLDocumentNode*,BSCallback*,IBindCtx*); +void abort_document_bindings(HTMLDocumentNode*); + +HRESULT bind_mon_to_buffer(HTMLDocumentNode*,IMoniker*,void**,DWORD*); nsChannelBSC *create_channelbsc(IMoniker*); HRESULT channelbsc_load_stream(nsChannelBSC*,IStream*); void channelbsc_set_channel(nsChannelBSC*,nsChannel*,nsIStreamListener*,nsISupports*); IMoniker *get_channelbsc_mon(nsChannelBSC*); +void set_ready_state(HTMLWindow*,READYSTATE); + HRESULT HTMLSelectionObject_Create(HTMLDocumentNode*,nsISelection*,IHTMLSelectionObject**); HRESULT HTMLTxtRange_Create(HTMLDocumentNode*,nsIDOMRange*,IHTMLTxtRange**); IHTMLStyle *HTMLStyle_Create(nsIDOMCSSStyleDeclaration*); @@ -653,28 +695,32 @@ void detach_selection(HTMLDocumentNode*); void detach_ranges(HTMLDocumentNode*); HRESULT get_node_text(HTMLDOMNode*,BSTR*); +HRESULT create_nselem(HTMLDocumentNode*,const WCHAR*,nsIDOMHTMLElement**); + HTMLDOMNode *HTMLDOMTextNode_Create(HTMLDocumentNode*,nsIDOMNode*); HTMLElement *HTMLElement_Create(HTMLDocumentNode*,nsIDOMNode*,BOOL); HTMLElement *HTMLCommentElement_Create(HTMLDocumentNode*,nsIDOMNode*); -HTMLElement *HTMLAnchorElement_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLBodyElement_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLIFrame_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLImgElement_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLInputElement_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLOptionElement_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLScriptElement_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLSelectElement_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLTable_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLTableRow_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLTextAreaElement_Create(nsIDOMHTMLElement*); -HTMLElement *HTMLGenericElement_Create(nsIDOMHTMLElement*); +HTMLElement *HTMLAnchorElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLBodyElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLFrameElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*,HTMLWindow*); +HTMLElement *HTMLIFrame_Create(HTMLDocumentNode*,nsIDOMHTMLElement*,HTMLWindow*); +HTMLElement *HTMLImgElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLInputElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLOptionElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLScriptElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLSelectElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLTable_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLTableRow_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLTextAreaElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLGenericElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); void HTMLDOMNode_Init(HTMLDocumentNode*,HTMLDOMNode*,nsIDOMNode*); -void HTMLElement_Init(HTMLElement*,dispex_static_data_t*); +void HTMLElement_Init(HTMLElement*,HTMLDocumentNode*,nsIDOMHTMLElement*,dispex_static_data_t*); void HTMLElement2_Init(HTMLElement*); void HTMLElement3_Init(HTMLElement*); -void HTMLTextContainer_Init(HTMLTextContainer*,dispex_static_data_t*); +void HTMLTextContainer_Init(HTMLTextContainer*,HTMLDocumentNode*,nsIDOMHTMLElement*,dispex_static_data_t*); +void HTMLFrameBase_Init(HTMLFrameBase*,HTMLDocumentNode*,nsIDOMHTMLElement*,HTMLWindow*,dispex_static_data_t*); HRESULT HTMLDOMNode_QI(HTMLDOMNode*,REFIID,void**); void HTMLDOMNode_destructor(HTMLDOMNode*); @@ -682,6 +728,9 @@ void HTMLDOMNode_destructor(HTMLDOMNode*); HRESULT HTMLElement_QI(HTMLDOMNode*,REFIID,void**); void HTMLElement_destructor(HTMLDOMNode*); +HRESULT HTMLFrameBase_QI(HTMLFrameBase*,REFIID,void**); +void HTMLFrameBase_destructor(HTMLFrameBase*); + HTMLDOMNode *get_node(HTMLDocumentNode*,nsIDOMNode*,BOOL); void release_nodes(HTMLDocumentNode*); @@ -728,20 +777,19 @@ void set_dirty(HTMLDocument*,VARIANT_BOOL); extern DWORD mshtml_tls; -typedef struct task_t { - HTMLDocument *doc; - - enum { - TASK_SETDOWNLOADSTATE, - TASK_PARSECOMPLETE, - TASK_SETPROGRESS, - TASK_START_BINDING - } task_id; - - nsChannelBSC *bscallback; +typedef struct task_t task_t; +typedef void (*task_proc_t)(task_t*); +struct task_t { + LONG target_magic; + task_proc_t proc; struct task_t *next; -} task_t; +}; + +typedef struct { + task_t header; + HTMLDocumentObj *doc; +} docobj_task_t; typedef struct { HWND thread_hwnd; @@ -752,8 +800,11 @@ typedef struct { thread_data_t *get_thread_data(BOOL); HWND get_thread_hwnd(void); -void push_task(task_t*); -void remove_doc_tasks(const HTMLDocument*); + +LONG get_task_target_magic(void); +void push_task(task_t*,task_proc_t,LONG); +void remove_target_tasks(LONG); + DWORD set_task_timer(HTMLDocument*,DWORD,BOOL,IDispatch*); HRESULT clear_task_timer(HTMLDocument*,BOOL,DWORD); @@ -855,6 +906,17 @@ static inline char *heap_strdupWtoA(LPCWSTR str) return ret; } +static inline void windowref_addref(windowref_t *ref) +{ + InterlockedIncrement(&ref->ref); +} + +static inline void windowref_release(windowref_t *ref) +{ + if(!InterlockedDecrement(&ref->ref)) + heap_free(ref); +} + HINSTANCE get_shdoclc(void); extern HINSTANCE hInst; diff --git a/reactos/dll/win32/mshtml/mutation.c b/reactos/dll/win32/mshtml/mutation.c index dd47522f7c7..84c92413346 100644 --- a/reactos/dll/win32/mshtml/mutation.c +++ b/reactos/dll/win32/mshtml/mutation.c @@ -27,6 +27,7 @@ #include "winuser.h" #include "winreg.h" #include "ole2.h" +#include "shlguid.h" #include "mshtml_private.h" #include "htmlevent.h" @@ -37,43 +38,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); enum { MUTATION_COMMENT, + MUTATION_ENDLOAD, + MUTATION_FRAME, + MUTATION_IFRAME, MUTATION_SCRIPT }; -void set_mutation_observer(NSContainer *nscontainer, nsIDOMHTMLDocument *nshtmldoc) -{ - nsIDOMNSDocument *nsdoc; - nsresult nsres; - - nsres = nsIDOMHTMLDocument_QueryInterface(nshtmldoc, &IID_nsIDOMNSDocument, (void**)&nsdoc); - if(NS_FAILED(nsres)) { - ERR("Could not get nsIDOMNSDocument: %08x\n", nsres); - return; - } - - nsIDOMNSDocument_WineAddObserver(nsdoc, NSDOCOBS(nscontainer)); - nsIDOMNSDocument_Release(nsdoc); -} - -void remove_mutation_observer(NSContainer *nscontainer, nsIDOMHTMLDocument *nshtmldoc) -{ - nsIDOMNSDocument *nsdoc; - nsresult nsres; - - nsres = nsIDOMHTMLDocument_QueryInterface(nshtmldoc, &IID_nsIDOMNSDocument, (void**)&nsdoc); - if(NS_FAILED(nsres)) { - ERR("Could not get nsIDOMNSDocument: %08x\n", nsres); - return; - } - - nsIDOMNSDocument_WineRemoveObserver(nsdoc, NSDOCOBS(nscontainer)); - nsIDOMNSDocument_Release(nsdoc); -} - #define IE_MAJOR_VERSION 7 #define IE_MINOR_VERSION 0 -static BOOL handle_insert_comment(HTMLDocument *doc, const PRUnichar *comment) +static BOOL handle_insert_comment(HTMLDocumentNode *doc, const PRUnichar *comment) { DWORD len; int majorv = 0, minorv = 0; @@ -209,12 +183,12 @@ static BOOL handle_insert_comment(HTMLDocument *doc, const PRUnichar *comment) return TRUE; } -static void add_script_runner(NSContainer *This) +static void add_script_runner(HTMLDocumentNode *This) { nsIDOMNSDocument *nsdoc; nsresult nsres; - nsres = nsIDOMHTMLDocument_QueryInterface(This->doc->basedoc.nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc); + nsres = nsIDOMHTMLDocument_QueryInterface(This->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc); if(NS_FAILED(nsres)) { ERR("Could not get nsIDOMNSDocument: %08x\n", nsres); return; @@ -224,12 +198,12 @@ static void add_script_runner(NSContainer *This) nsIDOMNSDocument_Release(nsdoc); } -#define NSRUNNABLE_THIS(iface) DEFINE_THIS(NSContainer, Runnable, iface) +#define NSRUNNABLE_THIS(iface) DEFINE_THIS(HTMLDocumentNode, IRunnable, iface) static nsresult NSAPI nsRunnable_QueryInterface(nsIRunnable *iface, nsIIDRef riid, nsQIResult result) { - NSContainer *This = NSRUNNABLE_THIS(iface); + HTMLDocumentNode *This = NSRUNNABLE_THIS(iface); if(IsEqualGUID(riid, &IID_nsISupports)) { TRACE("(%p)->(IID_nsISupports %p)\n", This, result); @@ -249,34 +223,203 @@ static nsresult NSAPI nsRunnable_QueryInterface(nsIRunnable *iface, static nsrefcnt NSAPI nsRunnable_AddRef(nsIRunnable *iface) { - NSContainer *This = NSRUNNABLE_THIS(iface); - return nsIWebBrowserChrome_AddRef(NSWBCHROME(This)); + HTMLDocumentNode *This = NSRUNNABLE_THIS(iface); + return htmldoc_addref(&This->basedoc); } static nsrefcnt NSAPI nsRunnable_Release(nsIRunnable *iface) { - NSContainer *This = NSRUNNABLE_THIS(iface); - return nsIWebBrowserChrome_Release(NSWBCHROME(This)); + HTMLDocumentNode *This = NSRUNNABLE_THIS(iface); + return htmldoc_release(&This->basedoc); } -static void pop_mutation_queue(NSContainer *nscontainer) +static void push_mutation_queue(HTMLDocumentNode *doc, DWORD type, nsISupports *nsiface) { - mutation_queue_t *tmp = nscontainer->mutation_queue; + mutation_queue_t *elem; + + elem = heap_alloc(sizeof(mutation_queue_t)); + if(!elem) + return; + + elem->next = NULL; + elem->type = type; + elem->nsiface = nsiface; + if(nsiface) + nsISupports_AddRef(nsiface); + + if(doc->mutation_queue_tail) { + doc->mutation_queue_tail = doc->mutation_queue_tail->next = elem; + }else { + doc->mutation_queue = doc->mutation_queue_tail = elem; + add_script_runner(doc); + } +} + +static void pop_mutation_queue(HTMLDocumentNode *doc) +{ + mutation_queue_t *tmp = doc->mutation_queue; if(!tmp) return; - nscontainer->mutation_queue = tmp->next; + doc->mutation_queue = tmp->next; if(!tmp->next) - nscontainer->mutation_queue_tail = NULL; + doc->mutation_queue_tail = NULL; - nsISupports_Release(tmp->nsiface); + if(tmp->nsiface) + nsISupports_Release(tmp->nsiface); heap_free(tmp); } +static nsresult init_nsdoc_window(HTMLDocumentNode *doc, nsIDOMDocument *nsdoc, HTMLWindow **ret) +{ + nsIDOMWindow *nswindow; + + nswindow = get_nsdoc_window(nsdoc); + if(!nswindow) + return NS_ERROR_FAILURE; + + if(!nswindow_to_window(nswindow)) { + HTMLWindow *window; + HRESULT hres; + + hres = HTMLWindow_Create(doc->basedoc.doc_obj, nswindow, doc->basedoc.window, &window); + if(SUCCEEDED(hres)) + *ret = window; + } + + nsIDOMWindow_Release(nswindow); + return NS_OK; +} + +static nsresult init_iframe_window(HTMLDocumentNode *doc, nsISupports *nsunk) +{ + nsIDOMHTMLIFrameElement *nsiframe; + HTMLWindow *window = NULL; + nsIDOMDocument *nsdoc; + nsresult nsres; + + nsres = nsISupports_QueryInterface(nsunk, &IID_nsIDOMHTMLIFrameElement, (void**)&nsiframe); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMHTMLIFrameElement: %08x\n", nsres); + return nsres; + } + + nsres = nsIDOMHTMLIFrameElement_GetContentDocument(nsiframe, &nsdoc); + nsIDOMHTMLIFrameElement_Release(nsiframe); + if(NS_FAILED(nsres) || !nsdoc) { + ERR("GetContentDocument failed: %08x\n", nsres); + return nsres; + } + + nsres = init_nsdoc_window(doc, nsdoc, &window); + + if(window) { + HTMLIFrame_Create(doc, (nsIDOMHTMLElement*)nsiframe, window); + IHTMLWindow2_Release(HTMLWINDOW2(window)); + } + + nsIDOMDocument_Release(nsdoc); + return nsres; +} + +static nsresult init_frame_window(HTMLDocumentNode *doc, nsISupports *nsunk) +{ + nsIDOMHTMLFrameElement *nsframe; + HTMLWindow *window = NULL; + nsIDOMDocument *nsdoc; + nsresult nsres; + + nsres = nsISupports_QueryInterface(nsunk, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMHTMLFrameElement: %08x\n", nsres); + return nsres; + } + + nsres = nsIDOMHTMLFrameElement_GetContentDocument(nsframe, &nsdoc); + nsIDOMHTMLFrameElement_Release(nsframe); + if(NS_FAILED(nsres) || !nsdoc) { + ERR("GetContentDocument failed: %08x\n", nsres); + return nsres; + } + + nsres = init_nsdoc_window(doc, nsdoc, &window); + + if(window) { + HTMLFrameElement_Create(doc, (nsIDOMHTMLElement*)nsframe, window); + IHTMLWindow2_Release(HTMLWINDOW2(window)); + } + + nsIDOMDocument_Release(nsdoc); + return nsres; +} + +/* Calls undocumented 69 cmd of CGID_Explorer */ +static void call_explorer_69(HTMLDocumentObj *doc) +{ + IOleCommandTarget *olecmd; + VARIANT var; + HRESULT hres; + + if(!doc->client) + return; + + hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); + if(FAILED(hres)) + return; + + VariantInit(&var); + hres = IOleCommandTarget_Exec(olecmd, &CGID_Explorer, 69, 0, NULL, &var); + IOleCommandTarget_Release(olecmd); + if(SUCCEEDED(hres) && V_VT(&var) != VT_NULL) + FIXME("handle result\n"); +} + +static void parse_complete_proc(task_t *task) +{ + HTMLDocumentObj *doc = ((docobj_task_t*)task)->doc; + + TRACE("(%p)\n", doc); + + if(doc->usermode == EDITMODE) + init_editor(&doc->basedoc); + + call_explorer_69(doc); + call_property_onchanged(&doc->basedoc.cp_propnotif, 1005); + call_explorer_69(doc); + + /* FIXME: IE7 calls EnableModelless(TRUE), EnableModelless(FALSE) and sets interactive state here */ + + set_ready_state(doc->basedoc.window, READYSTATE_INTERACTIVE); +} + +static void handle_end_load(HTMLDocumentNode *This) +{ + docobj_task_t *task; + + TRACE("\n"); + + if(This != This->basedoc.doc_obj->basedoc.doc_node) { + set_ready_state(This->basedoc.window, READYSTATE_INTERACTIVE); + return; + } + + task = heap_alloc(sizeof(docobj_task_t)); + if(!task) + return; + + task->doc = This->basedoc.doc_obj; + + /* + * This should be done in the worker thread that parses HTML, + * but we don't have such thread (Gecko parses HTML for us). + */ + push_task(&task->header, &parse_complete_proc, This->basedoc.doc_obj->basedoc.task_magic); +} + static nsresult NSAPI nsRunnable_Run(nsIRunnable *iface) { - NSContainer *This = NSRUNNABLE_THIS(iface); + HTMLDocumentNode *This = NSRUNNABLE_THIS(iface); nsresult nsres; TRACE("(%p)\n", This); @@ -300,7 +443,7 @@ static nsresult NSAPI nsRunnable_Run(nsIRunnable *iface) const PRUnichar *comment; nsAString_GetData(&comment_str, &comment); - remove_comment = handle_insert_comment(&This->doc->basedoc, comment); + remove_comment = handle_insert_comment(This, comment); } nsAString_Finish(&comment_str); @@ -330,6 +473,18 @@ static nsresult NSAPI nsRunnable_Run(nsIRunnable *iface) break; } + case MUTATION_ENDLOAD: + handle_end_load(This); + break; + + case MUTATION_FRAME: + init_frame_window(This, This->mutation_queue->nsiface); + break; + + case MUTATION_IFRAME: + init_iframe_window(This, This->mutation_queue->nsiface); + break; + case MUTATION_SCRIPT: { nsIDOMHTMLScriptElement *nsscript; @@ -340,7 +495,7 @@ static nsresult NSAPI nsRunnable_Run(nsIRunnable *iface) break; } - doc_insert_script(This->doc->basedoc.window, nsscript); + doc_insert_script(This->basedoc.window, nsscript); nsIDOMHTMLScriptElement_Release(nsscript); break; } @@ -364,12 +519,12 @@ static const nsIRunnableVtbl nsRunnableVtbl = { nsRunnable_Run }; -#define NSDOCOBS_THIS(iface) DEFINE_THIS(NSContainer, DocumentObserver, iface) +#define NSDOCOBS_THIS(iface) DEFINE_THIS(HTMLDocumentNode, IDocumentObserver, iface) static nsresult NSAPI nsDocumentObserver_QueryInterface(nsIDocumentObserver *iface, nsIIDRef riid, nsQIResult result) { - NSContainer *This = NSDOCOBS_THIS(iface); + HTMLDocumentNode *This = NSDOCOBS_THIS(iface); if(IsEqualGUID(&IID_nsISupports, riid)) { TRACE("(%p)->(IID_nsISupports, %p)\n", This, result); @@ -386,20 +541,20 @@ static nsresult NSAPI nsDocumentObserver_QueryInterface(nsIDocumentObserver *ifa return NS_NOINTERFACE; } - nsIWebBrowserChrome_AddRef(NSWBCHROME(This)); + htmldoc_addref(&This->basedoc); return NS_OK; } static nsrefcnt NSAPI nsDocumentObserver_AddRef(nsIDocumentObserver *iface) { - NSContainer *This = NSDOCOBS_THIS(iface); - return nsIWebBrowserChrome_AddRef(NSWBCHROME(This)); + HTMLDocumentNode *This = NSDOCOBS_THIS(iface); + return htmldoc_addref(&This->basedoc); } static nsrefcnt NSAPI nsDocumentObserver_Release(nsIDocumentObserver *iface) { - NSContainer *This = NSDOCOBS_THIS(iface); - return nsIWebBrowserChrome_Release(NSWBCHROME(This)); + HTMLDocumentNode *This = NSDOCOBS_THIS(iface); + return htmldoc_release(&This->basedoc); } static void NSAPI nsDocumentObserver_CharacterDataWillChange(nsIDocumentObserver *iface, @@ -461,22 +616,12 @@ static void NSAPI nsDocumentObserver_BeginLoad(nsIDocumentObserver *iface, nsIDo static void NSAPI nsDocumentObserver_EndLoad(nsIDocumentObserver *iface, nsIDocument *aDocument) { - NSContainer *This = NSDOCOBS_THIS(iface); - task_t *task; + HTMLDocumentNode *This = NSDOCOBS_THIS(iface); TRACE("\n"); - task = heap_alloc(sizeof(task_t)); - - task->doc = &This->doc->basedoc; - task->task_id = TASK_PARSECOMPLETE; - task->next = NULL; - - /* - * This should be done in the worker thread that parses HTML, - * but we don't have such thread (Gecko parses HTML for us). - */ - push_task(task); + This->content_ready = TRUE; + push_mutation_queue(This, MUTATION_ENDLOAD, NULL); } static void NSAPI nsDocumentObserver_ContentStatesChanged(nsIDocumentObserver *iface, nsIDocument *aDocument, @@ -514,29 +659,12 @@ static void NSAPI nsDocumentObserver_StyleRuleRemoved(nsIDocumentObserver *iface { } -static void push_mutation_queue(NSContainer *nscontainer, DWORD type, nsISupports *nsiface) -{ - mutation_queue_t *elem; - - elem = heap_alloc(sizeof(mutation_queue_t)); - if(!elem) - return; - - elem->next = NULL; - elem->type = type; - elem->nsiface = nsiface; - nsISupports_AddRef(nsiface); - - if(nscontainer->mutation_queue_tail) - nscontainer->mutation_queue_tail = nscontainer->mutation_queue_tail->next = elem; - else - nscontainer->mutation_queue = nscontainer->mutation_queue_tail = elem; -} - static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, nsIDocument *aDocument, nsIContent *aContent) { - NSContainer *This = NSDOCOBS_THIS(iface); + HTMLDocumentNode *This = NSDOCOBS_THIS(iface); + nsIDOMHTMLIFrameElement *nsiframe; + nsIDOMHTMLFrameElement *nsframe; nsIDOMComment *nscomment; nsIDOMElement *nselem; nsresult nsres; @@ -545,7 +673,7 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMElement, (void**)&nselem); if(NS_SUCCEEDED(nsres)) { - check_event_attr(This->doc->basedoc.doc_node, nselem); + check_event_attr(This, nselem); nsIDOMElement_Release(nselem); } @@ -555,14 +683,29 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, push_mutation_queue(This, MUTATION_COMMENT, (nsISupports*)nscomment); nsIDOMComment_Release(nscomment); - add_script_runner(This); + } + + nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLIFrameElement, (void**)&nsiframe); + if(NS_SUCCEEDED(nsres)) { + TRACE("iframe node\n"); + + push_mutation_queue(This, MUTATION_IFRAME, (nsISupports*)nsiframe); + nsIDOMHTMLIFrameElement_Release(nsiframe); + } + + nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe); + if(NS_SUCCEEDED(nsres)) { + TRACE("frame node\n"); + + push_mutation_queue(This, MUTATION_FRAME, (nsISupports*)nsframe); + nsIDOMHTMLFrameElement_Release(nsframe); } } static void NSAPI nsDocumentObserver_DoneAddingChildren(nsIDocumentObserver *iface, nsIContent *aContent, PRBool aHaveNotified) { - NSContainer *This = NSDOCOBS_THIS(iface); + HTMLDocumentNode *This = NSDOCOBS_THIS(iface); nsIDOMHTMLScriptElement *nsscript; nsresult nsres; @@ -570,9 +713,10 @@ static void NSAPI nsDocumentObserver_DoneAddingChildren(nsIDocumentObserver *ifa nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLScriptElement, (void**)&nsscript); if(NS_SUCCEEDED(nsres)) { + TRACE("script node\n"); + push_mutation_queue(This, MUTATION_SCRIPT, (nsISupports*)nsscript); nsIDOMHTMLScriptElement_Release(nsscript); - add_script_runner(This); } } @@ -606,8 +750,35 @@ static const nsIDocumentObserverVtbl nsDocumentObserverVtbl = { nsDocumentObserver_DoneAddingChildren }; -void init_mutation(NSContainer *nscontainer) +void init_mutation(HTMLDocumentNode *doc) { - nscontainer->lpDocumentObserverVtbl = &nsDocumentObserverVtbl; - nscontainer->lpRunnableVtbl = &nsRunnableVtbl; + nsIDOMNSDocument *nsdoc; + nsresult nsres; + + doc->lpIDocumentObserverVtbl = &nsDocumentObserverVtbl; + doc->lpIRunnableVtbl = &nsRunnableVtbl; + + nsres = nsIDOMHTMLDocument_QueryInterface(doc->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMNSDocument: %08x\n", nsres); + return; + } + + nsIDOMNSDocument_WineAddObserver(nsdoc, NSDOCOBS(doc)); + nsIDOMNSDocument_Release(nsdoc); +} + +void release_mutation(HTMLDocumentNode *doc) +{ + nsIDOMNSDocument *nsdoc; + nsresult nsres; + + nsres = nsIDOMHTMLDocument_QueryInterface(doc->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIDOMNSDocument: %08x\n", nsres); + return; + } + + nsIDOMNSDocument_WineRemoveObserver(nsdoc, NSDOCOBS(doc)); + nsIDOMNSDocument_Release(nsdoc); } diff --git a/reactos/dll/win32/mshtml/navigate.c b/reactos/dll/win32/mshtml/navigate.c index 267168f9d51..727eaef15fe 100644 --- a/reactos/dll/win32/mshtml/navigate.c +++ b/reactos/dll/win32/mshtml/navigate.c @@ -41,6 +41,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define CONTENT_LENGTH "Content-Length" #define UTF16_STR "utf-16" +static WCHAR emptyW[] = {0}; + typedef struct { const nsIInputStreamVtbl *lpInputStreamVtbl; @@ -82,7 +84,7 @@ struct BSCallback { IMoniker *mon; IBinding *binding; - HTMLDocument *doc; + HTMLDocumentNode *doc; struct list entry; }; @@ -313,7 +315,7 @@ static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *ifa This->binding = pbind; if(This->doc) - list_add_head(&This->doc->doc_obj->bindings, &This->entry); + list_add_head(&This->doc->bindings, &This->entry); return This->vtbl->start_binding(This); } @@ -705,7 +707,7 @@ static void parse_post_data(nsIInputStream *post_data_stream, LPWSTR *headers_re *post_data_len_ret = post_data_len; } -HRESULT start_binding(HTMLDocument *doc, BSCallback *bscallback, IBindCtx *bctx) +HRESULT start_binding(HTMLWindow *window, HTMLDocumentNode *doc, BSCallback *bscallback, IBindCtx *bctx) { IStream *str = NULL; HRESULT hres; @@ -714,7 +716,8 @@ HRESULT start_binding(HTMLDocument *doc, BSCallback *bscallback, IBindCtx *bctx) /* NOTE: IE7 calls IsSystemMoniker here*/ - call_docview_84(doc->doc_obj); + if(window) + call_docview_84(window->doc_obj); if(bctx) { RegisterBindStatusCallback(bctx, STATUSCLB(bscallback), NULL, 0); @@ -846,14 +849,14 @@ static BufferBSC *create_bufferbsc(IMoniker *mon) return ret; } -HRESULT bind_mon_to_buffer(HTMLDocument *doc, IMoniker *mon, void **buf, DWORD *size) +HRESULT bind_mon_to_buffer(HTMLDocumentNode *doc, IMoniker *mon, void **buf, DWORD *size) { BufferBSC *bsc = create_bufferbsc(mon); HRESULT hres; *buf = NULL; - hres = start_binding(doc, &bsc->bsc, NULL); + hres = start_binding(NULL, doc, &bsc->bsc, NULL); if(SUCCEEDED(hres)) { hres = bsc->hres; if(SUCCEEDED(hres)) { @@ -872,6 +875,8 @@ HRESULT bind_mon_to_buffer(HTMLDocument *doc, IMoniker *mon, void **buf, DWORD * struct nsChannelBSC { BSCallback bsc; + HTMLWindow *window; + nsChannel *nschannel; nsIStreamListener *nslistener; nsISupports *nscontext; @@ -948,11 +953,8 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) on_start_nsrequest(This); - /* events are reset when a new document URI is loaded, so re-initialise them here */ - if(This->bsc.doc && This->bsc.doc->doc_obj->bscallback == This && This->bsc.doc->doc_obj->nscontainer) { - update_nsdocument(This->bsc.doc->doc_obj); - init_nsevents(This->bsc.doc->doc_obj->nscontainer); - } + if(This->window) + update_window_doc(This->window); } This->bsc.readed += This->nsstream->buf_size; @@ -1105,41 +1107,52 @@ IMoniker *get_channelbsc_mon(nsChannelBSC *This) return This->bsc.mon; } -void set_document_bscallback(HTMLDocument *doc, nsChannelBSC *callback) +void set_window_bscallback(HTMLWindow *window, nsChannelBSC *callback) +{ + if(window->bscallback) { + if(window->bscallback->bsc.binding) + IBinding_Abort(window->bscallback->bsc.binding); + window->bscallback->bsc.doc = NULL; + window->bscallback->window = NULL; + IBindStatusCallback_Release(STATUSCLB(&window->bscallback->bsc)); + } + + window->bscallback = callback; + + if(callback) { + callback->window = window; + IBindStatusCallback_AddRef(STATUSCLB(&callback->bsc)); + callback->bsc.doc = window->doc; + } +} + +void abort_document_bindings(HTMLDocumentNode *doc) { BSCallback *iter; - if(doc->doc_obj->bscallback) { - if(doc->doc_obj->bscallback->bsc.binding) - IBinding_Abort(doc->doc_obj->bscallback->bsc.binding); - doc->doc_obj->bscallback->bsc.doc = NULL; - IBindStatusCallback_Release(STATUSCLB(&doc->doc_obj->bscallback->bsc)); - } - - LIST_FOR_EACH_ENTRY(iter, &doc->doc_obj->bindings, BSCallback, entry) { + LIST_FOR_EACH_ENTRY(iter, &doc->bindings, BSCallback, entry) { + if(iter->binding) + IBinding_Abort(iter->binding); iter->doc = NULL; list_remove(&iter->entry); } - - doc->doc_obj->bscallback = callback; - - if(callback) { - IBindStatusCallback_AddRef(STATUSCLB(&callback->bsc)); - callback->bsc.doc = doc; - } } HRESULT channelbsc_load_stream(nsChannelBSC *bscallback, IStream *stream) { HRESULT hres; - const char text_html[] = "text/html"; + if(!bscallback->nschannel) { + ERR("NULL nschannel\n"); + return E_FAIL; + } + + bscallback->nschannel->content_type = heap_strdupA("text/html"); + if(!bscallback->nschannel->content_type) + return E_OUTOFMEMORY; add_nsrequest(bscallback); - if(bscallback->nschannel) - bscallback->nschannel->content_type = heap_strdupA(text_html); - hres = read_stream_data(bscallback, stream); IBindStatusCallback_OnStopBinding(STATUSCLB(&bscallback->bsc), hres, ERROR_SUCCESS); @@ -1160,14 +1173,27 @@ void channelbsc_set_channel(nsChannelBSC *This, nsChannel *channel, nsIStreamLis } } -void hlink_frame_navigate(HTMLDocument *doc, IHlinkFrame *hlink_frame, - LPCWSTR uri, nsIInputStream *post_data_stream, DWORD hlnf) +HRESULT hlink_frame_navigate(HTMLDocument *doc, LPCWSTR url, + nsIInputStream *post_data_stream, DWORD hlnf) { + IHlinkFrame *hlink_frame; + IServiceProvider *sp; BSCallback *callback; IBindCtx *bindctx; IMoniker *mon; IHlink *hlink; - HRESULT hr; + HRESULT hres; + + hres = IOleClientSite_QueryInterface(doc->doc_obj->client, &IID_IServiceProvider, + (void**)&sp); + if(FAILED(hres)) + return hres; + + hres = IServiceProvider_QueryService(sp, &IID_IHlinkFrame, &IID_IHlinkFrame, + (void**)&hlink_frame); + IServiceProvider_Release(sp); + if(FAILED(hres)) + return hres; callback = &create_channelbsc(NULL)->bsc; @@ -1178,33 +1204,52 @@ void hlink_frame_navigate(HTMLDocument *doc, IHlinkFrame *hlink_frame, debugstr_an(callback->post_data, callback->post_data_len)); } - hr = CreateAsyncBindCtx(0, STATUSCLB(callback), NULL, &bindctx); - if (FAILED(hr)) { - IBindStatusCallback_Release(STATUSCLB(callback)); - return; - } + hres = CreateAsyncBindCtx(0, STATUSCLB(callback), NULL, &bindctx); + if(SUCCEEDED(hres)) + hres = CoCreateInstance(&CLSID_StdHlink, NULL, CLSCTX_INPROC_SERVER, + &IID_IHlink, (LPVOID*)&hlink); - hr = CoCreateInstance(&CLSID_StdHlink, NULL, CLSCTX_INPROC_SERVER, &IID_IHlink, (LPVOID*)&hlink); - if (FAILED(hr)) { - IBindCtx_Release(bindctx); - IBindStatusCallback_Release(STATUSCLB(callback)); - return; - } + if(SUCCEEDED(hres)) + hres = CreateURLMoniker(NULL, url, &mon); - hr = CreateURLMoniker(NULL, uri, &mon); - if (SUCCEEDED(hr)) { - IHlink_SetMonikerReference(hlink, 0, mon, NULL); + if(SUCCEEDED(hres)) { + IHlink_SetMonikerReference(hlink, HLINKSETF_TARGET, mon, NULL); if(hlnf & HLNF_OPENINNEWWINDOW) { static const WCHAR wszBlank[] = {'_','b','l','a','n','k',0}; IHlink_SetTargetFrameName(hlink, wszBlank); /* FIXME */ } - IHlinkFrame_Navigate(hlink_frame, hlnf, bindctx, STATUSCLB(callback), hlink); + hres = IHlinkFrame_Navigate(hlink_frame, hlnf, bindctx, STATUSCLB(callback), hlink); IMoniker_Release(mon); } + IHlinkFrame_Release(hlink_frame); IBindCtx_Release(bindctx); IBindStatusCallback_Release(STATUSCLB(callback)); + return hres; +} + +HRESULT navigate_url(HTMLDocumentNode *doc, OLECHAR *url) +{ + OLECHAR *translated_url = NULL; + HRESULT hres; + + if(!url) + url = emptyW; + + if(doc->basedoc.doc_obj->hostui) { + hres = IDocHostUIHandler_TranslateUrl(doc->basedoc.doc_obj->hostui, 0, url, + &translated_url); + if(hres == S_OK) + url = translated_url; + } + + hres = hlink_frame_navigate(&doc->basedoc, url, NULL, 0); + if(FAILED(hres)) + FIXME("hlink_frame_navigate failed: %08x\n", hres); + + CoTaskMemFree(translated_url); + return hres; } diff --git a/reactos/dll/win32/mshtml/nsembed.c b/reactos/dll/win32/mshtml/nsembed.c index 6a413769ffb..2150a0f30d5 100644 --- a/reactos/dll/win32/mshtml/nsembed.c +++ b/reactos/dll/win32/mshtml/nsembed.c @@ -807,63 +807,6 @@ void set_ns_editmode(NSContainer *This) nsIWebBrowser_SetParentURIContentListener(This->webbrowser, NSURICL(This)); } -void update_nsdocument(HTMLDocumentObj *doc) -{ - HTMLDocumentNode *doc_node; - nsIDOMHTMLDocument *nsdoc; - nsIDOMDocument *nsdomdoc; - nsresult nsres; - HRESULT hres; - - if(!doc->nscontainer || !doc->nscontainer->navigation) - return; - - nsres = nsIWebNavigation_GetDocument(doc->nscontainer->navigation, &nsdomdoc); - if(NS_FAILED(nsres) || !nsdomdoc) { - ERR("GetDocument failed: %08x\n", nsres); - return; - } - - nsres = nsIDOMDocument_QueryInterface(nsdomdoc, &IID_nsIDOMHTMLDocument, (void**)&nsdoc); - nsIDOMDocument_Release(nsdomdoc); - if(NS_FAILED(nsres)) { - ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres); - return; - } - - if(nsdoc == doc->basedoc.nsdoc) { - nsIDOMHTMLDocument_Release(nsdoc); - return; - } - - if(doc->basedoc.nsdoc) { - remove_mutation_observer(doc->nscontainer, doc->basedoc.nsdoc); - nsIDOMHTMLDocument_Release(doc->basedoc.nsdoc); - - doc_node = doc->basedoc.doc_node; - doc_node->basedoc.doc_obj = NULL; - IHTMLDocument2_Release(HTMLDOC(&doc_node->basedoc)); - doc->basedoc.doc_node = NULL; - } - - doc->basedoc.nsdoc = nsdoc; - if(!nsdoc) { - window_set_docnode(doc->basedoc.window, NULL); - return; - } - - set_mutation_observer(doc->nscontainer, nsdoc); - - hres = create_doc_from_nsdoc(nsdoc, doc, doc->basedoc.window, &doc_node); - if(FAILED(hres)) { - ERR("Could not create document: %08x\n", hres); - return; - } - - doc->basedoc.doc_node = doc_node; - window_set_docnode(doc->basedoc.window, doc_node); -} - void close_gecko(void) { TRACE("()\n"); @@ -963,13 +906,7 @@ static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface, PRUint32 statusType, const PRUnichar *status) { NSContainer *This = NSWBCHROME_THIS(iface); - TRACE("(%p)->(%d %s)\n", This, statusType, debugstr_w(status)); - - /* FIXME: This hack should be removed when we'll load all pages by URLMoniker */ - if(This->doc) - update_nsdocument(This->doc); - return NS_OK; } @@ -1678,7 +1615,7 @@ NSContainer *NSContainer_Create(HTMLDocumentObj *doc, NSContainer *parent) NSContainer *ret; nsresult nsres; - if(!load_gecko(FALSE)) + if(!load_gecko(TRUE)) return NULL; ret = heap_alloc_zero(sizeof(NSContainer)); @@ -1694,7 +1631,6 @@ NSContainer *NSContainer_Create(HTMLDocumentObj *doc, NSContainer *parent) ret->doc = doc; ret->ref = 1; - init_mutation(ret); nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID, NULL, &IID_nsIWebBrowser, (void**)&ret->webbrowser); @@ -1761,8 +1697,6 @@ NSContainer *NSContainer_Create(HTMLDocumentObj *doc, NSContainer *parent) if(NS_FAILED(nsres)) ERR("SetParentURIContentListener failed: %08x\n", nsres); - init_nsevents(ret); - nsres = nsIWebBrowser_QueryInterface(ret->webbrowser, &IID_nsIScrollable, (void**)&scrollable); if(NS_SUCCEEDED(nsres)) { nsres = nsIScrollable_SetDefaultScrollbarPreferences(scrollable, diff --git a/reactos/dll/win32/mshtml/nsevents.c b/reactos/dll/win32/mshtml/nsevents.c index f145cc63adf..7c4c09b0fa7 100644 --- a/reactos/dll/win32/mshtml/nsevents.c +++ b/reactos/dll/win32/mshtml/nsevents.c @@ -26,6 +26,8 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmcid.h" +#include "shlguid.h" #include "wine/debug.h" #include "wine/unicode.h" @@ -35,6 +37,35 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +typedef struct { + const nsIDOMEventListenerVtbl *lpDOMEventListenerVtbl; + nsDocumentEventListener *This; +} nsEventListener; + +struct nsDocumentEventListener { + nsEventListener blur_listener; + nsEventListener focus_listener; + nsEventListener keypress_listener; + nsEventListener load_listener; + nsEventListener htmlevent_listener; + + LONG ref; + + HTMLDocumentNode *doc; +}; + +static LONG release_listener(nsDocumentEventListener *This) +{ + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) + heap_free(This); + + return ref; +} + #define NSEVENTLIST_THIS(iface) DEFINE_THIS(nsEventListener, DOMEventListener, iface) static nsresult NSAPI nsDOMEventListener_QueryInterface(nsIDOMEventListener *iface, @@ -63,37 +94,44 @@ static nsresult NSAPI nsDOMEventListener_QueryInterface(nsIDOMEventListener *ifa static nsrefcnt NSAPI nsDOMEventListener_AddRef(nsIDOMEventListener *iface) { - NSContainer *This = NSEVENTLIST_THIS(iface)->This; - return nsIWebBrowserChrome_AddRef(NSWBCHROME(This)); + nsDocumentEventListener *This = NSEVENTLIST_THIS(iface)->This; + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; } static nsrefcnt NSAPI nsDOMEventListener_Release(nsIDOMEventListener *iface) { - NSContainer *This = NSEVENTLIST_THIS(iface)->This; - return nsIWebBrowserChrome_Release(NSWBCHROME(This)); + nsDocumentEventListener *This = NSEVENTLIST_THIS(iface)->This; + + return release_listener(This); } -static BOOL is_doc_child_focus(NSContainer *This) +static BOOL is_doc_child_focus(HTMLDocumentObj *doc) { HWND hwnd; - if(!This->doc) - return FALSE; - - for(hwnd = GetFocus(); hwnd && hwnd != This->doc->basedoc.doc_obj->hwnd; hwnd = GetParent(hwnd)); + for(hwnd = GetFocus(); hwnd && hwnd != doc->hwnd; hwnd = GetParent(hwnd)); return hwnd != NULL; } static nsresult NSAPI handle_blur(nsIDOMEventListener *iface, nsIDOMEvent *event) { - NSContainer *This = NSEVENTLIST_THIS(iface)->This; + HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc; + HTMLDocumentObj *doc_obj; - TRACE("(%p)\n", This); + TRACE("(%p)\n", doc); - if(!This->reset_focus && This->doc && This->doc->basedoc.doc_obj->focus && !is_doc_child_focus(This)) { - This->doc->basedoc.doc_obj->focus = FALSE; - notif_focus(This->doc); + if(!doc || !doc->basedoc.doc_obj) + return NS_ERROR_FAILURE; + doc_obj = doc->basedoc.doc_obj; + + if(!doc_obj->nscontainer->reset_focus && doc_obj->focus && !is_doc_child_focus(doc_obj)) { + doc_obj->focus = FALSE; + notif_focus(doc_obj); } return NS_OK; @@ -101,13 +139,18 @@ static nsresult NSAPI handle_blur(nsIDOMEventListener *iface, nsIDOMEvent *event static nsresult NSAPI handle_focus(nsIDOMEventListener *iface, nsIDOMEvent *event) { - NSContainer *This = NSEVENTLIST_THIS(iface)->This; + HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc; + HTMLDocumentObj *doc_obj; - TRACE("(%p)\n", This); + TRACE("(%p)\n", doc); - if(!This->reset_focus && This->doc && !This->doc->focus) { - This->doc->focus = TRUE; - notif_focus(This->doc); + if(!doc) + return NS_ERROR_FAILURE; + doc_obj = doc->basedoc.doc_obj; + + if(!doc_obj->nscontainer->reset_focus && !doc_obj->focus) { + doc_obj->focus = TRUE; + notif_focus(doc_obj); } return NS_OK; @@ -116,46 +159,96 @@ static nsresult NSAPI handle_focus(nsIDOMEventListener *iface, nsIDOMEvent *even static nsresult NSAPI handle_keypress(nsIDOMEventListener *iface, nsIDOMEvent *event) { - NSContainer *This = NSEVENTLIST_THIS(iface)->This; + HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc; + HTMLDocumentObj *doc_obj; - TRACE("(%p)->(%p)\n", This, event); + if(!doc) + return NS_ERROR_FAILURE; + doc_obj = doc->basedoc.doc_obj; - update_doc(&This->doc->basedoc, UPDATE_UI); - if(This->doc->usermode == EDITMODE) - handle_edit_event(&This->doc->basedoc, event); + TRACE("(%p)->(%p)\n", doc, event); + + update_doc(&doc_obj->basedoc, UPDATE_UI); + if(doc_obj->usermode == EDITMODE) + handle_edit_event(&doc_obj->basedoc, event); return NS_OK; } +static void handle_docobj_load(HTMLDocumentObj *doc) +{ + IOleCommandTarget *olecmd = NULL; + HRESULT hres; + + if(!doc->client) + return; + + hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); + if(SUCCEEDED(hres)) { + VARIANT state, progress; + + V_VT(&progress) = VT_I4; + V_I4(&progress) = 0; + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER, + &progress, NULL); + + V_VT(&state) = VT_I4; + V_I4(&state) = 0; + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, + &state, NULL); + + IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 103, 0, NULL, NULL); + IOleCommandTarget_Exec(olecmd, &CGID_MSHTML, IDM_PARSECOMPLETE, 0, NULL, NULL); + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_HTTPEQUIV_DONE, 0, NULL, NULL); + + IOleCommandTarget_Release(olecmd); + } +} + static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event) { - NSContainer *This = NSEVENTLIST_THIS(iface)->This; + HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc; + HTMLDocumentObj *doc_obj; nsIDOMHTMLElement *nsbody = NULL; - TRACE("(%p)\n", This); + TRACE("(%p)\n", doc); - if(!This->doc) - return NS_OK; + if(!doc) + return NS_ERROR_FAILURE; + doc_obj = doc->basedoc.doc_obj; - update_nsdocument(This->doc); - connect_scripts(This->doc->basedoc.window); + connect_scripts(doc->basedoc.window); - if(This->editor_controller) { - nsIController_Release(This->editor_controller); - This->editor_controller = NULL; + if(doc_obj->nscontainer->editor_controller) { + nsIController_Release(doc_obj->nscontainer->editor_controller); + doc_obj->nscontainer->editor_controller = NULL; } - if(This->doc->usermode == EDITMODE) - handle_edit_load(&This->doc->basedoc); + if(doc_obj->usermode == EDITMODE) + handle_edit_load(&doc_obj->basedoc); - if(!This->doc->basedoc.nsdoc) { + if(doc == doc_obj->basedoc.doc_node) + handle_docobj_load(doc_obj); + + set_ready_state(doc->basedoc.window, READYSTATE_COMPLETE); + + if(doc == doc_obj->basedoc.doc_node) { + if(doc_obj->frame) { + static const WCHAR wszDone[] = {'D','o','n','e',0}; + IOleInPlaceFrame_SetStatusText(doc_obj->frame, wszDone); + } + + update_title(doc_obj); + } + + if(!doc->nsdoc) { ERR("NULL nsdoc\n"); return NS_ERROR_FAILURE; } - nsIDOMHTMLDocument_GetBody(This->doc->basedoc.nsdoc, &nsbody); + nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody); if(nsbody) { - fire_event(This->doc->basedoc.doc_node, EVENTID_LOAD, (nsIDOMNode*)nsbody, event); + fire_event(doc, EVENTID_LOAD, (nsIDOMNode*)nsbody, event); nsIDOMHTMLElement_Release(nsbody); } @@ -164,7 +257,7 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent *event) { - NSContainer *This = NSEVENTLIST_THIS(iface)->This; + HTMLDocumentNode *doc = NSEVENTLIST_THIS(iface)->This->doc; const PRUnichar *type; nsIDOMEventTarget *event_target; nsIDOMNode *nsnode; @@ -191,7 +284,7 @@ static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent * return NS_OK; } - fire_event(This->doc->basedoc.doc_node, eid, nsnode, event); + fire_event(doc, eid, nsnode, event); nsIDOMNode_Release(nsnode); @@ -228,31 +321,40 @@ static void init_event(nsIDOMEventTarget *target, const PRUnichar *type, } -static void init_listener(nsEventListener *This, NSContainer *container, +static void init_listener(nsEventListener *This, nsDocumentEventListener *listener, const nsIDOMEventListenerVtbl *vtbl) { This->lpDOMEventListenerVtbl = vtbl; - This->This = container; + This->This = listener; } -void add_nsevent_listener(HTMLWindow *window, LPCWSTR type) +void add_nsevent_listener(HTMLDocumentNode *doc, LPCWSTR type) { nsIDOMEventTarget *target; nsresult nsres; - nsres = nsIDOMWindow_QueryInterface(window->nswindow, &IID_nsIDOMEventTarget, (void**)&target); + nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target); if(NS_FAILED(nsres)) { ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres); return; } - init_event(target, type, NSEVENTLIST(&window->doc_obj->nscontainer->htmlevent_listener), TRUE); + init_event(target, type, NSEVENTLIST(&doc->nsevent_listener->htmlevent_listener), TRUE); nsIDOMEventTarget_Release(target); } -void init_nsevents(NSContainer *This) +void release_nsevents(HTMLDocumentNode *doc) { - nsIDOMWindow *dom_window; + if(doc->nsevent_listener) { + doc->nsevent_listener->doc = NULL; + release_listener(doc->nsevent_listener); + doc->nsevent_listener = NULL; + } +} + +void init_nsevents(HTMLDocumentNode *doc) +{ + nsDocumentEventListener *listener; nsIDOMEventTarget *target; nsresult nsres; @@ -261,29 +363,31 @@ void init_nsevents(NSContainer *This) static const PRUnichar wsz_keypress[] = {'k','e','y','p','r','e','s','s',0}; static const PRUnichar wsz_load[] = {'l','o','a','d',0}; - init_listener(&This->blur_listener, This, &blur_vtbl); - init_listener(&This->focus_listener, This, &focus_vtbl); - init_listener(&This->keypress_listener, This, &keypress_vtbl); - init_listener(&This->load_listener, This, &load_vtbl); - init_listener(&This->htmlevent_listener, This, &htmlevent_vtbl); - - nsres = nsIWebBrowser_GetContentDOMWindow(This->webbrowser, &dom_window); - if(NS_FAILED(nsres)) { - ERR("GetContentDOMWindow failed: %08x\n", nsres); + listener = heap_alloc(sizeof(nsDocumentEventListener)); + if(!listener) return; - } - nsres = nsIDOMWindow_QueryInterface(dom_window, &IID_nsIDOMEventTarget, (void**)&target); - nsIDOMWindow_Release(dom_window); + listener->ref = 1; + listener->doc = doc; + + init_listener(&listener->blur_listener, listener, &blur_vtbl); + init_listener(&listener->focus_listener, listener, &focus_vtbl); + init_listener(&listener->keypress_listener, listener, &keypress_vtbl); + init_listener(&listener->load_listener, listener, &load_vtbl); + init_listener(&listener->htmlevent_listener, listener, &htmlevent_vtbl); + + doc->nsevent_listener = listener; + + nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target); if(NS_FAILED(nsres)) { ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres); return; } - init_event(target, wsz_blur, NSEVENTLIST(&This->blur_listener), TRUE); - init_event(target, wsz_focus, NSEVENTLIST(&This->focus_listener), TRUE); - init_event(target, wsz_keypress, NSEVENTLIST(&This->keypress_listener), FALSE); - init_event(target, wsz_load, NSEVENTLIST(&This->load_listener), TRUE); + init_event(target, wsz_blur, NSEVENTLIST(&listener->blur_listener), TRUE); + init_event(target, wsz_focus, NSEVENTLIST(&listener->focus_listener), TRUE); + init_event(target, wsz_keypress, NSEVENTLIST(&listener->keypress_listener), FALSE); + init_event(target, wsz_load, NSEVENTLIST(&listener->load_listener), TRUE); nsIDOMEventTarget_Release(target); } diff --git a/reactos/dll/win32/mshtml/nsiface.idl b/reactos/dll/win32/mshtml/nsiface.idl index 571c0230b09..19f29b0b663 100644 --- a/reactos/dll/win32/mshtml/nsiface.idl +++ b/reactos/dll/win32/mshtml/nsiface.idl @@ -89,6 +89,7 @@ interface nsIDocumentStateListener; interface nsIDOMCSSStyleSheet; interface nsIDOMDocumentView; interface nsIDocumentObserver; +interface nsIDOMWindow; interface IMoniker; @@ -109,7 +110,6 @@ typedef nsISupports nsISHistory; typedef nsISupports nsIWidget; typedef nsISupports nsIHttpHeaderVisitor; typedef nsISupports nsIDOMBarProp; -typedef nsISupports nsIDOMWindowCollection; typedef nsISupports nsIPrompt; typedef nsISupports nsIAuthPrompt; typedef nsISupports nsIDOMNamedNodeMap; @@ -135,7 +135,6 @@ typedef nsISupports nsIDOMHTMLTableSectionElement; typedef nsISupports nsIDOMClientRectList; typedef nsISupports nsIDOMClientRect; typedef nsISupports nsIDOMLocation; -typedef nsISupports nsIBoxObject; typedef nsISupports nsIDocument; typedef nsISupports nsIContent; typedef nsISupports nsINode; @@ -1011,6 +1010,18 @@ interface nsIDOMDocumentView : nsISupports nsresult GetDefaultView(nsIDOMAbstractView **aDefaultView); } +[ + object, + uuid(46b91d66-28e2-11d4-ab1e-0010830123b4), + local + /* FROZEN */ +] +interface nsIDOMDocumentEvent : nsISupports +{ +cpp_quote("#undef CreateEvent") + nsresult CreateEvent(const nsAString *eventType, nsIDOMEvent **_retval); +} + [ object, uuid(a6cf90ce-15b3-11d2-932e-00805f8add32), @@ -1106,6 +1117,19 @@ interface nsISelection : nsISupports nsresult ToString(PRUnichar **_retval); } +[ + object, + uuid(a6cf906f-15b3-11d2-932e-00805f8add32), + local + /* FROZEN */ +] +interface nsIDOMWindowCollection : nsISupports +{ + nsresult GetLength(PRUint32 *aLength); + nsresult Item(PRUint32 index, nsIDOMWindow **_retval); + nsresult NamedItem(const nsAString *name, nsIDOMWindow **_retval); +} + [ object, uuid(a6cf906b-15b3-11d2-932e-00805f8add32), @@ -1487,6 +1511,33 @@ interface nsIDOMHTMLIFrameElement : nsIDOMHTMLElement nsresult GetContentDocument(nsIDOMDocument **aContentDocument); } +[ + object, + uuid(a6cf90b9-15b3-11d2-932e-00805f8add32), + local + /* FROZEN */ +] +interface nsIDOMHTMLFrameElement : nsIDOMHTMLElement +{ + nsresult GetFrameBorder(nsAString *aFrameBorder); + nsresult SetFrameBorder(const nsAString *aFrameBorder); + nsresult GetLongDesc(nsAString *aLongDesc); + nsresult SetLongDesc(const nsAString *aLongDesc); + nsresult GetMarginHeight(nsAString *aMarginHeight); + nsresult SetMarginHeight(const nsAString *aMarginHeight); + nsresult GetMarginWidth(nsAString *aMarginWidth); + nsresult SetMarginWidth(const nsAString *aMarginWidth); + nsresult GetName(nsAString *aName); + nsresult SetName(const nsAString *aName); + nsresult GetNoResize(PRBool *aNoResize); + nsresult SetNoResize(PRBool aNoResize); + nsresult GetScrolling(nsAString *aScrolling); + nsresult SetScrolling(const nsAString *aScrolling); + nsresult GetSrc(nsAString *aSrc); + nsresult SetSrc(const nsAString *aSrc); + nsresult GetContentDocument(nsIDOMDocument **aContentDocument); +} + [ object, uuid(94928ab3-8b63-11d3-989d-001083010e9b), @@ -1613,6 +1664,20 @@ interface nsIWebNavigation : nsISupports nsresult SetSessionHistory(nsISHistory *aSessionHistory); } +[ + object, + uuid(570f39d0-efd0-11d3-b093-00a024ffc08c), + local + /* FROZEN */ +] +interface nsIWebProgress : nsISupports +{ + nsresult AddProgressListener(nsIWebProgressListener *aListener, PRUint32 aNotifyMask); + nsresult RemoveProgressListener(nsIWebProgressListener *aListener); + nsresult GetDOMWindow(nsIDOMWindow **aDOMWindow); + nsresult GetIsLoadingDocument(PRBool *aIsLoadingDocument); +} + [ object, uuid(343700dd-078b-42b6-a809-b9c1d7e951d0), @@ -2619,9 +2684,12 @@ interface nsIDocumentObserver : nsIMutationObserver interface nsIWineURI : nsIURL { typedef struct NSContainer NSContainer; + typedef struct HTMLWindow HTMLWindow; nsresult GetNSContainer(NSContainer **aNSContainer); nsresult SetNSContainer(NSContainer *aNSContainer); + nsresult GetWindow(HTMLWindow **aHTMLWindow); + nsresult SetWindow(HTMLWindow *aHTMLWindow); nsresult GetIsDocumentURI(PRBool *aIsDocumentURI); nsresult SetIsDocumentURI(PRBool aIsDocumentURI); nsresult GetWineURL(LPCWSTR *aURL); diff --git a/reactos/dll/win32/mshtml/nsio.c b/reactos/dll/win32/mshtml/nsio.c index d7fe4a9e1d4..97927472546 100644 --- a/reactos/dll/win32/mshtml/nsio.c +++ b/reactos/dll/win32/mshtml/nsio.c @@ -59,6 +59,7 @@ typedef struct { nsIURI *uri; nsIURL *nsurl; NSContainer *container; + windowref_t *window_ref; LPWSTR wine_url; PRBool is_doc_uri; BOOL use_wine_url; @@ -67,7 +68,7 @@ typedef struct { #define NSURI(x) ((nsIURI*) &(x)->lpWineURIVtbl) #define NSWINEURI(x) ((nsIWineURI*) &(x)->lpWineURIVtbl) -static nsresult create_uri(nsIURI*,NSContainer*,nsIWineURI**); +static nsresult create_uri(nsIURI*,HTMLWindow*,NSContainer*,nsIWineURI**); static const char *debugstr_nsacstr(const nsACString *nsstr) { @@ -128,7 +129,6 @@ static BOOL exec_shldocvw_67(HTMLDocumentObj *doc, LPCWSTR url) static BOOL before_async_open(nsChannel *channel, NSContainer *container) { HTMLDocumentObj *doc = container->doc; - IServiceProvider *service_provider; DWORD hlnf = 0; LPCWSTR uri; HRESULT hres; @@ -154,23 +154,8 @@ static BOOL before_async_open(nsChannel *channel, NSContainer *container) if(!hlnf && !exec_shldocvw_67(doc, uri)) return FALSE; - hres = IOleClientSite_QueryInterface(doc->client, &IID_IServiceProvider, - (void**)&service_provider); - if(SUCCEEDED(hres)) { - IHlinkFrame *hlink_frame; - - hres = IServiceProvider_QueryService(service_provider, &IID_IHlinkFrame, - &IID_IHlinkFrame, (void**)&hlink_frame); - IServiceProvider_Release(service_provider); - if(SUCCEEDED(hres)) { - hlink_frame_navigate(&doc->basedoc, hlink_frame, uri, channel->post_data_stream, hlnf); - IHlinkFrame_Release(hlink_frame); - - return FALSE; - } - } - - return TRUE; + hres = hlink_frame_navigate(&doc->basedoc, uri, channel->post_data_stream, hlnf); + return hres != S_OK; } #define NSCHANNEL_THIS(iface) DEFINE_THIS(nsChannel, HttpChannel, iface) @@ -518,9 +503,8 @@ static nsresult NSAPI nsChannel_GetContentType(nsIHttpChannel *iface, nsACString if(This->channel) return nsIChannel_GetContentType(This->channel, aContentType); - TRACE("returning default text/html\n"); - nsACString_SetData(aContentType, "text/html"); - return NS_OK; + WARN("unknown type\n"); + return NS_ERROR_FAILURE; } static nsresult NSAPI nsChannel_SetContentType(nsIHttpChannel *iface, @@ -647,14 +631,14 @@ static HRESULT create_mon_for_nschannel(nsChannel *channel, IMoniker **mon) hres = CreateURLMoniker(NULL, wine_url, mon); if(FAILED(hres)) - WARN("CreateURLMonikrer failed: %08x\n", hres); + WARN("CreateURLMoniker failed: %08x\n", hres); return hres; } -static NSContainer *get_nscontainer_from_load_group(nsChannel *This) +static HTMLWindow *get_window_from_load_group(nsChannel *This) { - NSContainer *container; + HTMLWindow *window; nsIChannel *channel; nsIRequest *req; nsIWineURI *wine_uri; @@ -691,79 +675,117 @@ static NSContainer *get_nscontainer_from_load_group(nsChannel *This) return NULL; } - nsIWineURI_GetNSContainer(wine_uri, &container); + nsIWineURI_GetWindow(wine_uri, &window); nsIWineURI_Release(wine_uri); - return container; + return window; } -static nsresult async_open_doc_uri(nsChannel *This, NSContainer *container, - nsIStreamListener *listener, nsISupports *context, BOOL *open) +static HTMLWindow *get_channel_window(nsChannel *This) { - IMoniker *mon; - HRESULT hres; + nsIRequestObserver *req_observer; + nsIWebProgress *web_progress; + nsIDOMWindow *nswindow; + HTMLWindow *window; + nsresult nsres; - *open = FALSE; - - if(container->bscallback) { - channelbsc_set_channel(container->bscallback, This, listener, context); - - if(container->doc && container->doc->mime) { - heap_free(This->content_type); - This->content_type = heap_strdupWtoA(container->doc->mime); - } - - return NS_OK; - }else { - BOOL cont = before_async_open(This, container); - - if(!cont) { - TRACE("canceled\n"); - return NS_ERROR_UNEXPECTED; - } - - if(!container->doc) { - return This->channel - ? nsIChannel_AsyncOpen(This->channel, listener, context) - : NS_ERROR_UNEXPECTED; - } - - hres = create_mon_for_nschannel(This, &mon); - if(FAILED(hres)) { - return NS_ERROR_UNEXPECTED; - } - set_current_mon(&container->doc->basedoc, mon); + if(!This->load_group) { + ERR("NULL load_group\n"); + return NULL; } - *open = TRUE; - return NS_OK; + nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer); + if(NS_FAILED(nsres) || !req_observer) { + ERR("GetGroupObserver failed: %08x\n", nsres); + return NULL; + } + + nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress); + nsIRequestObserver_Release(req_observer); + if(NS_FAILED(nsres)) { + ERR("Could not get nsIWebProgress iface: %08x\n", nsres); + return NULL; + } + + nsres = nsIWebProgress_GetDOMWindow(web_progress, &nswindow); + nsIWebProgress_Release(web_progress); + if(NS_FAILED(nsres) || !nswindow) { + ERR("GetDOMWindow failed: %08x\n", nsres); + return NULL; + } + + window = nswindow_to_window(nswindow); + nsIDOMWindow_Release(nswindow); + + if(window) + IHTMLWindow2_AddRef(HTMLWINDOW2(window)); + else + FIXME("NULL window for %p\n", nswindow); + return window; } -static nsresult async_open(nsChannel *This, NSContainer *container, nsIStreamListener *listener, +typedef struct { + task_t header; + HTMLDocumentNode *doc; + nsChannelBSC *bscallback; +} start_binding_task_t; + +static void start_binding_proc(task_t *_task) +{ + start_binding_task_t *task = (start_binding_task_t*)_task; + + start_binding(NULL, task->doc, (BSCallback*)task->bscallback, NULL); +} + +typedef struct { + task_t header; + HTMLWindow *window; + nsChannelBSC *bscallback; +} start_doc_binding_task_t; + +static void start_doc_binding_proc(task_t *_task) +{ + start_doc_binding_task_t *task = (start_doc_binding_task_t*)_task; + + start_binding(task->window, NULL, (BSCallback*)task->bscallback, NULL); + IUnknown_Release((IUnknown*)task->bscallback); +} + +static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_channel, nsIStreamListener *listener, nsISupports *context) { nsChannelBSC *bscallback; IMoniker *mon = NULL; - task_t *task; HRESULT hres; hres = create_mon_for_nschannel(This, &mon); if(FAILED(hres)) return NS_ERROR_UNEXPECTED; + if(is_doc_channel) + set_current_mon(window, mon); + bscallback = create_channelbsc(mon); IMoniker_Release(mon); channelbsc_set_channel(bscallback, This, listener, context); - task = heap_alloc(sizeof(task_t)); + if(is_doc_channel) { + start_doc_binding_task_t *task; - task->doc = &container->doc->basedoc; - task->task_id = TASK_START_BINDING; - task->next = NULL; - task->bscallback = bscallback; + set_window_bscallback(window, bscallback); - push_task(task); + task = heap_alloc(sizeof(start_doc_binding_task_t)); + task->window = window; + task->bscallback = bscallback; + push_task(&task->header, start_doc_binding_proc, window->task_magic); + }else { + start_binding_task_t *task = heap_alloc(sizeof(start_binding_task_t)); + + task->doc = window->doc; + task->bscallback = bscallback; + push_task(&task->header, start_binding_proc, window->doc->basedoc.task_magic); + } return NS_OK; } @@ -772,37 +794,88 @@ static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListen nsISupports *aContext) { nsChannel *This = NSCHANNEL_THIS(iface); - NSContainer *container; + HTMLWindow *window = NULL; PRBool is_doc_uri; BOOL open = TRUE; nsresult nsres = NS_OK; TRACE("(%p)->(%p %p)\n", This, aListener, aContext); - nsIWineURI_GetNSContainer(This->uri, &container); + if(TRACE_ON(mshtml)) { + LPCWSTR url; - if(!container && This->load_group) { - container = get_nscontainer_from_load_group(This); - if(container) - nsIWineURI_SetNSContainer(This->uri, container); + nsIWineURI_GetWineURL(This->uri, &url); + TRACE("opening %s\n", debugstr_w(url)); } - if(!container) { - TRACE("container = NULL\n"); + nsIWineURI_GetIsDocumentURI(This->uri, &is_doc_uri); + if(is_doc_uri) { + window = get_channel_window(This); + if(window) { + nsIWineURI_SetWindow(This->uri, window); + }else { + NSContainer *nscontainer; + + nsIWineURI_GetNSContainer(This->uri, &nscontainer); + if(nscontainer) { + BOOL b; + + /* nscontainer->doc should be NULL which means navigation to a new window */ + if(nscontainer->doc) + FIXME("nscontainer->doc = %p\n", nscontainer->doc); + + b = before_async_open(This, nscontainer); + nsIWebBrowserChrome_Release(NSWBCHROME(nscontainer)); + if(b) + FIXME("Navigation not cancelled\n"); + return NS_ERROR_UNEXPECTED; + } + } + } + + if(!window) { + nsIWineURI_GetWindow(This->uri, &window); + + if(!window && This->load_group) { + window = get_window_from_load_group(This); + if(window) + nsIWineURI_SetWindow(This->uri, window); + } + } + + if(!window) { + TRACE("window = NULL\n"); return This->channel ? nsIChannel_AsyncOpen(This->channel, aListener, aContext) : NS_ERROR_UNEXPECTED; } - nsIWineURI_GetIsDocumentURI(This->uri, &is_doc_uri); + if(is_doc_uri && (This->load_flags & LOAD_INITIAL_DOCUMENT_URI)) { + if(window->doc_obj->nscontainer->bscallback) { + NSContainer *nscontainer = window->doc_obj->nscontainer; - if(is_doc_uri && (This->load_flags & LOAD_INITIAL_DOCUMENT_URI)) - nsres = async_open_doc_uri(This, container, aListener, aContext, &open); + channelbsc_set_channel(nscontainer->bscallback, This, aListener, aContext); + + if(nscontainer->doc->mime) { + heap_free(This->content_type); + This->content_type = heap_strdupWtoA(nscontainer->doc->mime); + } + + open = FALSE; + }else { + open = before_async_open(This, window->doc_obj->nscontainer); + if(!open) { + TRACE("canceled\n"); + nsres = NS_ERROR_UNEXPECTED; + } + } + } if(open) - nsres = async_open(This, container, aListener, aContext); + nsres = async_open(This, window, is_doc_uri, aListener, aContext); - nsIWebBrowserChrome_Release(NSWBCHROME(container)); + if(window) + IHTMLWindow2_Release(HTMLWINDOW2(window)); return nsres; } @@ -1364,6 +1437,8 @@ static nsrefcnt NSAPI nsURI_Release(nsIWineURI *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { + if(This->window_ref) + windowref_release(This->window_ref); if(This->container) nsIWebBrowserChrome_Release(NSWBCHROME(This->container)); if(This->nsurl) @@ -1679,7 +1754,7 @@ static nsresult NSAPI nsURI_Equals(nsIWineURI *iface, nsIURI *other, PRBool *_re } nsIWineURI_GetWineURL(wine_uri, &other_url); - *_retval = !UrlCompareW(This->wine_url, other_url, TRUE); + *_retval = other_url && !UrlCompareW(This->wine_url, other_url, TRUE); nsIWineURI_Release(wine_uri); return NS_OK; @@ -1725,7 +1800,7 @@ static nsresult NSAPI nsURI_Clone(nsIWineURI *iface, nsIURI **_retval) } } - nsres = create_uri(nsuri, This->container, &wine_uri); + nsres = create_uri(nsuri, This->window_ref ? This->window_ref->window : NULL, This->container, &wine_uri); if(NS_FAILED(nsres)) { WARN("create_uri failed: %08x\n", nsres); return nsres; @@ -1925,12 +2000,17 @@ static nsresult NSAPI nsURL_GetRef(nsIWineURI *iface, nsACString *aRef) static nsresult NSAPI nsURL_SetRef(nsIWineURI *iface, const nsACString *aRef) { nsURI *This = NSURI_THIS(iface); + const char *refa; TRACE("(%p)->(%s)\n", This, debugstr_nsacstr(aRef)); if(This->nsurl) return nsIURL_SetRef(This->nsurl, aRef); + nsACString_GetData(aRef, &refa); + if(!*refa) + return NS_OK; + FIXME("default action not implemented\n"); return NS_ERROR_NOT_IMPLEMENTED; } @@ -2098,6 +2178,48 @@ static nsresult NSAPI nsURI_SetNSContainer(nsIWineURI *iface, NSContainer *aCont return NS_OK; } +static nsresult NSAPI nsURI_GetWindow(nsIWineURI *iface, HTMLWindow **aHTMLWindow) +{ + nsURI *This = NSURI_THIS(iface); + + TRACE("(%p)->(%p)\n", This, aHTMLWindow); + + if(This->window_ref && This->window_ref->window) { + IHTMLWindow2_AddRef(HTMLWINDOW2(This->window_ref->window)); + *aHTMLWindow = This->window_ref->window; + }else { + *aHTMLWindow = NULL; + } + + return NS_OK; +} + +static nsresult NSAPI nsURI_SetWindow(nsIWineURI *iface, HTMLWindow *aHTMLWindow) +{ + nsURI *This = NSURI_THIS(iface); + + TRACE("(%p)->(%p)\n", This, aHTMLWindow); + + if(This->window_ref) { + if(This->window_ref->window == aHTMLWindow) + return NS_OK; + TRACE("Changing %p -> %p\n", This->window_ref->window, aHTMLWindow); + windowref_release(This->window_ref); + } + + if(aHTMLWindow) { + windowref_addref(aHTMLWindow->window_ref); + This->window_ref = aHTMLWindow->window_ref; + + if(aHTMLWindow->doc_obj) + nsIWineURI_SetNSContainer(NSWINEURI(This), aHTMLWindow->doc_obj->nscontainer); + }else { + This->window_ref = NULL; + } + + return NS_OK; +} + static nsresult NSAPI nsURI_GetIsDocumentURI(nsIWineURI *iface, PRBool *aIsDocumentURI) { nsURI *This = NSURI_THIS(iface); @@ -2210,26 +2332,24 @@ static const nsIWineURIVtbl nsWineURIVtbl = { nsURL_GetRelativeSpec, nsURI_GetNSContainer, nsURI_SetNSContainer, + nsURI_GetWindow, + nsURI_SetWindow, nsURI_GetIsDocumentURI, nsURI_SetIsDocumentURI, nsURI_GetWineURL, nsURI_SetWineURL }; -static nsresult create_uri(nsIURI *uri, NSContainer *container, nsIWineURI **_retval) +static nsresult create_uri(nsIURI *uri, HTMLWindow *window, NSContainer *container, nsIWineURI **_retval) { - nsURI *ret = heap_alloc(sizeof(nsURI)); + nsURI *ret = heap_alloc_zero(sizeof(nsURI)); ret->lpWineURIVtbl = &nsWineURIVtbl; ret->ref = 1; ret->uri = uri; - ret->container = container; - ret->wine_url = NULL; - ret->is_doc_uri = FALSE; - ret->use_wine_url = FALSE; - if(container) - nsIWebBrowserChrome_AddRef(NSWBCHROME(container)); + nsIWineURI_SetNSContainer(NSWINEURI(ret), container); + nsIWineURI_SetWindow(NSWINEURI(ret), window); if(uri) nsIURI_QueryInterface(uri, &IID_nsIURL, (void**)&ret->nsurl); @@ -2466,7 +2586,7 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval) { const char *spec = NULL; - NSContainer *nscontainer = NULL; + HTMLWindow *window = NULL; nsIURI *uri = NULL; LPCWSTR base_wine_url = NULL; nsIWineURI *base_wine_uri = NULL, *wine_uri; @@ -2510,20 +2630,20 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * if(aBaseURI) { nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsIWineURI, (void**)&base_wine_uri); if(NS_SUCCEEDED(nsres)) { - nsIWineURI_GetNSContainer(base_wine_uri, &nscontainer); + nsIWineURI_GetWindow(base_wine_uri, &window); nsIWineURI_GetWineURL(base_wine_uri, &base_wine_url); }else { TRACE("Could not get base nsIWineURI: %08x\n", nsres); } } - TRACE("nscontainer = %p\n", nscontainer); + TRACE("window = %p\n", window); - nsres = create_uri(uri, nscontainer, &wine_uri); + nsres = create_uri(uri, window, NULL, &wine_uri); *_retval = (nsIURI*)wine_uri; - if(nscontainer) - nsIWebBrowserChrome_Release(NSWBCHROME(nscontainer)); + if(window) + IHTMLWindow2_Release(HTMLWINDOW2(window)); if(base_wine_url) { WCHAR url[INTERNET_MAX_URL_LENGTH], rel_url[INTERNET_MAX_URL_LENGTH]; diff --git a/reactos/dll/win32/mshtml/olecmd.c b/reactos/dll/win32/mshtml/olecmd.c index c2f6fef22b1..b54f06420fb 100644 --- a/reactos/dll/win32/mshtml/olecmd.c +++ b/reactos/dll/win32/mshtml/olecmd.c @@ -543,9 +543,9 @@ static HRESULT exec_editmode(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, This->doc_obj->usermode = EDITMODE; - if(This->doc_obj->mon) { + if(This->window->mon) { CLSID clsid = IID_NULL; - hres = IMoniker_GetClassID(This->doc_obj->mon, &clsid); + hres = IMoniker_GetClassID(This->window->mon, &clsid); if(SUCCEEDED(hres)) { /* We should use IMoniker::Save here */ FIXME("Use CLSID %s\n", debugstr_guid(&clsid)); @@ -555,7 +555,7 @@ static HRESULT exec_editmode(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, if(This->doc_obj->frame) IOleInPlaceFrame_SetStatusText(This->doc_obj->frame, NULL); - This->doc_obj->readystate = READYSTATE_UNINITIALIZED; + This->window->readystate = READYSTATE_UNINITIALIZED; if(This->doc_obj->client) { IOleCommandTarget *cmdtrg; @@ -588,11 +588,11 @@ static HRESULT exec_editmode(HTMLDocument *This, DWORD cmdexecopt, VARIANT *in, update_doc(This, UPDATE_UI); - if(This->doc_obj->mon) { + if(This->window->mon) { /* FIXME: We should find nicer way to do this */ - remove_doc_tasks(This); + remove_target_tasks(This->task_magic); - mon = This->doc_obj->mon; + mon = This->window->mon; IMoniker_AddRef(mon); }else { static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; diff --git a/reactos/dll/win32/mshtml/persist.c b/reactos/dll/win32/mshtml/persist.c index f89cde8afcd..f3d23bd1021 100644 --- a/reactos/dll/win32/mshtml/persist.c +++ b/reactos/dll/win32/mshtml/persist.c @@ -48,38 +48,115 @@ static BOOL use_gecko_script(LPCWSTR url) && strncmpiW(aboutW, url, sizeof(aboutW)/sizeof(WCHAR)); } -void set_current_mon(HTMLDocument *This, IMoniker *mon) +void set_current_mon(HTMLWindow *This, IMoniker *mon) { HRESULT hres; - if(This->doc_obj->mon) { - IMoniker_Release(This->doc_obj->mon); - This->doc_obj->mon = NULL; + if(This->mon) { + IMoniker_Release(This->mon); + This->mon = NULL; } - if(This->doc_obj->url) { - CoTaskMemFree(This->doc_obj->url); - This->doc_obj->url = NULL; + if(This->url) { + CoTaskMemFree(This->url); + This->url = NULL; } if(!mon) return; IMoniker_AddRef(mon); - This->doc_obj->mon = mon; + This->mon = mon; - hres = IMoniker_GetDisplayName(mon, NULL, NULL, &This->doc_obj->url); + hres = IMoniker_GetDisplayName(mon, NULL, NULL, &This->url); if(FAILED(hres)) WARN("GetDisplayName failed: %08x\n", hres); - set_script_mode(This->window, use_gecko_script(This->doc_obj->url) ? SCRIPTMODE_GECKO : SCRIPTMODE_ACTIVESCRIPT); + set_script_mode(This, use_gecko_script(This->url) ? SCRIPTMODE_GECKO : SCRIPTMODE_ACTIVESCRIPT); } -static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BOOL *bind_complete) +static void set_progress_proc(task_t *_task) +{ + docobj_task_t *task = (docobj_task_t*)_task; + IOleCommandTarget *olecmd = NULL; + HTMLDocumentObj *doc = task->doc; + HRESULT hres; + + TRACE("(%p)\n", doc); + + if(doc->client) + IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); + + if(olecmd) { + VARIANT progress_max, progress; + + V_VT(&progress_max) = VT_I4; + V_I4(&progress_max) = 0; /* FIXME */ + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSMAX, OLECMDEXECOPT_DONTPROMPTUSER, + &progress_max, NULL); + + V_VT(&progress) = VT_I4; + V_I4(&progress) = 0; /* FIXME */ + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER, + &progress, NULL); + } + + if(doc->usermode == EDITMODE && doc->hostui) { + DOCHOSTUIINFO hostinfo; + + memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO)); + hostinfo.cbSize = sizeof(DOCHOSTUIINFO); + hres = IDocHostUIHandler_GetHostInfo(doc->hostui, &hostinfo); + if(SUCCEEDED(hres)) + /* FIXME: use hostinfo */ + TRACE("hostinfo = {%u %08x %08x %s %s}\n", + hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick, + debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS)); + } +} + +static void set_downloading_proc(task_t *_task) +{ + HTMLDocumentObj *doc = ((docobj_task_t*)_task)->doc; + IOleCommandTarget *olecmd; + HRESULT hres; + + TRACE("(%p)\n", doc); + + if(doc->frame) + IOleInPlaceFrame_SetStatusText(doc->frame, NULL /* FIXME */); + + if(!doc->client) + return; + + hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); + if(SUCCEEDED(hres)) { + VARIANT var; + + V_VT(&var) = VT_I4; + V_I4(&var) = 1; + + IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, + &var, NULL); + IOleCommandTarget_Release(olecmd); + } + + if(doc->hostui) { + IDropTarget *drop_target = NULL; + + hres = IDocHostUIHandler_GetDropTarget(doc->hostui, NULL /* FIXME */, &drop_target); + if(drop_target) { + FIXME("Use IDropTarget\n"); + IDropTarget_Release(drop_target); + } + } +} + +static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc) { nsChannelBSC *bscallback; LPOLESTR url = NULL; - task_t *task; + docobj_task_t *task; HRESULT hres; nsresult nsres; @@ -113,8 +190,7 @@ static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BO } } - This->doc_obj->readystate = READYSTATE_LOADING; - call_property_onchanged(&This->cp_propnotif, DISPID_READYSTATE); + set_ready_state(This->window, READYSTATE_LOADING); update_doc(This, UPDATE_TITLE); HTMLDocument_LockContainer(This->doc_obj, TRUE); @@ -127,7 +203,7 @@ static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BO TRACE("got url: %s\n", debugstr_w(url)); - set_current_mon(This, mon); + set_current_mon(This->window, mon); if(This->doc_obj->client) { VARIANT silent, offline; @@ -166,22 +242,14 @@ static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BO bscallback = create_channelbsc(mon); if(This->doc_obj->frame) { - task = heap_alloc(sizeof(task_t)); - - task->doc = This; - task->task_id = TASK_SETPROGRESS; - task->next = NULL; - - push_task(task); + task = heap_alloc(sizeof(docobj_task_t)); + task->doc = This->doc_obj; + push_task(&task->header, set_progress_proc, This->doc_obj->basedoc.task_magic); } - task = heap_alloc(sizeof(task_t)); - - task->doc = This; - task->task_id = TASK_SETDOWNLOADSTATE; - task->next = NULL; - - push_task(task); + task = heap_alloc(sizeof(docobj_task_t)); + task->doc = This->doc_obj; + push_task(&task->header, set_downloading_proc, This->doc_obj->basedoc.task_magic); if(This->doc_obj->nscontainer) { This->doc_obj->nscontainer->bscallback = bscallback; @@ -196,16 +264,21 @@ static HRESULT set_moniker(HTMLDocument *This, IMoniker *mon, IBindCtx *pibc, BO } } - set_document_bscallback(This, bscallback); + set_window_bscallback(This->window, bscallback); IUnknown_Release((IUnknown*)bscallback); CoTaskMemFree(url); - if(bind_complete) - *bind_complete = FALSE; return S_OK; } -static HRESULT get_doc_string(HTMLDocument *This, char **str) +void set_ready_state(HTMLWindow *window, READYSTATE readystate) +{ + window->readystate = readystate; + if(window->doc_obj->basedoc.window == window) + call_property_onchanged(&window->doc_obj->basedoc.cp_propnotif, DISPID_READYSTATE); +} + +static HRESULT get_doc_string(HTMLDocumentNode *This, char **str) { nsIDOMNode *nsnode; LPCWSTR strw; @@ -282,19 +355,15 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva IMoniker *pimkName, LPBC pibc, DWORD grfMode) { HTMLDocument *This = PERSISTMON_THIS(iface); - BOOL bind_complete = FALSE; HRESULT hres; TRACE("(%p)->(%x %p %p %08x)\n", This, fFullyAvailable, pimkName, pibc, grfMode); - hres = set_moniker(This, pimkName, pibc, &bind_complete); + hres = set_moniker(This, pimkName, pibc); if(FAILED(hres)) return hres; - if(!bind_complete) - return start_binding(This, (BSCallback*)This->doc_obj->bscallback, pibc); - - return S_OK; + return start_binding(This->window, NULL, (BSCallback*)This->window->bscallback, pibc); } static HRESULT WINAPI PersistMoniker_Save(IPersistMoniker *iface, IMoniker *pimkName, @@ -318,11 +387,11 @@ static HRESULT WINAPI PersistMoniker_GetCurMoniker(IPersistMoniker *iface, IMoni TRACE("(%p)->(%p)\n", This, ppimkName); - if(!This->doc_obj->mon) + if(!This->window || !This->window->mon) return E_UNEXPECTED; - IMoniker_AddRef(This->doc_obj->mon); - *ppimkName = This->doc_obj->mon; + IMoniker_AddRef(This->window->mon); + *ppimkName = This->window->mon; return S_OK; } @@ -462,7 +531,7 @@ static HRESULT WINAPI PersistFile_Save(IPersistFile *iface, LPCOLESTR pszFileNam return E_FAIL; } - hres = get_doc_string(This, &str); + hres = get_doc_string(This->doc_node, &str); if(SUCCEEDED(hres)) WriteFile(file, str, strlen(str), &written, NULL); @@ -551,12 +620,12 @@ static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM return hres; } - hres = set_moniker(This, mon, NULL, NULL); + hres = set_moniker(This, mon, NULL); IMoniker_Release(mon); if(FAILED(hres)) return hres; - return channelbsc_load_stream(This->doc_obj->bscallback, pStm); + return channelbsc_load_stream(This->window->bscallback, pStm); } static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStm, @@ -569,7 +638,7 @@ static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM TRACE("(%p)->(%p %x)\n", This, pStm, fClearDirty); - hres = get_doc_string(This, &str); + hres = get_doc_string(This->doc_node, &str); if(FAILED(hres)) return hres; diff --git a/reactos/dll/win32/mshtml/script.c b/reactos/dll/win32/mshtml/script.c index 5c83e1ed294..7df0dd6e9f3 100644 --- a/reactos/dll/win32/mshtml/script.c +++ b/reactos/dll/win32/mshtml/script.c @@ -620,11 +620,14 @@ static void parse_text(ScriptHost *script_host, LPCWSTR text) VariantInit(&var); memset(&excepinfo, 0, sizeof(excepinfo)); + TRACE(">>>\n"); hres = IActiveScriptParse64_ParseScriptText(script_host->parse, text, windowW, NULL, script_endW, 0, 0, SCRIPTTEXT_ISVISIBLE|SCRIPTTEXT_HOSTMANAGESSOURCE, &var, &excepinfo); - if(FAILED(hres)) - WARN("ParseScriptText failed: %08x\n", hres); + if(SUCCEEDED(hres)) + TRACE("<<<\n"); + else + WARN("<<< %08x\n", hres); } @@ -645,7 +648,7 @@ static void parse_extern_script(ScriptHost *script_host, LPCWSTR src) if(FAILED(hres)) return; - hres = bind_mon_to_buffer(&script_host->window->doc_obj->basedoc, mon, (void**)&buf, &size); + hres = bind_mon_to_buffer(script_host->window->doc, mon, (void**)&buf, &size); IMoniker_Release(mon); if(FAILED(hres)) return; diff --git a/reactos/dll/win32/mshtml/secmgr.c b/reactos/dll/win32/mshtml/secmgr.c index be56e5dbda9..8938943fb56 100644 --- a/reactos/dll/win32/mshtml/secmgr.c +++ b/reactos/dll/win32/mshtml/secmgr.c @@ -76,9 +76,9 @@ static HRESULT WINAPI InternetHostSecurityManager_ProcessUrlAction(IInternetHost HTMLDocumentNode *This = HOSTSECMGR_THIS(iface); const WCHAR *url; - TRACE("%p)->(%d %p %d %p %d %x %x)\n", This, dwAction, pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved); + TRACE("(%p)->(%d %p %d %p %d %x %x)\n", This, dwAction, pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved); - url = This->basedoc.doc_obj->url ? This->basedoc.doc_obj->url : about_blankW; + url = This->basedoc.window->url ? This->basedoc.window->url : about_blankW; return IInternetSecurityManager_ProcessUrlAction(This->secmgr, url, dwAction, pPolicy, cbPolicy, pContext, cbContext, dwFlags, dwReserved); @@ -124,7 +124,7 @@ static HRESULT WINAPI InternetHostSecurityManager_QueryCustomPolicy(IInternetHos TRACE("(%p)->(%s %p %p %p %d %x)\n", This, debugstr_guid(guidKey), ppPolicy, pcbPolicy, pContext, cbContext, dwReserved); - url = This->basedoc.doc_obj->url ? This->basedoc.doc_obj->url : about_blankW; + url = This->basedoc.window->url ? This->basedoc.window->url : about_blankW; hres = IInternetSecurityManager_QueryCustomPolicy(This->secmgr, url, guidKey, ppPolicy, pcbPolicy, pContext, cbContext, dwReserved); diff --git a/reactos/dll/win32/mshtml/selection.c b/reactos/dll/win32/mshtml/selection.c index f1909beadc2..4c670a6063d 100644 --- a/reactos/dll/win32/mshtml/selection.c +++ b/reactos/dll/win32/mshtml/selection.c @@ -156,12 +156,12 @@ static HRESULT WINAPI HTMLSelectionObject_createRange(IHTMLSelectionObject *ifac TRACE("nsrange_cnt = 0\n"); - if(!This->doc->basedoc.nsdoc) { + if(!This->doc->nsdoc) { WARN("nsdoc is NULL\n"); return E_UNEXPECTED; } - nsres = nsIDOMHTMLDocument_GetBody(This->doc->basedoc.nsdoc, &nsbody); + nsres = nsIDOMHTMLDocument_GetBody(This->doc->nsdoc, &nsbody); if(NS_FAILED(nsres) || !nsbody) { ERR("Could not get body: %08x\n", nsres); return E_FAIL; diff --git a/reactos/dll/win32/mshtml/task.c b/reactos/dll/win32/mshtml/task.c index a387e6ac656..e6b94a2d228 100644 --- a/reactos/dll/win32/mshtml/task.c +++ b/reactos/dll/win32/mshtml/task.c @@ -27,8 +27,6 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" -#include "mshtmcid.h" -#include "shlguid.h" #include "wine/debug.h" @@ -49,10 +47,14 @@ typedef struct { struct list entry; } task_timer_t; -void push_task(task_t *task) +void push_task(task_t *task, task_proc_t proc, LONG magic) { thread_data_t *thread_data = get_thread_data(TRUE); + task->target_magic = magic; + task->proc = proc; + task->next = NULL; + if(thread_data->task_queue_tail) thread_data->task_queue_tail->next = task; else @@ -87,7 +89,7 @@ static void release_task_timer(HWND thread_hwnd, task_timer_t *timer) heap_free(timer); } -void remove_doc_tasks(const HTMLDocument *doc) +void remove_target_tasks(LONG target) { thread_data_t *thread_data = get_thread_data(FALSE); struct list *liter, *ltmp; @@ -99,7 +101,7 @@ void remove_doc_tasks(const HTMLDocument *doc) LIST_FOR_EACH_SAFE(liter, ltmp, &thread_data->timer_list) { timer = LIST_ENTRY(liter, task_timer_t, entry); - if(timer->doc == doc) + if(timer->doc->task_magic == target) release_task_timer(thread_data->thread_hwnd, timer); } @@ -109,11 +111,11 @@ void remove_doc_tasks(const HTMLDocument *doc) } while(thread_data->task_queue_head - && thread_data->task_queue_head->doc == doc) + && thread_data->task_queue_head->target_magic == target) pop_task(); for(iter = thread_data->task_queue_head; iter; iter = iter->next) { - while(iter->next && iter->next->doc == doc) { + while(iter->next && iter->next->target_magic == target) { tmp = iter->next; iter->next = tmp->next; heap_free(tmp); @@ -124,6 +126,12 @@ void remove_doc_tasks(const HTMLDocument *doc) } } +LONG get_task_target_magic(void) +{ + static LONG magic = 0x10000000; + return InterlockedIncrement(&magic); +} + static BOOL queue_timer(thread_data_t *thread_data, task_timer_t *timer) { task_timer_t *iter; @@ -191,178 +199,10 @@ HRESULT clear_task_timer(HTMLDocument *doc, BOOL interval, DWORD id) return S_OK; } -static void set_downloading(HTMLDocumentObj *doc) +void parse_complete(HTMLDocumentObj *doc) { - IOleCommandTarget *olecmd; - HRESULT hres; - TRACE("(%p)\n", doc); - if(doc->frame) - IOleInPlaceFrame_SetStatusText(doc->frame, NULL /* FIXME */); - - if(!doc->client) - return; - - hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); - if(SUCCEEDED(hres)) { - VARIANT var; - - V_VT(&var) = VT_I4; - V_I4(&var) = 1; - - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, - &var, NULL); - IOleCommandTarget_Release(olecmd); - } - - if(doc->hostui) { - IDropTarget *drop_target = NULL; - - hres = IDocHostUIHandler_GetDropTarget(doc->hostui, NULL /* FIXME */, &drop_target); - if(drop_target) { - FIXME("Use IDropTarget\n"); - IDropTarget_Release(drop_target); - } - } -} - -/* Calls undocumented 69 cmd of CGID_Explorer */ -static void call_explorer_69(HTMLDocumentObj *doc) -{ - IOleCommandTarget *olecmd; - VARIANT var; - HRESULT hres; - - if(!doc->client) - return; - - hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd); - if(FAILED(hres)) - return; - - VariantInit(&var); - hres = IOleCommandTarget_Exec(olecmd, &CGID_Explorer, 69, 0, NULL, &var); - IOleCommandTarget_Release(olecmd); - if(SUCCEEDED(hres) && V_VT(&var) != VT_NULL) - FIXME("handle result\n"); -} - -static void set_parsecomplete(HTMLDocument *doc) -{ - IOleCommandTarget *olecmd = NULL; - - TRACE("(%p)\n", doc); - - if(doc->doc_obj->usermode == EDITMODE) - init_editor(doc); - - call_explorer_69(doc->doc_obj); - call_property_onchanged(&doc->cp_propnotif, 1005); - call_explorer_69(doc->doc_obj); - - /* FIXME: IE7 calls EnableModelless(TRUE), EnableModelless(FALSE) and sets interactive state here */ - - doc->doc_obj->readystate = READYSTATE_INTERACTIVE; - call_property_onchanged(&doc->cp_propnotif, DISPID_READYSTATE); - - if(doc->doc_obj->client) - IOleClientSite_QueryInterface(doc->doc_obj->client, &IID_IOleCommandTarget, (void**)&olecmd); - - if(olecmd) { - VARIANT state, progress; - - V_VT(&progress) = VT_I4; - V_I4(&progress) = 0; - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER, - &progress, NULL); - - V_VT(&state) = VT_I4; - V_I4(&state) = 0; - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETDOWNLOADSTATE, OLECMDEXECOPT_DONTPROMPTUSER, - &state, NULL); - - IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 103, 0, NULL, NULL); - IOleCommandTarget_Exec(olecmd, &CGID_MSHTML, IDM_PARSECOMPLETE, 0, NULL, NULL); - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_HTTPEQUIV_DONE, 0, NULL, NULL); - - IOleCommandTarget_Release(olecmd); - } - - doc->doc_obj->readystate = READYSTATE_COMPLETE; - call_property_onchanged(&doc->cp_propnotif, DISPID_READYSTATE); - - if(doc->doc_obj->frame) { - static const WCHAR wszDone[] = {'D','o','n','e',0}; - IOleInPlaceFrame_SetStatusText(doc->doc_obj->frame, wszDone); - } - - update_title(doc->doc_obj); -} - -static void set_progress(HTMLDocument *doc) -{ - IOleCommandTarget *olecmd = NULL; - HRESULT hres; - - TRACE("(%p)\n", doc); - - if(doc->doc_obj->client) - IOleClientSite_QueryInterface(doc->doc_obj->client, &IID_IOleCommandTarget, (void**)&olecmd); - - if(olecmd) { - VARIANT progress_max, progress; - - V_VT(&progress_max) = VT_I4; - V_I4(&progress_max) = 0; /* FIXME */ - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSMAX, OLECMDEXECOPT_DONTPROMPTUSER, - &progress_max, NULL); - - V_VT(&progress) = VT_I4; - V_I4(&progress) = 0; /* FIXME */ - IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS, OLECMDEXECOPT_DONTPROMPTUSER, - &progress, NULL); - } - - if(doc->doc_obj->usermode == EDITMODE && doc->doc_obj->hostui) { - DOCHOSTUIINFO hostinfo; - - memset(&hostinfo, 0, sizeof(DOCHOSTUIINFO)); - hostinfo.cbSize = sizeof(DOCHOSTUIINFO); - hres = IDocHostUIHandler_GetHostInfo(doc->doc_obj->hostui, &hostinfo); - if(SUCCEEDED(hres)) - /* FIXME: use hostinfo */ - TRACE("hostinfo = {%u %08x %08x %s %s}\n", - hostinfo.cbSize, hostinfo.dwFlags, hostinfo.dwDoubleClick, - debugstr_w(hostinfo.pchHostCss), debugstr_w(hostinfo.pchHostNS)); - } -} - -static void task_start_binding(HTMLDocument *doc, BSCallback *bscallback) -{ - if(doc) - start_binding(doc, bscallback, NULL); - IUnknown_Release((IUnknown*)bscallback); -} - -static void process_task(task_t *task) -{ - switch(task->task_id) { - case TASK_SETDOWNLOADSTATE: - set_downloading(task->doc->doc_obj); - break; - case TASK_PARSECOMPLETE: - set_parsecomplete(task->doc); - break; - case TASK_SETPROGRESS: - set_progress(task->doc); - break; - case TASK_START_BINDING: - task_start_binding(task->doc, (BSCallback*)task->bscallback); - break; - default: - ERR("Wrong task_id %d\n", task->task_id); - } } static void call_timer_disp(IDispatch *disp) @@ -433,7 +273,7 @@ static LRESULT WINAPI hidden_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa if(!task) break; - process_task(task); + task->proc(task); heap_free(task); } diff --git a/reactos/dll/win32/mshtml/txtrange.c b/reactos/dll/win32/mshtml/txtrange.c index 56aa33f9a20..c068c06014c 100644 --- a/reactos/dll/win32/mshtml/txtrange.c +++ b/reactos/dll/win32/mshtml/txtrange.c @@ -342,7 +342,7 @@ static nsIDOMNode *prev_node(HTMLTxtRange *This, nsIDOMNode *iter) if(!iter) { nsIDOMHTMLElement *nselem; - nsIDOMHTMLDocument_GetBody(This->doc->basedoc.nsdoc, &nselem); + nsIDOMHTMLDocument_GetBody(This->doc->nsdoc, &nselem); nsIDOMElement_GetLastChild(nselem, &tmp); if(!tmp) return (nsIDOMNode*)nselem; @@ -1139,7 +1139,7 @@ static HRESULT WINAPI HTMLTxtRange_put_text(IHTMLTxtRange *iface, BSTR v) return MSHTML_E_NODOC; nsAString_Init(&text_str, v); - nsres = nsIDOMHTMLDocument_CreateTextNode(This->doc->basedoc.nsdoc, &text_str, &text_node); + nsres = nsIDOMHTMLDocument_CreateTextNode(This->doc->nsdoc, &text_str, &text_node); nsAString_Finish(&text_str); if(NS_FAILED(nsres)) { ERR("CreateTextNode failed: %08x\n", nsres); @@ -1348,7 +1348,7 @@ static HRESULT WINAPI HTMLTxtRange_expand(IHTMLTxtRange *iface, BSTR Unit, VARIA nsIDOMHTMLElement *nsbody = NULL; nsresult nsres; - nsres = nsIDOMHTMLDocument_GetBody(This->doc->basedoc.nsdoc, &nsbody); + nsres = nsIDOMHTMLDocument_GetBody(This->doc->nsdoc, &nsbody); if(NS_FAILED(nsres) || !nsbody) { ERR("Could not get body: %08x\n", nsres); break; @@ -1778,28 +1778,22 @@ static HRESULT WINAPI RangeCommandTarget_QueryStatus(IOleCommandTarget *iface, c static HRESULT exec_indent(HTMLTxtRange *This, VARIANT *in, VARIANT *out) { + nsIDOMHTMLElement *blockquote_elem, *p_elem; nsIDOMDocumentFragment *fragment; - nsIDOMElement *blockquote_elem, *p_elem; nsIDOMNode *tmp; - nsAString tag_str; static const PRUnichar blockquoteW[] = {'B','L','O','C','K','Q','U','O','T','E',0}; static const PRUnichar pW[] = {'P',0}; TRACE("(%p)->(%p %p)\n", This, in, out); - if(!This->doc->basedoc.nsdoc) { + if(!This->doc->nsdoc) { WARN("NULL nsdoc\n"); return E_NOTIMPL; } - nsAString_Init(&tag_str, blockquoteW); - nsIDOMHTMLDocument_CreateElement(This->doc->basedoc.nsdoc, &tag_str, &blockquote_elem); - nsAString_Finish(&tag_str); - - nsAString_Init(&tag_str, pW); - nsIDOMDocument_CreateElement(This->doc->basedoc.nsdoc, &tag_str, &p_elem); - nsAString_Finish(&tag_str); + create_nselem(This->doc, blockquoteW, &blockquote_elem); + create_nselem(This->doc, pW, &p_elem); nsIDOMRange_ExtractContents(This->nsrange, &fragment); nsIDOMElement_AppendChild(p_elem, (nsIDOMNode*)fragment, &tmp); diff --git a/reactos/include/psdk/mshtmdid.h b/reactos/include/psdk/mshtmdid.h index 7dc257ac17a..59b04a4c83d 100644 --- a/reactos/include/psdk/mshtmdid.h +++ b/reactos/include/psdk/mshtmdid.h @@ -98,6 +98,8 @@ #define DISPID_DOMTEXTNODE DISPID_NORMAL_FIRST #define DISPID_GENERIC DISPID_NORMAL_FIRST #define DISPID_DOMIMPLEMENTATION DISPID_NORMAL_FIRST +#define DISPID_DOCUMENTCOMPATIBLEINFO DISPID_NORMAL_FIRST +#define DISPID_DOCUMENTCOMPATIBLEINFOCOLLECTION DISPID_NORMAL_FIRST #define DISPID_IE8_ANCHOR DISPID_IE8_NORMAL_FIRST #define DISPID_IE8_AREA DISPID_IE8_NORMAL_FIRST @@ -562,100 +564,9 @@ #define DISPID_EVPROP_ONBEFOREACTIVATE (DISPID_EVENTS+90) #define DISPID_EVPROP_ONFOCUSIN (DISPID_EVENTS+91) #define DISPID_EVPROP_ONFOCUSOUT (DISPID_EVENTS+92) -#define DISPID_EVPROPS_COUNT 93 - -#define DISPID_EVMETH_ONMOUSEOVER STDDISPID_XOBJ_ONMOUSEOVER -#define DISPID_EVMETH_ONMOUSEOUT STDDISPID_XOBJ_ONMOUSEOUT -#define DISPID_EVMETH_ONMOUSEDOWN DISPID_MOUSEDOWN -#define DISPID_EVMETH_ONMOUSEUP DISPID_MOUSEUP -#define DISPID_EVMETH_ONMOUSEMOVE DISPID_MOUSEMOVE -#define DISPID_EVMETH_ONKEYDOWN DISPID_KEYDOWN -#define DISPID_EVMETH_ONKEYUP DISPID_KEYUP -#define DISPID_EVMETH_ONKEYPRESS DISPID_KEYPRESS -#define DISPID_EVMETH_ONCLICK DISPID_CLICK -#define DISPID_EVMETH_ONDBLCLICK DISPID_DBLCLICK -#define DISPID_EVMETH_ONSELECT DISPID_ONSELECT -#define DISPID_EVMETH_ONSUBMIT DISPID_ONSUBMIT -#define DISPID_EVMETH_ONRESET DISPID_ONRESET -#define DISPID_EVMETH_ONHELP STDDISPID_XOBJ_ONHELP -#define DISPID_EVMETH_ONFOCUS STDDISPID_XOBJ_ONFOCUS -#define DISPID_EVMETH_ONBLUR STDDISPID_XOBJ_ONBLUR -#define DISPID_EVMETH_ONROWEXIT STDDISPID_XOBJ_ONROWEXIT -#define DISPID_EVMETH_ONROWENTER STDDISPID_XOBJ_ONROWENTER -#define DISPID_EVMETH_ONBOUNCE DISPID_ONBOUNCE -#define DISPID_EVMETH_ONBEFOREUPDATE STDDISPID_XOBJ_BEFOREUPDATE -#define DISPID_EVMETH_ONAFTERUPDATE STDDISPID_XOBJ_AFTERUPDATE -#define DISPID_EVMETH_ONBEFOREDRAGOVER EVENTID_CommonCtrlEvent_BeforeDragOver -#define DISPID_EVMETH_ONBEFOREDROPORPASTE EVENTID_CommonCtrlEvent_BeforeDropOrPaste -#define DISPID_EVMETH_ONREADYSTATECHANGE DISPID_READYSTATECHANGE -#define DISPID_EVMETH_ONFINISH DISPID_ONFINISH -#define DISPID_EVMETH_ONSTART DISPID_ONSTART -#define DISPID_EVMETH_ONABORT DISPID_ONABORT -#define DISPID_EVMETH_ONERROR DISPID_ONERROR -#define DISPID_EVMETH_ONCHANGE DISPID_ONCHANGE -#define DISPID_EVMETH_ONSCROLL DISPID_ONSCROLL -#define DISPID_EVMETH_ONLOAD DISPID_ONLOAD -#define DISPID_EVMETH_ONUNLOAD DISPID_ONUNLOAD -#define DISPID_EVMETH_ONLAYOUT DISPID_ONLAYOUT -#define DISPID_EVMETH_ONDRAGSTART STDDISPID_XOBJ_ONDRAGSTART -#define DISPID_EVMETH_ONRESIZE DISPID_ONRESIZE -#define DISPID_EVMETH_ONSELECTSTART STDDISPID_XOBJ_ONSELECTSTART -#define DISPID_EVMETH_ONERRORUPDATE STDDISPID_XOBJ_ERRORUPDATE -#define DISPID_EVMETH_ONBEFOREUNLOAD DISPID_ONBEFOREUNLOAD -#define DISPID_EVMETH_ONDATASETCHANGED STDDISPID_XOBJ_ONDATASETCHANGED -#define DISPID_EVMETH_ONDATAAVAILABLE STDDISPID_XOBJ_ONDATAAVAILABLE -#define DISPID_EVMETH_ONDATASETCOMPLETE STDDISPID_XOBJ_ONDATASETCOMPLETE -#define DISPID_EVMETH_ONFILTER STDDISPID_XOBJ_ONFILTER -#define DISPID_EVMETH_ONCHANGEFOCUS DISPID_ONCHANGEFOCUS -#define DISPID_EVMETH_ONCHANGEBLUR DISPID_ONCHANGEBLUR -#define DISPID_EVMETH_ONLOSECAPTURE STDDISPID_XOBJ_ONLOSECAPTURE -#define DISPID_EVMETH_ONPROPERTYCHANGE STDDISPID_XOBJ_ONPROPERTYCHANGE -#define DISPID_EVMETH_ONPERSISTSAVE DISPID_ONPERSISTSAVE -#define DISPID_EVMETH_ONDRAG STDDISPID_XOBJ_ONDRAG -#define DISPID_EVMETH_ONDRAGEND STDDISPID_XOBJ_ONDRAGEND -#define DISPID_EVMETH_ONDRAGENTER STDDISPID_XOBJ_ONDRAGENTER -#define DISPID_EVMETH_ONDRAGOVER STDDISPID_XOBJ_ONDRAGOVER -#define DISPID_EVMETH_ONDRAGLEAVE STDDISPID_XOBJ_ONDRAGLEAVE -#define DISPID_EVMETH_ONDROP STDDISPID_XOBJ_ONDROP -#define DISPID_EVMETH_ONCUT STDDISPID_XOBJ_ONCUT -#define DISPID_EVMETH_ONCOPY STDDISPID_XOBJ_ONCOPY -#define DISPID_EVMETH_ONPASTE STDDISPID_XOBJ_ONPASTE -#define DISPID_EVMETH_ONBEFORECUT STDDISPID_XOBJ_ONBEFORECUT -#define DISPID_EVMETH_ONBEFORECOPY STDDISPID_XOBJ_ONBEFORECOPY -#define DISPID_EVMETH_ONBEFOREPASTE STDDISPID_XOBJ_ONBEFOREPASTE -#define DISPID_EVMETH_ONPERSISTLOAD DISPID_ONPERSISTLOAD -#define DISPID_EVMETH_ONROWSDELETE STDDISPID_XOBJ_ONROWSDELETE -#define DISPID_EVMETH_ONROWSINSERTED STDDISPID_XOBJ_ONROWSINSERTED -#define DISPID_EVMETH_ONCELLCHANGE STDDISPID_XOBJ_ONCELLCHANGE -#define DISPID_EVMETH_ONCONTEXTMENU DISPID_ONCONTEXTMENU -#define DISPID_EVMETH_ONBEFOREPRINT DISPID_ONBEFOREPRINT -#define DISPID_EVMETH_ONAFTERPRINT DISPID_ONAFTERPRINT -#define DISPID_EVMETH_ONSTOP DISPID_ONSTOP -#define DISPID_EVMETH_ONBEFOREEDITFOCUS DISPID_ONBEFOREEDITFOCUS -#define DISPID_EVMETH_ONMOUSEHOVER DISPID_ONMOUSEHOVER -#define DISPID_EVMETH_ONCONTENTREADY DISPID_ONCONTENTREADY -#define DISPID_EVMETH_ONLAYOUTCOMPLETE DISPID_ONLAYOUTCOMPLETE -#define DISPID_EVMETH_ONPAGE DISPID_ONPAGE -#define DISPID_EVMETH_ONLINKEDOVERFLOW DISPID_ONLINKEDOVERFLOW -#define DISPID_EVMETH_ONMOUSEWHEEL DISPID_ONMOUSEWHEEL -#define DISPID_EVMETH_ONBEFOREDEACTIVAT DISPID_ONBEFOREDEACTIVATE -#define DISPID_EVMETH_ONMOVE DISPID_ONMOVE -#define DISPID_EVMETH_ONCONTROLSELECT DISPID_ONCONTROLSELECT -#define DISPID_EVMETH_ONSELECTIONCHANGE DISPID_ONSELECTIONCHANGE -#define DISPID_EVMETH_ONMOVESTART DISPID_ONMOVESTART -#define DISPID_EVMETH_ONMOVEEND DISPID_ONMOVEEND -#define DISPID_EVMETH_ONRESIZESTART DISPID_ONRESIZESTART -#define DISPID_EVMETH_ONRESIZEEND DISPID_ONRESIZEEND -#define DISPID_EVMETH_ONMOUSEENTER DISPID_ONMOUSEENTER -#define DISPID_EVMETH_ONMOUSELEAVE DISPID_ONMOUSELEAVE -#define DISPID_EVMETH_ONACTIVATE DISPID_ONACTIVATE -#define DISPID_EVMETH_ONDEACTIVATE DISPID_ONDEACTIVATE -#define DISPID_EVMETH_ONMULTILAYOUTCLEANUP DISPID_ONMULTILAYOUTCLEANUP -#define DISPID_EVMETH_ONBEFOREACTIVATE DISPID_ONBEFOREACTIVATE -#define DISPID_EVMETH_ONFOCUSIN DISPID_ONFOCUSIN -#define DISPID_EVMETH_ONFOCUSOUT DISPID_ONFOCUSOUT -#define DISPID_EVPROPS_COUNT 93 - +#define DISPID_EVPROP_ONSTORAGE (DISPID_EVENTS+93) +#define DISPID_EVPROP_ONSTORAGECOMMIT (DISPID_EVENTS+94) +#define DISPID_EVPROPS_COUNT 95 #define DISPID_EVMETH_ONMOUSEOVER STDDISPID_XOBJ_ONMOUSEOVER #define DISPID_EVMETH_ONMOUSEOUT STDDISPID_XOBJ_ONMOUSEOUT @@ -747,6 +658,8 @@ #define DISPID_EVMETH_ONBEFOREACTIVATE DISPID_ONBEFOREACTIVATE #define DISPID_EVMETH_ONFOCUSIN DISPID_ONFOCUSIN #define DISPID_EVMETH_ONFOCUSOUT DISPID_ONFOCUSOUT +#define DISPID_EVMETH_ONSTORAGE DISPID_ONSTORAGE +#define DISPID_EVMETH_ONSTORAGECOMMIT DISPID_ONSTORAGECOMMIT #define DISPID_ONABORT (DISPID_NORMAL_FIRST) #define DISPID_ONCHANGE (DISPID_NORMAL_FIRST+1) @@ -795,6 +708,8 @@ #define DISPID_ONBEFOREACTIVATE (DISPID_NORMAL_FIRST+47) #define DISPID_ONFOCUSIN (DISPID_NORMAL_FIRST+48) #define DISPID_ONFOCUSOUT (DISPID_NORMAL_FIRST+49) +#define DISPID_ONSTORAGE (DISPID_NORMAL_FIRST+50) +#define DISPID_ONSTORAGECOMMIT (DISPID_NORMAL_FIRST+51) /* HTMLDocumentEvents */ #define DISPID_HTMLDOCUMENTEVENTS_ONHELP DISPID_EVMETH_ONHELP @@ -1014,6 +929,13 @@ #define DISPID_IHTMLDOCUMENT5_ONBEFOREDEACTIVATE DISPID_EVPROP_ONBEFOREDEACTIVATE #define DISPID_IHTMLDOCUMENT5_COMPATMODE DISPID_OMDOCUMENT+102 +/* IHTMLDocument6 */ +#define DISPID_IHTMLDOCUMENT6_COMPATIBLE DISPID_OMDOCUMENT+103 +#define DISPID_IHTMLDOCUMENT6_DOCUMENTMODE DISPID_OMDOCUMENT+104 +#define DISPID_IHTMLDOCUMENT6_ONSTORAGE DISPID_EVPROP_ONSTORAGE +#define DISPID_IHTMLDOCUMENT6_ONSTORAGECOMMIT DISPID_EVPROP_ONSTORAGECOMMIT +#define DISPID_IHTMLDOCUMENT6_IE8_GETELEMENTBYID DISPID_OMDOCUMENT+105 +#define DISPID_IHTMLDOCUMENT6_UPDATESETTINGS DISPID_OMDOCUMENT+106 /* IHTMLElementCollection */ #define DISPID_IHTMLELEMENTCOLLECTION_LENGTH DISPID_COLLECTION @@ -2095,6 +2017,14 @@ #define DISPID_IHTMLDOMATTRIBUTE2_HASCHILDNODES DISPID_DOMATTRIBUTE+19 #define DISPID_IHTMLDOMATTRIBUTE2_CLONENODE DISPID_DOMATTRIBUTE+20 +/* IHTMLDocumentCompatibleInfo */ +#define DISPID_IHTMLDOCUMENTCOMPATIBLEINFO_USERAGENT DISPID_DOCUMENTCOMPATIBLEINFO +#define DISPID_IHTMLDOCUMENTCOMPATIBLEINFO_VERSION DISPID_DOCUMENTCOMPATIBLEINFO+1 + +/* IHTMLDocumentCompatibleInfoCollection */ +#define DISPID_IHTMLDOCUMENTCOMPATIBLEINFOCOLLECTION_ITEM DISPID_DOCUMENTCOMPATIBLEINFOCOLLECTION +#define DISPID_IHTMLDOCUMENTCOMPATIBLEINFOCOLLECTION_LENGTH DISPID_DOCUMENTCOMPATIBLEINFOCOLLECTION+1 + /* IHTMLBodyElement */ #define DISPID_IHTMLBODYELEMENT_BACKGROUND DISPID_A_BACKGROUNDIMAGE #define DISPID_IHTMLBODYELEMENT_BGPROPERTIES DISPID_A_BACKGROUNDATTACHMENT diff --git a/reactos/include/psdk/mshtml.idl b/reactos/include/psdk/mshtml.idl index 6b694e1deae..f004e74ae14 100644 --- a/reactos/include/psdk/mshtml.idl +++ b/reactos/include/psdk/mshtml.idl @@ -3685,6 +3685,42 @@ interface IHTMLDOMImplementation : IDispatch [retval, out] VARIANT_BOOL *pfHasFeature); } +/***************************************************************************** + * IHTMLDocumentCompatibleInfo interface + */ +[ + odl, + oleautomation, + dual, + uuid(3051041a-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLDocumentCompatibleInfo : IDispatch +{ + [propget, id(DISPID_IHTMLDOCUMENTCOMPATIBLEINFO_USERAGENT)] + HRESULT userAgent([retval, out] BSTR *p); + + [propget, id(DISPID_IHTMLDOCUMENTCOMPATIBLEINFO_VERSION)] + HRESULT version([retval, out] BSTR *p); +} + +/***************************************************************************** + * IHTMLDocumentCompatibleInfoCollection interface + */ +[ + odl, + oleautomation, + dual, + uuid(30510418-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLDocumentCompatibleInfoCollection : IDispatch +{ + [propget, id(DISPID_IHTMLDOCUMENTCOMPATIBLEINFOCOLLECTION_LENGTH)] + HRESULT length([retval, out] long *p); + + [id(DISPID_IHTMLDOCUMENTCOMPATIBLEINFOCOLLECTION_ITEM)] + HRESULT item([in] long i, [retval, out]IHTMLDocumentCompatibleInfo **p); +} + /***************************************************************************** * DispHTMLDOMTextNode dispinterface */ @@ -6586,7 +6622,7 @@ interface IHTMLImgElement : IDispatch odl, oleautomation, dual, - uuid(3050F38E-98B5-11CF-BB82-00AAA0BDCE0B) + uuid(3050F38E-98B5-11CF-BB82-00AA00BDCE0B) ] interface IHTMLImageElementFactory : IDispatch { @@ -11740,6 +11776,44 @@ interface IHTMLDocument5 : IDispatch HRESULT compatMode([retval, out] BSTR *p); } +/***************************************************************************** + * IHTMLDocument6 interface + */ +[ + odl, + oleautomation, + dual, + uuid(30510417-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLDocument6 : IDispatch +{ + [propget, id(DISPID_IHTMLDOCUMENT6_COMPATIBLE)] + HRESULT compatible([retval, out] IHTMLDocumentCompatibleInfoCollection **p); + + [propget, id(DISPID_IHTMLDOCUMENT6_DOCUMENTMODE)] + HRESULT documentMode([retval, out] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT6_ONSTORAGE), displaybind, bindable] + HRESULT onstorage([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT6_ONSTORAGE), displaybind, bindable] + HRESULT onstorage([out] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT6_ONSTORAGECOMMIT), displaybind, bindable] + HRESULT onstoragecommit([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT6_ONSTORAGECOMMIT), displaybind, bindable] + HRESULT onstoragecommit([out] VARIANT *p); + + [id(DISPID_IHTMLDOCUMENT6_IE8_GETELEMENTBYID)] + HRESULT getElementById( + [in] BSTR bstrId, + [retval, out] IHTMLElement2 **p); + + [id(DISPID_IHTMLDOCUMENT6_UPDATESETTINGS)] + HRESULT updateSettings(); +} + /***************************************************************************** * DispHTMLDocument dispinterface */ @@ -12316,6 +12390,30 @@ methods: [propget, id(DISPID_IHTMLDOCUMENT5_COMPATMODE)] BSTR compatMode(); + [propget, id(DISPID_IHTMLDOCUMENT6_COMPATIBLE)] + IHTMLDocumentCompatibleInfoCollection *compatible(); + + [propget, id(DISPID_IHTMLDOCUMENT6_DOCUMENTMODE)] + VARIANT documentMode(); + + [propput, id(DISPID_IHTMLDOCUMENT6_ONSTORAGE), displaybind, bindable] + void onstorage(VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT6_ONSTORAGE), displaybind, bindable] + VARIANT onstorage(); + + [propput, id(DISPID_IHTMLDOCUMENT6_ONSTORAGECOMMIT), displaybind, bindable] + void onstoragecommit(VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT6_ONSTORAGECOMMIT), displaybind, bindable] + VARIANT onstoragecommit(); + + [id(DISPID_IHTMLDOCUMENT6_IE8_GETELEMENTBYID)] + IHTMLElement2 *ie8_getElementById([in] BSTR bstrId); + + [id(DISPID_IHTMLDOCUMENT6_UPDATESETTINGS)] + void updateSettings(); + WINE_HTMLDOMNODE_DISPINTERFACE_DECL; } @@ -12334,6 +12432,7 @@ coclass HTMLDocument interface IHTMLDocument3; interface IHTMLDocument4; interface IHTMLDocument5; + interface IHTMLDocument6; interface IHTMLDOMNode; interface IHTMLDOMNode2; } From 5bc70bf808347cdb9d927e75c4be806456b5e865 Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Mon, 16 Nov 2009 00:26:56 +0000 Subject: [PATCH 062/140] Update ScummVM Link to the Version 1.0.0. Congrats to the ScummVM Team reaching Final State after 8 years of work. Best wishes for the future from us. svn path=/trunk/; revision=44190 --- reactos/base/applications/rapps/rapps/scummvm.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/base/applications/rapps/rapps/scummvm.txt b/reactos/base/applications/rapps/rapps/scummvm.txt index 91114aace1e..8c201eae424 100644 --- a/reactos/base/applications/rapps/rapps/scummvm.txt +++ b/reactos/base/applications/rapps/rapps/scummvm.txt @@ -2,13 +2,13 @@ [Section] Name = ScummVM -Version = 0.13.1 +Version = 1.0.0 Licence = GPL Description = Sam and Max, Day of the Tentacle, etc on ReactOS. -Size = 2.9MB +Size = 3.1MB Category = 4 URLSite = http://scummvm.org/ -URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scummvm/scummvm-0.13.1-win32.exe +URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.0.0/scummvm-1.0.0-win32.exe CDPath = none From fe383756c1c2fa311ba55b768b2a66777a25cbeb Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Mon, 16 Nov 2009 01:13:42 +0000 Subject: [PATCH 063/140] sync msi to wine 1.1.33 svn path=/trunk/; revision=44191 --- reactos/dll/win32/msi/action.c | 39 ++++++++------- reactos/dll/win32/msi/alter.c | 5 +- reactos/dll/win32/msi/appsearch.c | 3 +- reactos/dll/win32/msi/create.c | 5 +- reactos/dll/win32/msi/delete.c | 7 +-- reactos/dll/win32/msi/dialog.c | 61 ++++++++++++++++++++++-- reactos/dll/win32/msi/distinct.c | 7 +-- reactos/dll/win32/msi/insert.c | 19 ++++---- reactos/dll/win32/msi/install.c | 73 +++++++++++++++++++++++++++-- reactos/dll/win32/msi/join.c | 8 ++-- reactos/dll/win32/msi/media.c | 21 ++++++--- reactos/dll/win32/msi/msi.c | 35 +++++++++----- reactos/dll/win32/msi/msi_main.c | 13 ++--- reactos/dll/win32/msi/msipriv.h | 10 ++-- reactos/dll/win32/msi/msiquery.c | 14 ++++-- reactos/dll/win32/msi/msiserver.idl | 1 + reactos/dll/win32/msi/package.c | 37 +++++++++++---- reactos/dll/win32/msi/query.h | 8 +++- reactos/dll/win32/msi/select.c | 11 +++-- reactos/dll/win32/msi/sql.tab.c | 3 +- reactos/dll/win32/msi/sql.y | 3 +- reactos/dll/win32/msi/storages.c | 6 ++- reactos/dll/win32/msi/streams.c | 6 ++- reactos/dll/win32/msi/table.c | 13 ++++- reactos/dll/win32/msi/update.c | 7 +-- reactos/dll/win32/msi/where.c | 15 +++--- 26 files changed, 319 insertions(+), 111 deletions(-) diff --git a/reactos/dll/win32/msi/action.c b/reactos/dll/win32/msi/action.c index a6af7cc12e4..3a11c616a82 100644 --- a/reactos/dll/win32/msi/action.c +++ b/reactos/dll/win32/msi/action.c @@ -4888,7 +4888,6 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package ) static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags ) { LPCWSTR cptr = *name; - LPCWSTR ptr = *value; static const WCHAR prefix[] = {'[','~',']',0}; static const int prefix_len = 3; @@ -4919,18 +4918,22 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags ) return ERROR_FUNCTION_FAILED; } - if (!strncmpW(ptr, prefix, prefix_len)) + if (*value) { - *flags |= ENV_MOD_APPEND; - *value += lstrlenW(prefix); - } - else if (lstrlenW(*value) >= prefix_len) - { - ptr += lstrlenW(ptr) - prefix_len; - if (!lstrcmpW(ptr, prefix)) + LPCWSTR ptr = *value; + if (!strncmpW(ptr, prefix, prefix_len)) { - *flags |= ENV_MOD_PREFIX; - /* the "[~]" will be removed by deformat_string */; + *flags |= ENV_MOD_APPEND; + *value += lstrlenW(prefix); + } + else if (lstrlenW(*value) >= prefix_len) + { + ptr += lstrlenW(ptr) - prefix_len; + if (!lstrcmpW(ptr, prefix)) + { + *flags |= ENV_MOD_PREFIX; + /* the "[~]" will be removed by deformat_string */; + } } } @@ -4978,8 +4981,7 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param ) if (res != ERROR_SUCCESS) goto done; - deformat_string(package, value, &deformatted); - if (!deformatted) + if (value && !deformat_string(package, value, &deformatted)) { res = ERROR_OUTOFMEMORY; goto done; @@ -5066,7 +5068,7 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param ) } } } - else + else if (value) { size = (lstrlenW(value) + 1) * sizeof(WCHAR); newval = msi_alloc(size); @@ -5079,8 +5081,13 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param ) lstrcpyW(newval, value); } - TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval)); - res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size); + if (newval) + { + TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval)); + res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size); + } + else + res = ERROR_SUCCESS; done: if (env) RegCloseKey(env); diff --git a/reactos/dll/win32/msi/alter.c b/reactos/dll/win32/msi/alter.c index 0f750d0166e..a62b13e9352 100644 --- a/reactos/dll/win32/msi/alter.c +++ b/reactos/dll/win32/msi/alter.c @@ -183,11 +183,12 @@ static UINT ALTER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col } static UINT ALTER_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { MSIALTERVIEW *av = (MSIALTERVIEW*)view; - TRACE("%p %d %p %p %p\n", av, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", av, n, name, type, temporary, table_name ); return ERROR_FUNCTION_FAILED; } diff --git a/reactos/dll/win32/msi/appsearch.c b/reactos/dll/win32/msi/appsearch.c index 4ef4087cb9d..95daabb40bb 100644 --- a/reactos/dll/win32/msi/appsearch.c +++ b/reactos/dll/win32/msi/appsearch.c @@ -445,7 +445,8 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNAT if (sz == 0) goto end; - if ((ptr = strchrW((LPWSTR)value, '"')) && (end = strchrW(++ptr, '"'))) + if ((regType == REG_SZ || regType == REG_EXPAND_SZ) && + (ptr = strchrW((LPWSTR)value, '"')) && (end = strchrW(++ptr, '"'))) *end = '\0'; else ptr = (LPWSTR)value; diff --git a/reactos/dll/win32/msi/create.c b/reactos/dll/win32/msi/create.c index 63cd373dbdc..2e13d592552 100644 --- a/reactos/dll/win32/msi/create.c +++ b/reactos/dll/win32/msi/create.c @@ -91,11 +91,12 @@ static UINT CREATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT CREATE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { MSICREATEVIEW *cv = (MSICREATEVIEW*)view; - TRACE("%p %d %p %p %p\n", cv, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", cv, n, name, type, temporary, table_name ); return ERROR_FUNCTION_FAILED; } diff --git a/reactos/dll/win32/msi/delete.c b/reactos/dll/win32/msi/delete.c index c824d9e0f23..210fc9e8aac 100644 --- a/reactos/dll/win32/msi/delete.c +++ b/reactos/dll/win32/msi/delete.c @@ -127,17 +127,18 @@ static UINT DELETE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT DELETE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view; - TRACE("%p %d %p %p %p\n", dv, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", dv, n, name, type, temporary, table_name ); if( !dv->table ) return ERROR_FUNCTION_FAILED; return dv->table->ops->get_column_info( dv->table, n, name, - type, temporary ); + type, temporary, table_name); } static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, diff --git a/reactos/dll/win32/msi/dialog.c b/reactos/dll/win32/msi/dialog.c index 3f1b5710f88..a22091f95fa 100644 --- a/reactos/dll/win32/msi/dialog.c +++ b/reactos/dll/win32/msi/dialog.c @@ -606,6 +606,8 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, func = MSI_RecordGetInteger( rec , 1 ); val = MSI_RecordGetInteger( rec , 2 ); + TRACE("progress: func %u, val %u\n", func, val); + switch (func) { case 0: /* init */ @@ -618,10 +620,12 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control, break; case 2: /* move */ ctrl->progress_current += val; - SendMessageW(ctrl->hwnd, PBM_SETPOS, 100*(ctrl->progress_current/ctrl->progress_max), 0); + if (ctrl->progress_current > ctrl->progress_max) + ctrl->progress_current = ctrl->progress_max; + SendMessageW(ctrl->hwnd, PBM_SETPOS, MulDiv(100, ctrl->progress_current, ctrl->progress_max), 0); break; default: - ERR("Unknown progress message %d\n", func); + FIXME("Unknown progress message %u\n", func); break; } } @@ -681,6 +685,10 @@ static msi_control *msi_dialog_add_control( msi_dialog *dialog, name = MSI_RecordGetString( rec, 2 ); attributes = MSI_RecordGetInteger( rec, 8 ); text = MSI_RecordGetString( rec, 10 ); + + TRACE("%s, %s, %08x, %s, %08x\n", debugstr_w(szCls), debugstr_w(name), + attributes, debugstr_w(text), style); + if( attributes & msidbControlAttributesVisible ) style |= WS_VISIBLE; if( ~attributes & msidbControlAttributesEnabled ) @@ -1571,8 +1579,14 @@ end: static UINT msi_dialog_progress_bar( msi_dialog *dialog, MSIRECORD *rec ) { msi_control *control; + DWORD attributes, style; - control = msi_dialog_add_control( dialog, rec, PROGRESS_CLASSW, WS_VISIBLE ); + style = WS_VISIBLE; + attributes = MSI_RecordGetInteger( rec, 8 ); + if( !(attributes & msidbControlAttributesProgress95) ) + style |= PBS_SMOOTH; + + control = msi_dialog_add_control( dialog, rec, PROGRESS_CLASSW, style ); if( !control ) return ERROR_FUNCTION_FAILED; @@ -2600,15 +2614,44 @@ static void msi_dialog_vcl_add_columns( msi_dialog *dialog, msi_control *control } } +static LONGLONG msi_vcl_get_cost( msi_dialog *dialog ) +{ + MSIFEATURE *feature; + INT each_cost; + LONGLONG total_cost = 0; + + LIST_FOR_EACH_ENTRY( feature, &dialog->package->features, MSIFEATURE, entry ) + { + if (ERROR_SUCCESS == (MSI_GetFeatureCost(dialog->package, feature, + MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &each_cost))) + { + /* each_cost is in 512-byte units */ + total_cost += each_cost * 512; + } + if (ERROR_SUCCESS == (MSI_GetFeatureCost(dialog->package, feature, + MSICOSTTREE_SELFONLY, INSTALLSTATE_ABSENT, &each_cost))) + { + /* each_cost is in 512-byte units */ + total_cost -= each_cost * 512; + } + } + return total_cost; +} + static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control ) { ULARGE_INTEGER total, free; + LONGLONG difference, cost; WCHAR size_text[MAX_PATH]; + WCHAR cost_text[MAX_PATH]; LPWSTR drives, ptr; LVITEMW lvitem; DWORD size; int i = 0; + cost = msi_vcl_get_cost(dialog); + StrFormatByteSizeW(cost, cost_text, MAX_PATH); + size = GetLogicalDriveStringsW( 0, NULL ); if ( !size ) return; @@ -2628,6 +2671,7 @@ static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control SendMessageW( control->hwnd, LVM_INSERTITEMW, 0, (LPARAM)&lvitem ); GetDiskFreeSpaceExW(ptr, &free, &total, NULL); + difference = free.QuadPart - cost; StrFormatByteSizeW(total.QuadPart, size_text, MAX_PATH); lvitem.iSubItem = 1; @@ -2641,6 +2685,17 @@ static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control lvitem.cchTextMax = lstrlenW(size_text) + 1; SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem ); + lvitem.iSubItem = 3; + lvitem.pszText = cost_text; + lvitem.cchTextMax = lstrlenW(cost_text) + 1; + SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem ); + + StrFormatByteSizeW(difference, size_text, MAX_PATH); + lvitem.iSubItem = 4; + lvitem.pszText = size_text; + lvitem.cchTextMax = lstrlenW(size_text) + 1; + SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem ); + ptr += lstrlenW(ptr) + 1; i++; } diff --git a/reactos/dll/win32/msi/distinct.c b/reactos/dll/win32/msi/distinct.c index 1e0cc2fba9c..06beece8c77 100644 --- a/reactos/dll/win32/msi/distinct.c +++ b/reactos/dll/win32/msi/distinct.c @@ -205,17 +205,18 @@ static UINT DISTINCT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT * } static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view; - TRACE("%p %d %p %p %p\n", dv, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", dv, n, name, type, temporary, table_name ); if( !dv->table ) return ERROR_FUNCTION_FAILED; return dv->table->ops->get_column_info( dv->table, n, name, - type, temporary ); + type, temporary, table_name ); } static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, diff --git a/reactos/dll/win32/msi/insert.c b/reactos/dll/win32/msi/insert.c index 0a1fbe6de77..61807e9534e 100644 --- a/reactos/dll/win32/msi/insert.c +++ b/reactos/dll/win32/msi/insert.c @@ -114,8 +114,8 @@ static BOOL msi_columns_in_order(MSIINSERTVIEW *iv, UINT col_count) for (i = 1; i <= col_count; i++) { - iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL); - iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL); + iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL, NULL); + iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL, NULL); res = lstrcmpW(a, b); msi_free(a); @@ -157,13 +157,14 @@ static UINT msi_arrange_record(MSIINSERTVIEW *iv, MSIRECORD **values) for (colidx = 1; colidx <= val_count; colidx++) { - r = iv->sv->ops->get_column_info(iv->sv, colidx, &a, NULL, NULL); + r = iv->sv->ops->get_column_info(iv->sv, colidx, &a, NULL, NULL, NULL); if (r != ERROR_SUCCESS) goto err; for (i = 1; i <= col_count; i++) { - r = iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL); + r = iv->table->ops->get_column_info(iv->table, i, &b, NULL, + NULL, NULL); if (r != ERROR_SUCCESS) goto err; @@ -200,7 +201,8 @@ static BOOL row_has_null_primary_keys(MSIINSERTVIEW *iv, MSIRECORD *row) for (i = 1; i <= col_count; i++) { - r = iv->table->ops->get_column_info(iv->table, i, NULL, &type, NULL); + r = iv->table->ops->get_column_info(iv->table, i, NULL, &type, + NULL, NULL); if (r != ERROR_SUCCESS) return FALSE; @@ -291,18 +293,19 @@ static UINT INSERT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT INSERT_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view; MSIVIEW *sv; - TRACE("%p %d %p %p %p\n", iv, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", iv, n, name, type, temporary, table_name ); sv = iv->sv; if( !sv ) return ERROR_FUNCTION_FAILED; - return sv->ops->get_column_info( sv, n, name, type, temporary ); + return sv->ops->get_column_info( sv, n, name, type, temporary, table_name ); } static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row) diff --git a/reactos/dll/win32/msi/install.c b/reactos/dll/win32/msi/install.c index 606caba1345..1a535eb0273 100644 --- a/reactos/dll/win32/msi/install.c +++ b/reactos/dll/win32/msi/install.c @@ -934,8 +934,24 @@ UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature, UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature, MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost) { - FIXME("(%d %s %i %i %p): stub\n", hInstall, debugstr_a(szFeature), - iCostTree, iState, piCost); + LPWSTR szwFeature = NULL; + UINT rc; + + szwFeature = strdupAtoW(szFeature); + + rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost); + + msi_free(szwFeature); + + return rc; +} + +UINT MSI_GetFeatureCost(MSIPACKAGE *package, MSIFEATURE *feature, + MSICOSTTREE iCostTree, INSTALLSTATE iState, + LPINT piCost) +{ + FIXME("(%s %i %i %p): not implemented yet\n", + debugstr_w(feature->Feature), iCostTree, iState, piCost); if (piCost) *piCost = 0; return ERROR_SUCCESS; } @@ -946,10 +962,57 @@ UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature, UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature, MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost) { - FIXME("(%d %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature), + MSIPACKAGE *package; + MSIFEATURE *feature; + UINT ret; + + TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature), iCostTree, iState, piCost); - if (piCost) *piCost = 0; - return ERROR_SUCCESS; + + package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE); + if (!package) + { + HRESULT hr; + BSTR feature; + IWineMsiRemotePackage *remote_package; + + remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall); + if (!remote_package) + return ERROR_INVALID_HANDLE; + + feature = SysAllocString(szFeature); + if (!feature) + { + IWineMsiRemotePackage_Release(remote_package); + return ERROR_OUTOFMEMORY; + } + + hr = IWineMsiRemotePackage_GetFeatureCost(remote_package, feature, + iCostTree, iState, piCost); + + SysFreeString(feature); + IWineMsiRemotePackage_Release(remote_package); + + if (FAILED(hr)) + { + if (HRESULT_FACILITY(hr) == FACILITY_WIN32) + return HRESULT_CODE(hr); + + return ERROR_FUNCTION_FAILED; + } + + return ERROR_SUCCESS; + } + + feature = get_loaded_feature(package, szFeature); + + if (feature) + ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost); + else + ret = ERROR_UNKNOWN_FEATURE; + + msiobj_release( &package->hdr ); + return ret; } /*********************************************************************** diff --git a/reactos/dll/win32/msi/join.c b/reactos/dll/win32/msi/join.c index 35db2fef160..1aeb17cdc03 100644 --- a/reactos/dll/win32/msi/join.c +++ b/reactos/dll/win32/msi/join.c @@ -194,13 +194,14 @@ static UINT JOIN_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols } static UINT JOIN_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name ) { MSIJOINVIEW *jv = (MSIJOINVIEW*)view; JOINTABLE *table; UINT cols = 0; - TRACE("%p %d %p %p %p\n", jv, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", jv, n, name, type, temporary, table_name ); if (n == 0 || n > jv->columns) return ERROR_FUNCTION_FAILED; @@ -209,7 +210,8 @@ static UINT JOIN_get_column_info( struct tagMSIVIEW *view, { if (n <= cols + table->columns) return table->view->ops->get_column_info(table->view, n - cols, - name, type, temporary); + name, type, temporary, + table_name); cols += table->columns; } diff --git a/reactos/dll/win32/msi/media.c b/reactos/dll/win32/msi/media.c index 0ec76bd1ca9..67cb7dc22eb 100644 --- a/reactos/dll/win32/msi/media.c +++ b/reactos/dll/win32/msi/media.c @@ -70,7 +70,6 @@ static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root) static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi) { - LPSTR msg; LPWSTR error, error_dialog; LPWSTR source_dir; UINT r = ERROR_SUCCESS; @@ -78,24 +77,34 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi) static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0}; if ((msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) == - INSTALLUILEVEL_NONE && !gUIHandlerA) + INSTALLUILEVEL_NONE && !gUIHandlerA && !gUIHandlerW && !gUIHandlerRecord) return ERROR_SUCCESS; error = generate_error_string(package, 1302, 1, mi->disk_prompt); error_dialog = msi_dup_property(package, error_prop); source_dir = msi_dup_property(package, cszSourceDir); - while (r == ERROR_SUCCESS && - !source_matches_volume(mi, source_dir)) + while (r == ERROR_SUCCESS && !source_matches_volume(mi, source_dir)) { r = msi_spawn_error_dialog(package, error_dialog, error); - if (gUIHandlerA) + if (gUIHandlerW) { - msg = strdupWtoA(error); + gUIHandlerW(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, error); + } + else if (gUIHandlerA) + { + char *msg = strdupWtoA(error); gUIHandlerA(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, msg); msi_free(msg); } + else if (gUIHandlerRecord) + { + MSIHANDLE rec = MsiCreateRecord(1); + MsiRecordSetStringW(rec, 0, error); + gUIHandlerRecord(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, rec); + MsiCloseHandle(rec); + } } msi_free(error); diff --git a/reactos/dll/win32/msi/msi.c b/reactos/dll/win32/msi/msi.c index 14f8f134365..2515714ce73 100644 --- a/reactos/dll/win32/msi/msi.c +++ b/reactos/dll/win32/msi/msi.c @@ -1902,10 +1902,12 @@ INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler, { INSTALLUI_HANDLERA prev = gUIHandlerA; - TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext); + TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext); + gUIHandlerA = puiHandler; - gUIFilter = dwMessageFilter; - gUIContext = pvContext; + gUIHandlerW = NULL; + gUIFilter = dwMessageFilter; + gUIContext = pvContext; return prev; } @@ -1915,10 +1917,12 @@ INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler, { INSTALLUI_HANDLERW prev = gUIHandlerW; - TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext); + TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext); + + gUIHandlerA = NULL; gUIHandlerW = puiHandler; - gUIFilter = dwMessageFilter; - gUIContext = pvContext; + gUIFilter = dwMessageFilter; + gUIContext = pvContext; return prev; } @@ -3591,13 +3595,20 @@ UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated ) /*********************************************************************** * MsiSetExternalUIRecord [MSI.@] */ -UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD puiHandler, - DWORD dwMessageFilter, LPVOID pvContext, - PINSTALLUI_HANDLER_RECORD ppuiPrevHandler) +UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD handler, + DWORD filter, LPVOID context, + PINSTALLUI_HANDLER_RECORD prev ) { - FIXME("%p %08x %p %p\n", puiHandler, dwMessageFilter ,pvContext, - ppuiPrevHandler); - return ERROR_CALL_NOT_IMPLEMENTED; + TRACE("%p %08x %p %p\n", handler, filter, context, prev); + + if (prev) + *prev = gUIHandlerRecord; + + gUIHandlerRecord = handler; + gUIFilter = filter; + gUIContext = context; + + return ERROR_SUCCESS; } /*********************************************************************** diff --git a/reactos/dll/win32/msi/msi_main.c b/reactos/dll/win32/msi/msi_main.c index 9474b2a9597..df29184ab92 100644 --- a/reactos/dll/win32/msi/msi_main.c +++ b/reactos/dll/win32/msi/msi_main.c @@ -37,12 +37,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); static LONG dll_count; /* the UI level */ -INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC; -HWND gUIhwnd = 0; -INSTALLUI_HANDLERA gUIHandlerA = NULL; -INSTALLUI_HANDLERW gUIHandlerW = NULL; -DWORD gUIFilter = 0; -LPVOID gUIContext = NULL; +INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC; +HWND gUIhwnd = 0; +INSTALLUI_HANDLERA gUIHandlerA = NULL; +INSTALLUI_HANDLERW gUIHandlerW = NULL; +INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL; +DWORD gUIFilter = 0; +LPVOID gUIContext = NULL; WCHAR gszLogFile[MAX_PATH]; HINSTANCE msi_hInstance; diff --git a/reactos/dll/win32/msi/msipriv.h b/reactos/dll/win32/msi/msipriv.h index 9692b64e14a..5b23f55b189 100644 --- a/reactos/dll/win32/msi/msipriv.h +++ b/reactos/dll/win32/msi/msipriv.h @@ -228,11 +228,11 @@ typedef struct tagMSIVIEWOPS /* * get_column_info - returns the name and type of a specific column * - * The name is HeapAlloc'ed by this function and should be freed by - * the caller. + * The name and tablename is HeapAlloc'ed by this function and should be + * freed by the caller. * The column information can be queried at any time. */ - UINT (*get_column_info)( struct tagMSIVIEW *view, UINT n, LPWSTR *name, UINT *type, BOOL *temporary ); + UINT (*get_column_info)( struct tagMSIVIEW *view, UINT n, LPWSTR *name, UINT *type, BOOL *temporary, LPWSTR *tableName); /* * modify - not yet implemented properly @@ -737,7 +737,7 @@ extern UINT MSI_ViewFetch( MSIQUERY*, MSIRECORD ** ); extern UINT MSI_ViewClose( MSIQUERY* ); extern UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **); extern UINT MSI_ViewModify( MSIQUERY *, MSIMODIFY, MSIRECORD * ); -extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, UINT * ); +extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, LPCWSTR, UINT * ); extern UINT msi_view_get_row(MSIDATABASE *, MSIVIEW *, UINT, MSIRECORD **); /* install internals */ @@ -759,6 +759,7 @@ extern LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename ); extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR); extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR); extern UINT msi_clone_properties(MSIPACKAGE *); +extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE, LPINT); /* for deformating */ extern UINT MSI_FormatRecordW( MSIPACKAGE *, MSIRECORD *, LPWSTR, LPDWORD ); @@ -843,6 +844,7 @@ extern INSTALLUILEVEL gUILevel; extern HWND gUIhwnd; extern INSTALLUI_HANDLERA gUIHandlerA; extern INSTALLUI_HANDLERW gUIHandlerW; +extern INSTALLUI_HANDLER_RECORD gUIHandlerRecord; extern DWORD gUIFilter; extern LPVOID gUIContext; extern WCHAR gszLogFile[MAX_PATH]; diff --git a/reactos/dll/win32/msi/msiquery.c b/reactos/dll/win32/msi/msiquery.c index b9733820a69..ddbb28d6496 100644 --- a/reactos/dll/win32/msi/msiquery.c +++ b/reactos/dll/win32/msi/msiquery.c @@ -56,9 +56,10 @@ static void MSI_CloseView( MSIOBJECTHDR *arg ) } } -UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n ) +UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, LPCWSTR table_name, UINT *n ) { LPWSTR col_name; + LPWSTR haystack_table_name; UINT i, count, r; r = table->ops->get_dimensions( table, NULL, &count ); @@ -70,11 +71,15 @@ UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n ) INT x; col_name = NULL; - r = table->ops->get_column_info( table, i, &col_name, NULL, NULL ); + r = table->ops->get_column_info( table, i, &col_name, NULL, + NULL, &haystack_table_name ); if( r != ERROR_SUCCESS ) return r; x = lstrcmpW( name, col_name ); + if( table_name ) + x |= lstrcmpW( table_name, haystack_table_name ); msi_free( col_name ); + msi_free( haystack_table_name ); if( !x ) { *n = i; @@ -306,7 +311,7 @@ UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec) for (i = 1; i <= col_count; i++) { - ret = view->ops->get_column_info(view, i, NULL, &type, NULL); + ret = view->ops->get_column_info(view, i, NULL, &type, NULL, NULL); if (ret) { ERR("Error getting column type for %d\n", i); @@ -553,7 +558,8 @@ UINT MSI_ViewGetColumnInfo( MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec ) for( i=0; iops->get_column_info( view, i+1, &name, &type, &temporary ); + r = view->ops->get_column_info( view, i+1, &name, &type, &temporary, + NULL ); if( r != ERROR_SUCCESS ) continue; if (info == MSICOLINFO_NAMES) diff --git a/reactos/dll/win32/msi/msiserver.idl b/reactos/dll/win32/msi/msiserver.idl index ac442dbd076..9972a023652 100644 --- a/reactos/dll/win32/msi/msiserver.idl +++ b/reactos/dll/win32/msi/msiserver.idl @@ -72,6 +72,7 @@ interface IWineMsiRemotePackage : IUnknown HRESULT SetInstallLevel( [in] int level ); HRESULT FormatRecord( [in] MSIHANDLE record, [out] BSTR *value ); HRESULT EvaluateCondition( [in] BSTR condition ); + HRESULT GetFeatureCost( [in] BSTR feature, [in] INT cost_tree, [in] INSTALLSTATE state, [out] INT *cost); } [ diff --git a/reactos/dll/win32/msi/package.c b/reactos/dll/win32/msi/package.c index 13091d967e4..87f1092c9e9 100644 --- a/reactos/dll/win32/msi/package.c +++ b/reactos/dll/win32/msi/package.c @@ -1203,19 +1203,28 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, } } - TRACE("(%p %x %x %s)\n", gUIHandlerA, gUIFilter, log_type, - debugstr_w(message)); + TRACE("%p %p %p %x %x %s\n", gUIHandlerA, gUIHandlerW, gUIHandlerRecord, + gUIFilter, log_type, debugstr_w(message)); /* convert it to ASCII */ - len = WideCharToMultiByte( CP_ACP, 0, message, -1, - NULL, 0, NULL, NULL ); + len = WideCharToMultiByte( CP_ACP, 0, message, -1, NULL, 0, NULL, NULL ); msg = msi_alloc( len ); - WideCharToMultiByte( CP_ACP, 0, message, -1, - msg, len, NULL, NULL ); + WideCharToMultiByte( CP_ACP, 0, message, -1, msg, len, NULL, NULL ); - if (gUIHandlerA && (gUIFilter & log_type)) + if (gUIHandlerW && (gUIFilter & log_type)) { - rc = gUIHandlerA(gUIContext,eMessageType,msg); + rc = gUIHandlerW( gUIContext, eMessageType, message ); + } + else if (gUIHandlerA && (gUIFilter & log_type)) + { + rc = gUIHandlerA( gUIContext, eMessageType, msg ); + } + else if (gUIHandlerRecord && (gUIFilter & log_type)) + { + MSIHANDLE rec = MsiCreateRecord( 1 ); + MsiRecordSetStringW( rec, 0, message ); + rc = gUIHandlerRecord( gUIContext, eMessageType, rec ); + MsiCloseHandle( rec ); } if ((!rc) && (gszLogFile[0]) && !((eMessageType & 0xff000000) == @@ -1234,8 +1243,7 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, } } msi_free( msg ); - - msi_free( message); + msi_free( message ); switch (eMessageType & 0xff000000) { @@ -1890,6 +1898,14 @@ static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR return HRESULT_FROM_WIN32(r); } +static HRESULT WINAPI mrp_GetFeatureCost( IWineMsiRemotePackage *iface, BSTR feature, + INT cost_tree, INSTALLSTATE state, INT *cost ) +{ + msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface ); + UINT r = MsiGetFeatureCostW(This->package, feature, cost_tree, state, cost); + return HRESULT_FROM_WIN32(r); +} + static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl = { mrp_QueryInterface, @@ -1914,6 +1930,7 @@ static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl = mrp_SetInstallLevel, mrp_FormatRecord, mrp_EvaluateCondition, + mrp_GetFeatureCost, }; HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj ) diff --git a/reactos/dll/win32/msi/query.h b/reactos/dll/win32/msi/query.h index eb11a1c0321..a43663de697 100644 --- a/reactos/dll/win32/msi/query.h +++ b/reactos/dll/win32/msi/query.h @@ -68,6 +68,12 @@ struct complex_expr struct expr *right; }; +struct ext_column +{ + LPCWSTR column; + LPCWSTR table; +}; + struct expr { int type; @@ -77,7 +83,7 @@ struct expr INT ival; UINT uval; LPCWSTR sval; - LPCWSTR column; + struct ext_column column; UINT col_number; } u; }; diff --git a/reactos/dll/win32/msi/select.c b/reactos/dll/win32/msi/select.c index 8fd761ed0dd..c4b9e804c07 100644 --- a/reactos/dll/win32/msi/select.c +++ b/reactos/dll/win32/msi/select.c @@ -209,11 +209,12 @@ static UINT SELECT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT SELECT_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { MSISELECTVIEW *sv = (MSISELECTVIEW*)view; - TRACE("%p %d %p %p %p\n", sv, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", sv, n, name, type, temporary, table_name ); if( !sv->table ) return ERROR_FUNCTION_FAILED; @@ -224,7 +225,7 @@ static UINT SELECT_get_column_info( struct tagMSIVIEW *view, n = sv->cols[ n - 1 ]; return sv->table->ops->get_column_info( sv->table, n, name, - type, temporary ); + type, temporary, table_name ); } static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) @@ -247,7 +248,7 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row) { col = sv->cols[i]; - r = SELECT_get_column_info(view, i + 1, &name, &type, NULL); + r = SELECT_get_column_info(view, i + 1, &name, &type, NULL, NULL); msi_free(name); if (r != ERROR_SUCCESS) { @@ -388,7 +389,7 @@ static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPCWSTR name ) if( sv->num_cols >= sv->max_cols ) return ERROR_FUNCTION_FAILED; - r = VIEW_find_column( table, name, &n ); + r = VIEW_find_column( table, name, NULL, &n ); if( r != ERROR_SUCCESS ) return r; diff --git a/reactos/dll/win32/msi/sql.tab.c b/reactos/dll/win32/msi/sql.tab.c index 31eb33853b5..84597a4f6b7 100644 --- a/reactos/dll/win32/msi/sql.tab.c +++ b/reactos/dll/win32/msi/sql.tab.c @@ -2778,7 +2778,8 @@ static struct expr * EXPR_column( void *info, const column_info *column ) if( e ) { e->type = EXPR_COLUMN; - e->u.sval = column->column; + e->u.column.column = column->column; + e->u.column.table = column->table; } return e; } diff --git a/reactos/dll/win32/msi/sql.y b/reactos/dll/win32/msi/sql.y index 969c92cc817..e2484df9e98 100644 --- a/reactos/dll/win32/msi/sql.y +++ b/reactos/dll/win32/msi/sql.y @@ -856,7 +856,8 @@ static struct expr * EXPR_column( void *info, const column_info *column ) if( e ) { e->type = EXPR_COLUMN; - e->u.sval = column->column; + e->u.column.column = column->column; + e->u.column.table = column->table; } return e; } diff --git a/reactos/dll/win32/msi/storages.c b/reactos/dll/win32/msi/storages.c index 16b323c872e..005bcdb663e 100644 --- a/reactos/dll/win32/msi/storages.c +++ b/reactos/dll/win32/msi/storages.c @@ -289,14 +289,16 @@ static UINT STORAGES_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *c } static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, UINT n, - LPWSTR *name, UINT *type, BOOL *temporary) + LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { LPCWSTR name_ptr = NULL; static const WCHAR Name[] = {'N','a','m','e',0}; static const WCHAR Data[] = {'D','a','t','a',0}; - TRACE("(%p, %d, %p, %p, %p)\n", view, n, name, type, temporary); + TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary, + table_name); if (n == 0 || n > NUM_STORAGES_COLS) return ERROR_INVALID_PARAMETER; diff --git a/reactos/dll/win32/msi/streams.c b/reactos/dll/win32/msi/streams.c index 12f707e5e57..23ae971c7d8 100644 --- a/reactos/dll/win32/msi/streams.c +++ b/reactos/dll/win32/msi/streams.c @@ -255,14 +255,16 @@ static UINT STREAMS_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT STREAMS_get_column_info(struct tagMSIVIEW *view, UINT n, - LPWSTR *name, UINT *type, BOOL *temporary) + LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { LPCWSTR name_ptr = NULL; static const WCHAR Name[] = {'N','a','m','e',0}; static const WCHAR Data[] = {'D','a','t','a',0}; - TRACE("(%p, %d, %p, %p, %p)\n", view, n, name, type, temporary); + TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary, + table_name); if (n == 0 || n > NUM_STREAMS_COLS) return ERROR_INVALID_PARAMETER; diff --git a/reactos/dll/win32/msi/table.c b/reactos/dll/win32/msi/table.c index 35f797975a6..33d1fce64c6 100644 --- a/reactos/dll/win32/msi/table.c +++ b/reactos/dll/win32/msi/table.c @@ -1582,7 +1582,8 @@ static UINT TABLE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col } static UINT TABLE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name ) { MSITABLEVIEW *tv = (MSITABLEVIEW*)view; @@ -1598,6 +1599,13 @@ static UINT TABLE_get_column_info( struct tagMSIVIEW *view, return ERROR_FUNCTION_FAILED; } + if( table_name ) + { + *table_name = strdupW( tv->columns[n-1].tablename ); + if( !*table_name ) + return ERROR_FUNCTION_FAILED; + } + if( type ) *type = tv->columns[n-1].type; @@ -2118,6 +2126,7 @@ done: static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWSTR name) { UINT n, r, count; + MSITABLEVIEW *tv = (MSITABLEVIEW*)view; r = TABLE_get_dimensions(view, NULL, &count); if (r != ERROR_SUCCESS) @@ -2126,7 +2135,7 @@ static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWS if (order->num_cols >= count) return ERROR_FUNCTION_FAILED; - r = VIEW_find_column(view, name, &n); + r = VIEW_find_column(view, name, tv->name, &n); if (r != ERROR_SUCCESS) return r; diff --git a/reactos/dll/win32/msi/update.c b/reactos/dll/win32/msi/update.c index 56d2391a731..c80d5a90d6a 100644 --- a/reactos/dll/win32/msi/update.c +++ b/reactos/dll/win32/msi/update.c @@ -155,18 +155,19 @@ static UINT UPDATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co } static UINT UPDATE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR* table_name ) { MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view; MSIVIEW *wv; - TRACE("%p %d %p %p %p\n", uv, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", uv, n, name, type, temporary, table_name ); wv = uv->wv; if( !wv ) return ERROR_FUNCTION_FAILED; - return wv->ops->get_column_info( wv, n, name, type, temporary ); + return wv->ops->get_column_info( wv, n, name, type, temporary, table_name ); } static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, diff --git a/reactos/dll/win32/msi/where.c b/reactos/dll/win32/msi/where.c index fc804a4d68f..32f71b9d1e0 100644 --- a/reactos/dll/win32/msi/where.c +++ b/reactos/dll/win32/msi/where.c @@ -490,17 +490,18 @@ static UINT WHERE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col } static UINT WHERE_get_column_info( struct tagMSIVIEW *view, - UINT n, LPWSTR *name, UINT *type, BOOL *temporary ) + UINT n, LPWSTR *name, UINT *type, BOOL *temporary, + LPWSTR *table_name) { MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view; - TRACE("%p %d %p %p %p\n", wv, n, name, type, temporary ); + TRACE("%p %d %p %p %p %p\n", wv, n, name, type, temporary, table_name ); if( !wv->table ) return ERROR_FUNCTION_FAILED; return wv->table->ops->get_column_info( wv->table, n, name, - type, temporary ); + type, temporary, table_name ); } static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, @@ -597,11 +598,13 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr switch( cond->type ) { case EXPR_COLUMN: - r = VIEW_find_column( table, cond->u.column, &val ); + r = VIEW_find_column( table, cond->u.column.column, + cond->u.column.table, &val ); if( r == ERROR_SUCCESS ) { UINT type = 0; - r = table->ops->get_column_info( table, val, NULL, &type, NULL ); + r = table->ops->get_column_info( table, val, NULL, &type, + NULL, NULL ); if( r == ERROR_SUCCESS ) { if (type&MSITYPE_STRING) @@ -619,7 +622,7 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr else { *valid = 0; - WARN("Couldn't find column %s\n", debugstr_w( cond->u.column ) ); + WARN("Couldn't find column %s.%s\n", debugstr_w( cond->u.column.table ), debugstr_w( cond->u.column.column ) ); } break; case EXPR_COMPLEX: From 4df398e191ecc982cb70fda7a83c0f623770b250 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Mon, 16 Nov 2009 01:15:54 +0000 Subject: [PATCH 064/140] sync msi winetest to wine 1.1.33 svn path=/trunk/; revision=44192 --- rostests/winetests/msi/db.c | 96 +++++++++++++++++++++++++++ rostests/winetests/msi/install.c | 110 ++++++++++++++++++++++++++++++- rostests/winetests/msi/msi.c | 12 ++++ rostests/winetests/msi/source.c | 6 ++ 4 files changed, 223 insertions(+), 1 deletion(-) diff --git a/rostests/winetests/msi/db.c b/rostests/winetests/msi/db.c index bfaba172945..19cd74cd646 100644 --- a/rostests/winetests/msi/db.c +++ b/rostests/winetests/msi/db.c @@ -1566,6 +1566,101 @@ static void test_binary(void) DeleteFile( msifile ); } +static void test_where_not_in_selected(void) +{ + MSIHANDLE hdb = 0, rec, view; + LPCSTR query; + UINT r; + + hdb = create_db(); + ok( hdb, "failed to create db\n"); + + r = run_query(hdb, 0, + "CREATE TABLE `IESTable` (" + "`Action` CHAR(64), " + "`Condition` CHAR(64), " + "`Sequence` LONG PRIMARY KEY `Sequence`)"); + ok( r == S_OK, "Cannot create IESTable table: %d\n", r); + + r = run_query(hdb, 0, + "CREATE TABLE `CATable` (" + "`Action` CHAR(64), " + "`Type` LONG PRIMARY KEY `Type`)"); + ok( r == S_OK, "Cannot create CATable table: %d\n", r); + + r = run_query(hdb, 0, "INSERT INTO `IESTable` " + "( `Action`, `Condition`, `Sequence`) " + "VALUES ( 'clean', 'cond4', 4)"); + ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); + + r = run_query(hdb, 0, "INSERT INTO `IESTable` " + "( `Action`, `Condition`, `Sequence`) " + "VALUES ( 'depends', 'cond1', 1)"); + ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); + + r = run_query(hdb, 0, "INSERT INTO `IESTable` " + "( `Action`, `Condition`, `Sequence`) " + "VALUES ( 'build', 'cond2', 2)"); + ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); + + r = run_query(hdb, 0, "INSERT INTO `IESTable` " + "( `Action`, `Condition`, `Sequence`) " + "VALUES ( 'build2', 'cond6', 6)"); + ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r ); + + r = run_query(hdb, 0, "INSERT INTO `IESTable` " + "( `Action`, `Condition`, `Sequence`) " + "VALUES ( 'build', 'cond3', 3)"); + ok(r == S_OK, "cannot add entry to IESTable table:%d\n", r ); + + r = run_query(hdb, 0, "INSERT INTO `CATable` " + "( `Action`, `Type` ) " + "VALUES ( 'build', 32)"); + ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); + + r = run_query(hdb, 0, "INSERT INTO `CATable` " + "( `Action`, `Type` ) " + "VALUES ( 'depends', 64)"); + ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); + + r = run_query(hdb, 0, "INSERT INTO `CATable` " + "( `Action`, `Type` ) " + "VALUES ( 'clean', 63)"); + ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); + + r = run_query(hdb, 0, "INSERT INTO `CATable` " + "( `Action`, `Type` ) " + "VALUES ( 'build2', 34)"); + ok(r == S_OK, "cannot add entry to CATable table:%d\n", r ); + query = "Select IESTable.Condition from CATable, IESTable where " + "CATable.Action = IESTable.Action and CATable.Type = 32"; + r = MsiDatabaseOpenView(hdb, query, &view); + ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r ); + + r = MsiViewExecute(view, 0); + ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r ); + + r = MsiViewFetch(view, &rec); + ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); + + ok( check_record( rec, 1, "cond2"), "wrong condition\n"); + + MsiCloseHandle( rec ); + r = MsiViewFetch(view, &rec); + ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r ); + + ok( check_record( rec, 1, "cond3"), "wrong condition\n"); + + MsiCloseHandle( rec ); + MsiViewClose(view); + MsiCloseHandle(view); + + MsiCloseHandle( hdb ); + DeleteFile(msifile); + +} + + static void test_where(void) { MSIHANDLE hdb = 0, rec, view; @@ -8450,6 +8545,7 @@ START_TEST(db) test_longstrings(); test_streamtable(); test_binary(); + test_where_not_in_selected(); test_where(); test_msiimport(); test_binary_import(); diff --git a/rostests/winetests/msi/install.c b/rostests/winetests/msi/install.c index ed1ebc2d96f..c6fd1ca4701 100644 --- a/rostests/winetests/msi/install.c +++ b/rostests/winetests/msi/install.c @@ -35,6 +35,8 @@ static UINT (WINAPI *pMsiQueryComponentStateA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, INSTALLSTATE*); +static UINT (WINAPI *pMsiSetExternalUIRecord) + (INSTALLUI_HANDLER_RECORD, DWORD, LPVOID, PINSTALLUI_HANDLER_RECORD); static UINT (WINAPI *pMsiSourceListEnumSourcesA) (LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPSTR, LPDWORD); static UINT (WINAPI *pMsiSourceListGetInfoA) @@ -172,7 +174,13 @@ static const CHAR environment_dat[] = "Environment\tName\tValue\tComponent_\n" "Var1\t=-MSITESTVAR1\t1\tOne\n" "Var2\tMSITESTVAR2\t1\tOne\n" "Var3\t=-MSITESTVAR3\t1\tOne\n" - "Var4\tMSITESTVAR4\t1\tOne\n"; + "Var4\tMSITESTVAR4\t1\tOne\n" + "Var5\t-MSITESTVAR5\t\tOne\n" + "Var6\tMSITESTVAR6\t\tOne\n" + "Var7\t!-MSITESTVAR7\t\tOne\n" + "Var8\t!-*MSITESTVAR8\t\tOne\n" + "Var9\t=-MSITESTVAR9\t\tOne\n" + "Var10\t=MSITESTVAR10\t\tOne\n"; static const CHAR condition_dat[] = "Feature_\tLevel\tCondition\n" "s38\ti2\tS255\n" @@ -1684,6 +1692,7 @@ static void init_functionpointers(void) trace("GetProcAddress(%s) failed\n", #func); GET_PROC(hmsi, MsiQueryComponentStateA); + GET_PROC(hmsi, MsiSetExternalUIRecord); GET_PROC(hmsi, MsiSourceListEnumSourcesA); GET_PROC(hmsi, MsiSourceListGetInfoA); @@ -3944,6 +3953,7 @@ static void test_publish_registeruser(void) DeleteFile(msifile); DeleteFile("msitest\\maximus"); RemoveDirectory("msitest"); + LocalFree(usersid); } static void test_publish_processcomponents(void) @@ -4068,6 +4078,7 @@ static void test_publish_processcomponents(void) DeleteFile(msifile); DeleteFile("msitest\\maximus"); RemoveDirectory("msitest"); + LocalFree(usersid); } static void test_publish(void) @@ -6605,6 +6616,24 @@ static void test_envvar(void) res = RegDeleteValueA(env, "MSITESTVAR4"); ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res); + res = RegDeleteValueA(env, "MSITESTVAR5"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR6"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR7"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR8"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR9"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + + res = RegDeleteValueA(env, "MSITESTVAR10"); + ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res); + RegCloseKey(env); delete_pf("msitest\\cabout\\new\\five.txt", TRUE); @@ -6869,6 +6898,84 @@ static void test_file_in_use_cab(void) delete_test_files(); } +static INT CALLBACK handler_a(LPVOID context, UINT type, LPCSTR msg) +{ + return IDOK; +} + +static INT CALLBACK handler_w(LPVOID context, UINT type, LPCWSTR msg) +{ + return IDOK; +} + +static INT CALLBACK handler_record(LPVOID context, UINT type, MSIHANDLE record) +{ + return IDOK; +} + +static void test_MsiSetExternalUI(void) +{ + INSTALLUI_HANDLERA ret_a; + INSTALLUI_HANDLERW ret_w; + INSTALLUI_HANDLER_RECORD prev; + UINT error; + + ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL); + ok(ret_a == NULL, "expected NULL, got %p\n", ret_a); + + ret_a = MsiSetExternalUIA(NULL, 0, NULL); + ok(ret_a == handler_a, "expected %p, got %p\n", handler_a, ret_a); + + /* Not present before Installer 3.1 */ + if (!pMsiSetExternalUIRecord) { + win_skip("MsiSetExternalUIRecord is not available\n"); + return; + } + + error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev); + ok(!error, "MsiSetExternalUIRecord failed %u\n", error); + ok(prev == NULL, "expected NULL, got %p\n", prev); + + prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef; + error = pMsiSetExternalUIRecord(NULL, INSTALLLOGMODE_ERROR, NULL, &prev); + ok(!error, "MsiSetExternalUIRecord failed %u\n", error); + ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev); + + ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL); + ok(ret_w == NULL, "expected NULL, got %p\n", ret_w); + + ret_w = MsiSetExternalUIW(NULL, 0, NULL); + ok(ret_w == handler_w, "expected %p, got %p\n", handler_w, ret_w); + + ret_a = MsiSetExternalUIA(handler_a, INSTALLLOGMODE_ERROR, NULL); + ok(ret_a == NULL, "expected NULL, got %p\n", ret_a); + + ret_w = MsiSetExternalUIW(handler_w, INSTALLLOGMODE_ERROR, NULL); + ok(ret_w == NULL, "expected NULL, got %p\n", ret_w); + + prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef; + error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, &prev); + ok(!error, "MsiSetExternalUIRecord failed %u\n", error); + ok(prev == NULL, "expected NULL, got %p\n", prev); + + ret_a = MsiSetExternalUIA(NULL, 0, NULL); + ok(ret_a == NULL, "expected NULL, got %p\n", ret_a); + + ret_w = MsiSetExternalUIW(NULL, 0, NULL); + ok(ret_w == NULL, "expected NULL, got %p\n", ret_w); + + prev = (INSTALLUI_HANDLER_RECORD)0xdeadbeef; + error = pMsiSetExternalUIRecord(NULL, 0, NULL, &prev); + ok(!error, "MsiSetExternalUIRecord failed %u\n", error); + ok(prev == handler_record, "expected %p, got %p\n", handler_record, prev); + + error = pMsiSetExternalUIRecord(handler_record, INSTALLLOGMODE_ERROR, NULL, NULL); + ok(!error, "MsiSetExternalUIRecord failed %u\n", error); + + error = pMsiSetExternalUIRecord(NULL, 0, NULL, NULL); + ok(!error, "MsiSetExternalUIRecord failed %u\n", error); +} + START_TEST(install) { DWORD len; @@ -6957,6 +7064,7 @@ START_TEST(install) test_installed_prop(); test_file_in_use(); test_file_in_use_cab(); + test_MsiSetExternalUI(); DeleteFileA(log_file); diff --git a/rostests/winetests/msi/msi.c b/rostests/winetests/msi/msi.c index f25d5803628..8da34990006 100644 --- a/rostests/winetests/msi/msi.c +++ b/rostests/winetests/msi/msi.c @@ -1201,6 +1201,7 @@ static void test_MsiQueryFeatureState(void) RegCloseKey(compkey2); RegCloseKey(localkey); RegCloseKey(userkey); + LocalFree(usersid); } static void test_MsiQueryComponentState(void) @@ -1520,6 +1521,7 @@ static void test_MsiQueryComponentState(void) RegDeleteKeyA(compkey, ""); RegCloseKey(prodkey); RegCloseKey(compkey); + LocalFree(usersid); } static void test_MsiGetComponentPath(void) @@ -1872,6 +1874,7 @@ static void test_MsiGetComponentPath(void) RegCloseKey(prodkey); RegCloseKey(compkey); DeleteFileA("C:\\imapath"); + LocalFree(usersid); } static void test_MsiGetProductCode(void) @@ -2128,6 +2131,7 @@ static void test_MsiGetProductCode(void) RegDeleteValueA(compkey, prod2_squashed); RegDeleteKeyA(compkey, ""); RegCloseKey(compkey); + LocalFree(usersid); } static void test_MsiEnumClients(void) @@ -2314,6 +2318,7 @@ static void test_MsiEnumClients(void) RegDeleteValueA(compkey, prod2_squashed); RegDeleteKeyA(compkey, ""); RegCloseKey(compkey); + LocalFree(usersid); } static void get_version_info(LPSTR path, LPSTR *vercheck, LPDWORD verchecksz, @@ -3845,6 +3850,7 @@ static void test_MsiGetProductInfo(void) RegCloseKey(localkey); RegCloseKey(source); RegCloseKey(prodkey); + LocalFree(usersid); } static void test_MsiGetProductInfoEx(void) @@ -6582,6 +6588,7 @@ static void test_MsiGetProductInfoEx(void) RegDeleteValueA(prodkey, "HelpLink"); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); + LocalFree(usersid); } #define INIT_USERINFO() \ @@ -7161,6 +7168,7 @@ static void test_MsiGetUserInfo(void) RegCloseKey(userprod); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); + LocalFree(usersid); } static void test_MsiOpenProduct(void) @@ -7473,6 +7481,7 @@ static void test_MsiOpenProduct(void) RegCloseKey(prodkey); DeleteFileA(msifile); + LocalFree(usersid); } static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid) @@ -9201,6 +9210,7 @@ static void test_MsiEnumPatchesEx(void) test_MsiEnumPatchesEx_userunmanaged(NULL, usersid); /* FIXME: Successfully test userunmanaged with a different user */ test_MsiEnumPatchesEx_machine(); + LocalFree(usersid); } static void test_MsiEnumPatches(void) @@ -9864,6 +9874,7 @@ static void test_MsiEnumPatches(void) RegCloseKey(udprod); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); + LocalFree(usersid); } static void test_MsiGetPatchInfoEx(void) @@ -10876,6 +10887,7 @@ static void test_MsiGetPatchInfoEx(void) RegCloseKey(props); RegDeleteKeyA(udprod, ""); RegCloseKey(udprod); + LocalFree(usersid); } static void test_MsiEnumProducts(void) diff --git a/rostests/winetests/msi/source.c b/rostests/winetests/msi/source.c index 5a51c66c3f8..fd983ae50f0 100644 --- a/rostests/winetests/msi/source.c +++ b/rostests/winetests/msi/source.c @@ -628,6 +628,7 @@ static void test_MsiSourceListGetInfo(void) RegDeleteKeyA(userkey, ""); RegCloseKey(hkey); RegCloseKey(userkey); + LocalFree(usersid); } static void test_MsiSourceListAddSourceEx(void) @@ -1605,6 +1606,7 @@ static void test_MsiSourceListEnumSources(void) RegCloseKey(source); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); + LocalFree(usersid); } static void test_MsiSourceListSetInfo(void) @@ -2015,6 +2017,7 @@ static void test_MsiSourceListSetInfo(void) RegCloseKey(source); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); + LocalFree(usersid); } static void test_MsiSourceListAddMediaDisk(void) @@ -2312,6 +2315,7 @@ static void test_MsiSourceListAddMediaDisk(void) RegCloseKey(source); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); + LocalFree(usersid); } static void test_MsiSourceListEnumMediaDisks(void) @@ -3114,6 +3118,7 @@ static void test_MsiSourceListEnumMediaDisks(void) RegCloseKey(source); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); + LocalFree(usersid); } static void test_MsiSourceListAddSource(void) @@ -3369,6 +3374,7 @@ static void test_MsiSourceListAddSource(void) RegCloseKey(source); RegDeleteKeyA(prodkey, ""); RegCloseKey(prodkey); + LocalFree(usersid); } START_TEST(source) From 0b4a63a920703fe0b200b0cb9a75011a1d4a11f2 Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Mon, 16 Nov 2009 01:23:20 +0000 Subject: [PATCH 065/140] add MUI error codes from wine svn path=/trunk/; revision=44193 --- reactos/include/psdk/winerror.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/reactos/include/psdk/winerror.h b/reactos/include/psdk/winerror.h index 485bdc9a700..5fde25b0728 100644 --- a/reactos/include/psdk/winerror.h +++ b/reactos/include/psdk/winerror.h @@ -1924,6 +1924,16 @@ #define ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE 14079L #define ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME 14080 +#define ERROR_MUI_FILE_NOT_FOUND 15100 +#define ERROR_MUI_INVALID_FILE 15101 +#define ERROR_MUI_INVALID_RC_CONFIG 15102 +#define ERROR_MUI_INVALID_LOCALE_NAME 15103 +#define ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME 15104 +#define ERROR_MUI_FILE_NOT_LOADED 15105 +#define ERROR_RESOURCE_ENUM_USER_STOP 15106 +#define ERROR_MUI_INTLSETTINGS_UILANG_NOT_INSTALLED 15107 +#define ERROR_MUI_INTLSETTINGS_INVALID_LOCALE_NAME 15108 + /* HRESULT values for OLE, SHELL and other Interface stuff */ /* the codes 4000-40ff are reserved for OLE */ From 073d07ac3622fa9d5228566fd2b0a9e640db603e Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Mon, 16 Nov 2009 01:37:12 +0000 Subject: [PATCH 066/140] partial FormatMessage wine sync svn path=/trunk/; revision=44194 --- reactos/dll/win32/kernel32/misc/errormsg.c | 73 ++++++++++++---------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/errormsg.c b/reactos/dll/win32/kernel32/misc/errormsg.c index 85cd334b0bc..96c4441668b 100644 --- a/reactos/dll/win32/kernel32/misc/errormsg.c +++ b/reactos/dll/win32/kernel32/misc/errormsg.c @@ -75,6 +75,42 @@ __inline static LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str ) * Yes, ANSI strings in win32 resources. Go figure. */ +/********************************************************************** + * load_messageW (internal) + */ +static LPWSTR load_messageW( HMODULE module, UINT id, WORD lang ) +{ + PRTL_MESSAGE_RESOURCE_ENTRY mre; + WCHAR *buffer; + NTSTATUS Status; + + TRACE("module = %p, id = %08x\n", module, id ); + + if (!module) module = GetModuleHandleW( NULL ); + Status = RtlFindMessage( module, (ULONG) RT_MESSAGETABLE, lang, id, &mre ); + if (!NT_SUCCESS(Status)) + { + SetLastError( RtlNtStatusToDosError(Status) ); + return NULL; + } + + if (mre->Flags & MESSAGE_RESOURCE_UNICODE) + { + int len = (strlenW( (const WCHAR *)mre->Text ) + 1) * sizeof(WCHAR); + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL; + memcpy( buffer, mre->Text, len ); + } + else + { + int len = MultiByteToWideChar( CP_ACP, 0, (const char *)mre->Text, -1, NULL, 0 ); + if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL; + MultiByteToWideChar( CP_ACP, 0, (const char*)mre->Text, -1, buffer, len ); + } + //TRACE("returning %s\n", wine_dbgstr_w(buffer)); + return buffer; +} + + /********************************************************************** * load_messageA (internal) */ @@ -90,7 +126,10 @@ static LPSTR load_messageA( HMODULE module, UINT id, WORD lang ) if (!module) module = GetModuleHandleW( NULL ); Status = RtlFindMessage( module, (ULONG) RT_MESSAGETABLE, lang, id, &mre ); if (!NT_SUCCESS(Status)) + { + SetLastError( RtlNtStatusToDosError(Status) ); return NULL; + } if (mre->Flags & MESSAGE_RESOURCE_UNICODE) { @@ -109,36 +148,6 @@ static LPSTR load_messageA( HMODULE module, UINT id, WORD lang ) } - -static LPWSTR load_messageW( HMODULE module, UINT id, WORD lang ) -{ - PRTL_MESSAGE_RESOURCE_ENTRY mre; - WCHAR *buffer; - NTSTATUS Status; - - TRACE("module = %p, id = %08x\n", module, id ); - - if (!module) module = GetModuleHandleW( NULL ); - Status = RtlFindMessage( module, (ULONG) RT_MESSAGETABLE, lang, id, &mre ); - if (!NT_SUCCESS(Status)) - return NULL; - - if (mre->Flags & MESSAGE_RESOURCE_UNICODE) - { - int len = (strlenW( (const WCHAR *)mre->Text ) + 1) * sizeof(WCHAR); - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL; - memcpy( buffer, mre->Text, len ); - } - else - { - int len = MultiByteToWideChar( CP_ACP, 0, (const char *)mre->Text, -1, NULL, 0 ); - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL; - MultiByteToWideChar( CP_ACP, 0, (const char*)mre->Text, -1, buffer, len ); - } - //TRACE("returning %s\n", wine_dbgstr_w(buffer)); - return buffer; -} - /*********************************************************************** * FormatMessageA (KERNEL32.@) * FIXME: missing wrap, @@ -199,7 +208,6 @@ DWORD WINAPI FormatMessageA( if (!from) { - SetLastError (ERROR_RESOURCE_LANG_NOT_FOUND); return 0; } } @@ -457,7 +465,6 @@ DWORD WINAPI FormatMessageW( if (!from) { - SetLastError (ERROR_RESOURCE_LANG_NOT_FOUND); return 0; } } @@ -641,7 +648,7 @@ DWORD WINAPI FormatMessageW( if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) { /* nSize is the MINIMUM size */ DWORD len = strlenW(target) + 1; - *((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc(LMEM_ZEROINIT,len*sizeof(WCHAR)); + *((LPVOID*)lpBuffer) = LocalAlloc(LMEM_ZEROINIT,len*sizeof(WCHAR)); strcpyW(*(LPWSTR*)lpBuffer, target); } else lstrcpynW(lpBuffer, target, nSize); From acbe9adac1daba89cdcdc040a5b5fde83a92739f Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Mon, 16 Nov 2009 01:37:38 +0000 Subject: [PATCH 067/140] sync kernel32 winetest with wine 1.1.33 svn path=/trunk/; revision=44195 --- rostests/winetests/kernel32/file.c | 76 ++++++++++ rostests/winetests/kernel32/format_msg.c | 183 +++++++++++++++++++++-- rostests/winetests/kernel32/locale.c | 24 +++ rostests/winetests/kernel32/virtual.c | 18 +++ 4 files changed, 291 insertions(+), 10 deletions(-) diff --git a/rostests/winetests/kernel32/file.c b/rostests/winetests/kernel32/file.c index d59315e44bb..ec61659ad0b 100755 --- a/rostests/winetests/kernel32/file.c +++ b/rostests/winetests/kernel32/file.c @@ -563,6 +563,7 @@ static void test_CopyFileA(void) char source[MAX_PATH], dest[MAX_PATH]; static const char prefix[] = "pfx"; HANDLE hfile; + HANDLE hmapfile; FILETIME ft1, ft2; char buf[10]; DWORD ret; @@ -628,6 +629,34 @@ static void test_CopyFileA(void) ok( retok && ret == sizeof(prefix), "ReadFile: error %d\n", GetLastError()); ok(!memcmp(prefix, buf, sizeof(prefix)), "buffer contents mismatch\n"); + + /* check error on copying over a mapped file that was opened with FILE_SHARE_READ */ + hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); + + ret = CopyFileA(source, dest, FALSE); + ok(!ret && GetLastError() == ERROR_SHARING_VIOLATION, + "CopyFileA with mapped dest file: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError()); + + CloseHandle(hmapfile); + CloseHandle(hfile); + + hfile = CreateFileA(dest, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open destination file\n"); + + /* check error on copying over a mapped file that was opened with FILE_SHARE_WRITE */ + hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); + + ret = CopyFileA(source, dest, FALSE); + todo_wine { + ok(!ret, "CopyFileA: expected failure\n"); + ok(GetLastError() == ERROR_USER_MAPPED_FILE || + broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x and WinMe */ + "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %d\n", GetLastError()); + } + + CloseHandle(hmapfile); CloseHandle(hfile); ret = DeleteFileA(source); @@ -1263,7 +1292,10 @@ static void test_MoveFileA(void) char tempdir[MAX_PATH]; char source[MAX_PATH], dest[MAX_PATH]; static const char prefix[] = "pfx"; + HANDLE hfile; + HANDLE hmapfile; DWORD ret; + BOOL retok; ret = GetTempPathA(MAX_PATH, tempdir); ok(ret != 0, "GetTempPathA error %d\n", GetLastError()); @@ -1282,6 +1314,50 @@ static void test_MoveFileA(void) ret = DeleteFileA(dest); ok(ret, "DeleteFileA: error %d\n", GetLastError()); + hfile = CreateFileA(source, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n"); + + retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL ); + ok( retok && ret == sizeof(prefix), + "WriteFile error %d\n", GetLastError()); + + hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); + + ret = MoveFileA(source, dest); + todo_wine { + ok(!ret, "MoveFileA: expected failure\n"); + ok(GetLastError() == ERROR_SHARING_VIOLATION || + broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */ + "MoveFileA: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError()); + } + + CloseHandle(hmapfile); + CloseHandle(hfile); + + /* if MoveFile succeeded, move back to dest */ + if (ret) MoveFile(dest, source); + + hfile = CreateFileA(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n"); + + hmapfile = CreateFileMapping(hfile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); + ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); + + ret = MoveFileA(source, dest); + todo_wine { + ok(!ret, "MoveFileA: expected failure\n"); + ok(GetLastError() == ERROR_SHARING_VIOLATION || + broken(GetLastError() == ERROR_ACCESS_DENIED), /* Win9x and WinMe */ + "MoveFileA: expected ERROR_SHARING_VIOLATION, got %d\n", GetLastError()); + } + + CloseHandle(hmapfile); + CloseHandle(hfile); + + /* if MoveFile succeeded, move back to dest */ + if (ret) MoveFile(dest, source); + ret = MoveFileA(source, dest); ok(ret, "MoveFileA: failed, error %d\n", GetLastError()); diff --git a/rostests/winetests/kernel32/format_msg.c b/rostests/winetests/kernel32/format_msg.c index 70193214942..822667ccd24 100755 --- a/rostests/winetests/kernel32/format_msg.c +++ b/rostests/winetests/kernel32/format_msg.c @@ -26,29 +26,29 @@ /* #define ok(cond,failstr) if(!(cond)) {printf("line %d : %s\n",__LINE__,failstr);exit(1);} */ -static DWORD doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, - LPSTR out, DWORD outsize, ... ) +static DWORD __cdecl doit(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, + LPSTR out, DWORD outsize, ... ) { - va_list list; + __ms_va_list list; DWORD r; - va_start(list, outsize); + __ms_va_start(list, outsize); r = FormatMessageA(flags, src, msg_id, lang_id, out, outsize, &list); - va_end(list); + __ms_va_end(list); return r; } -static DWORD doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, - LPWSTR out, DWORD outsize, ... ) +static DWORD __cdecl doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id, + LPWSTR out, DWORD outsize, ... ) { - va_list list; + __ms_va_list list; DWORD r; - va_start(list, outsize); + __ms_va_start(list, outsize); r = FormatMessageW(flags, src, msg_id, lang_id, out, outsize, &list); - va_end(list); + __ms_va_end(list); return r; } @@ -87,6 +87,14 @@ static void test_message_from_string_wide(void) static const WCHAR fmt_hi_crlf[] = {'h','i','\r','\n',0}; static const WCHAR fmt_cr[] = {'\r',0}; static const WCHAR fmt_crcrlf[] = {'\r','\r','\n',0}; + static const WCHAR fmt_13s[] = {'%','1','!','3','s','!',0}; + static const WCHAR fmt_1os[] = {'%','1','!','*','s','!',0}; + static const WCHAR fmt_142u[] = {'%','1','!','4','.','2','u','!',0}; + static const WCHAR fmt_1oou[] = {'%','1','!','*','.','*','u','!',0}; + static const WCHAR fmt_1oou1oou[] = {'%','1','!','*','.','*','u','!',',','%','1','!','*','.','*','u','!',0}; + static const WCHAR fmt_1oou3oou[] = {'%','1','!','*','.','*','u','!',',','%','3','!','*','.','*','u','!',0}; + static const WCHAR fmt_1oou4oou[] = {'%','1','!','*','.','*','u','!',',','%','4','!','*','.','*','u','!',0}; + static const WCHAR s_123d[] = {'1','2','3',0}; static const WCHAR s_14d[] = {' ',' ',' ','1',0}; static const WCHAR s_14x[] = {' ',' ',' ','b',0}; @@ -105,6 +113,16 @@ static void test_message_from_string_wide(void) static const WCHAR s_hi_sp[] = {'h','i',' ',0}; static const WCHAR s_sp[] = {' ',0}; static const WCHAR s_2sp[] = {' ',' ',0}; + static const WCHAR s_spt[] = {' ',' ','t',0}; + static const WCHAR s_sp3t[] = {' ',' ',' ','t',0}; + static const WCHAR s_sp03[] = {' ',' ','0','3',0}; + static const WCHAR s_sp001[] = {' ',' ','0','0','1',0}; + static const WCHAR s_sp001002[] = {' ',' ','0','0','1',',',' ','0','0','0','2',0}; + static const WCHAR s_sp001sp002[] = {' ',' ','0','0','1',',',' ',' ','0','0','0','2',0}; + static const WCHAR s_sp002sp001[] = {' ',' ','0','0','0','2',',',' ',' ','0','0','1',0}; + static const WCHAR s_sp002sp003[] = {' ',' ','0','0','0','2',',',' ','0','0','0','0','3',0}; + static const WCHAR s_sp001004[] = {' ',' ','0','0','1',',','0','0','0','0','0','4',0}; + WCHAR out[0x100] = {0}; DWORD r, error; @@ -296,6 +314,46 @@ static void test_message_from_string_wide(void) ok(!lstrcmpW(s_crlfcrlf, out), "failed out=%s\n", wine_dbgstr_w(out)); ok(r==4,"failed: r=%d\n", r); + /* precision and width */ + + r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_13s, + 0, 0, out, sizeof(out)/sizeof(WCHAR), t ); + ok(!lstrcmpW(s_spt, out),"failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==3, "failed: r=%d\n",r); + r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1os, + 0, 0, out, sizeof(out)/sizeof(WCHAR), 4, t ); + ok(!lstrcmpW( s_sp3t, out),"failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==4,"failed: r=%d\n",r); + r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_142u, + 0, 0, out, sizeof(out)/sizeof(WCHAR), 3 ); + ok(!lstrcmpW( s_sp03, out),"failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==4,"failed: r=%d\n",r); + r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou, + 0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1 ); + ok(!lstrcmpW( s_sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==5,"failed: r=%d\n",r); + r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou1oou, + 0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1, 4, 2 ); + ok(!lstrcmpW( s_sp001002, out),"failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==11,"failed: r=%d\n",r); + r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1oou3oou, + 0, 0, out, sizeof(out)/sizeof(WCHAR), 5, 3, 1, 6, 4, 2 ); + ok(!lstrcmpW( s_sp001sp002, out) || broken(!lstrcmpW(s_sp001004, out)), + "failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==12,"failed: r=%d\n",r); + /* args are not counted the same way with an argument array */ + { + ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 }; + r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou1oou, + 0, 0, out, sizeof(out)/sizeof(WCHAR), (__ms_va_list *)args ); + ok(!lstrcmpW(s_sp002sp003, out),"failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==13,"failed: r=%d\n",r); + r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1oou4oou, + 0, 0, out, sizeof(out)/sizeof(WCHAR), (__ms_va_list *)args ); + ok(!lstrcmpW(s_sp002sp001, out),"failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==12,"failed: r=%d\n",r); + } + /* change of pace... test the low byte of dwflags */ /* line feed */ @@ -509,6 +567,52 @@ static void test_message_from_string(void) ok(!strcmp("\r\n\r\n", out),"failed out=[%s]\n",out); ok(r==4,"failed: r=%d\n",r); + /* precision and width */ + + r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!", + 0, 0, out, sizeof(out), "t" ); + ok(!strcmp(" t", out),"failed out=[%s]\n",out); + ok(r==3, "failed: r=%d\n",r); + r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*s!", + 0, 0, out, sizeof(out), 4, "t"); + if (!strcmp("*s",out)) win_skip( "width/precision not supported\n" ); + else + { + ok(!strcmp( " t", out),"failed out=[%s]\n",out); + ok(r==4,"failed: r=%d\n",r); + r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!4.2u!", + 0, 0, out, sizeof(out), 3 ); + ok(!strcmp( " 03", out),"failed out=[%s]\n",out); + ok(r==4,"failed: r=%d\n",r); + r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!", + 0, 0, out, sizeof(out), 5, 3, 1 ); + ok(!strcmp( " 001", out),"failed out=[%s]\n",out); + ok(r==5,"failed: r=%d\n",r); + r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%1!*.*u!", + 0, 0, out, sizeof(out), 5, 3, 1, 4, 2 ); + ok(!strcmp( " 001, 0002", out),"failed out=[%s]\n",out); + ok(r==11,"failed: r=%d\n",r); + r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!*.*u!,%3!*.*u!", + 0, 0, out, sizeof(out), 5, 3, 1, 6, 4, 2 ); + /* older Win versions marked as broken even though this is arguably the correct behavior */ + /* but the new (brain-damaged) behavior is specified on MSDN */ + ok(!strcmp( " 001, 0002", out) || broken(!strcmp(" 001,000004", out)), + "failed out=[%s]\n",out); + ok(r==12,"failed: r=%d\n",r); + /* args are not counted the same way with an argument array */ + { + ULONG_PTR args[] = { 6, 4, 2, 5, 3, 1 }; + r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, + "%1!*.*u!,%1!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args ); + ok(!strcmp(" 0002, 00003", out),"failed out=[%s]\n",out); + ok(r==13,"failed: r=%d\n",r); + r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, + "%1!*.*u!,%4!*.*u!", 0, 0, out, sizeof(out), (__ms_va_list *)args ); + ok(!strcmp(" 0002, 001", out),"failed out=[%s]\n",out); + ok(r==12,"failed: r=%d\n",r); + } + } + /* change of pace... test the low byte of dwflags */ /* line feed */ @@ -561,9 +665,68 @@ static void test_message_null_buffer(void) ok(error == ERROR_INVALID_PARAMETER, "last error %u\n", error); } +static void test_message_from_hmodule(void) +{ + DWORD ret, error; + HMODULE h; + CHAR out[0x100] = {0}; + + h = GetModuleHandle("kernel32.dll"); + ok(h != 0, "GetModuleHandle failed\n"); + + /*Test existing messageID; as the message strings from wine's kernel32 differ from windows' kernel32 we don't compare + the strings but only test that FormatMessage doesn't return 0*/ + ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 7/*=ERROR_ARENA_TRASHED*/, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); + ok(ret != 0, "FormatMessageA returned 0\n"); + + /*Test nonexistent messageID with varying language ID's Note: FormatMessageW behaves the same*/ + SetLastError(0xdeadbeef); + ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); + error = GetLastError(); + ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); + ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_FOUND, "last error %u\n", error); + + SetLastError(0xdeadbeef); + ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL); + error = GetLastError(); + ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); + ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error); + + SetLastError(0xdeadbeef); + ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, + MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), out, sizeof(out)/sizeof(CHAR), NULL); + error = GetLastError(); + ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); + ok(error == ERROR_MR_MID_NOT_FOUND || error == ERROR_MUI_FILE_NOT_LOADED, "last error %u\n", error); + + SetLastError(0xdeadbeef); + ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), out, sizeof(out)/sizeof(CHAR), NULL); + error = GetLastError(); + ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); + ok(error == ERROR_RESOURCE_LANG_NOT_FOUND || + error == ERROR_MR_MID_NOT_FOUND || + error == ERROR_MUI_FILE_NOT_LOADED, + "last error %u\n", error); + + SetLastError(0xdeadbeef); + ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), out, sizeof(out)/sizeof(CHAR), NULL); + error = GetLastError(); + ok(ret == 0, "FormatMessageA returned %u instead of 0\n", ret); + ok(error == ERROR_RESOURCE_LANG_NOT_FOUND || + error == ERROR_MR_MID_NOT_FOUND || + error == ERROR_MUI_FILE_NOT_FOUND, + "last error %u\n", error); +} + START_TEST(format_msg) { test_message_from_string(); test_message_from_string_wide(); test_message_null_buffer(); + test_message_from_hmodule(); } diff --git a/rostests/winetests/kernel32/locale.c b/rostests/winetests/kernel32/locale.c index 77fae8b8b05..37dc0aada7e 100755 --- a/rostests/winetests/kernel32/locale.c +++ b/rostests/winetests/kernel32/locale.c @@ -743,6 +743,18 @@ static void test_GetCurrencyFormatA(void) ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); EXPECT_LENA; EXPECT_EQA; + STRINGSA("235","$235.0"); /* Grouping of a positive number */ + format.Grouping = 3; + ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_LENA; EXPECT_EQA; + + STRINGSA("-235","$-235.0"); /* Grouping of a negative number */ + format.NegativeOrder = 2; + ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_LENA; EXPECT_EQA; + format.LeadingZero = 1; /* Always provide leading zero */ STRINGSA(".5","$0.5"); ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer)); @@ -990,6 +1002,18 @@ static void test_GetNumberFormatA(void) ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); EXPECT_LENA; EXPECT_EQA; + STRINGSA("235","235.0"); /* Grouping of a positive number */ + format.Grouping = 3; + ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_LENA; EXPECT_EQA; + + STRINGSA("-235","-235.0"); /* Grouping of a negative number */ + format.NegativeOrder = NEG_LEFT; + ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_LENA; EXPECT_EQA; + format.LeadingZero = 1; /* Always provide leading zero */ STRINGSA(".5","0.5"); ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer)); diff --git a/rostests/winetests/kernel32/virtual.c b/rostests/winetests/kernel32/virtual.c index b7e97db667c..5187a97627a 100755 --- a/rostests/winetests/kernel32/virtual.c +++ b/rostests/winetests/kernel32/virtual.c @@ -748,6 +748,24 @@ static void test_MapViewOfFile(void) ret = UnmapViewOfFile(ptr); ok(ret, "UnmapViewOfFile failed with error %d\n", GetLastError()); CloseHandle(mapping); + + addr = VirtualAlloc(NULL, 0x10000, MEM_COMMIT, PAGE_READONLY ); + ok( addr != NULL, "VirtualAlloc failed with error %u\n", GetLastError() ); + + SetLastError(0xdeadbeef); + ok( !UnmapViewOfFile(addr), "UnmapViewOfFile should fail on VirtualAlloc mem\n" ); + ok( GetLastError() == ERROR_INVALID_ADDRESS, + "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError()); + SetLastError(0xdeadbeef); + ok( !UnmapViewOfFile((char *)addr + 0x3000), "UnmapViewOfFile should fail on VirtualAlloc mem\n" ); + ok( GetLastError() == ERROR_INVALID_ADDRESS, + "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError()); + SetLastError(0xdeadbeef); + ok( !UnmapViewOfFile((void *)0xdeadbeef), "UnmapViewOfFile should fail on VirtualAlloc mem\n" ); + ok( GetLastError() == ERROR_INVALID_ADDRESS, + "got %u, expected ERROR_INVALID_ADDRESS\n", GetLastError()); + + ok( VirtualFree(addr, 0, MEM_RELEASE), "VirtualFree failed\n" ); } static DWORD (WINAPI *pNtMapViewOfSection)( HANDLE handle, HANDLE process, PVOID *addr_ptr, From aa317c6f632b28d9f5e7ef43e9f6dcf6e89513a7 Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Mon, 16 Nov 2009 01:56:48 +0000 Subject: [PATCH 068/140] Break long expressions, fix formatting. svn path=/trunk/; revision=44196 --- reactos/ntoskrnl/fsrtl/fastio.c | 1353 +++++++++++++++++-------------- 1 file changed, 762 insertions(+), 591 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/fastio.c b/reactos/ntoskrnl/fsrtl/fastio.c index bd20e5a53ee..068c45ea546 100644 --- a/reactos/ntoskrnl/fsrtl/fastio.c +++ b/reactos/ntoskrnl/fsrtl/fastio.c @@ -74,9 +74,9 @@ FsRtlCopyRead(IN PFILE_OBJECT FileObject, PFAST_IO_DISPATCH FastIoDispatch; PDEVICE_OBJECT Device; BOOLEAN Result = TRUE; - ULONG PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(FileOffset,Length); + ULONG PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(FileOffset, Length); - PAGED_CODE(); + PAGED_CODE(); ASSERT(FileObject); ASSERT(FileObject->FsContext); @@ -89,41 +89,45 @@ FsRtlCopyRead(IN PFILE_OBJECT FileObject, return TRUE; } - if (MAXLONGLONG < (LONGLONG) FileOffset->QuadPart + Length) { - IoStatus->Status = STATUS_INVALID_PARAMETER; - IoStatus->Information = 0; - return FALSE; + if (MAXLONGLONG < (LONGLONG) FileOffset->QuadPart + Length) + { + IoStatus->Status = STATUS_INVALID_PARAMETER; + IoStatus->Information = 0; + return FALSE; } /* Get the offset and FCB header */ Offset.QuadPart = FileOffset->QuadPart + Length; FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; - - if (Wait) { + if (Wait) + { /* Use a Resource Acquire */ FsRtlEnterFileSystem(); - CcFastReadWait++; + CcFastReadWait++; ExAcquireResourceSharedLite(FcbHeader->Resource, TRUE); - } else { - /* Acquire the resource without blocking */ - /* Return false and the I/O manager will retry using the standard IRP method. */ - /* Use a Resource Acquire */ + } + else + { + /* Acquire the resource without blocking. Return false and the I/O manager + * will retry using the standard IRP method. Use a Resource Acquire. + */ FsRtlEnterFileSystem(); - if (!ExAcquireResourceSharedLite(FcbHeader->Resource, FALSE)) { - FsRtlExitFileSystem(); - FsRtlIncrementCcFastReadResourceMiss(); - return FALSE; + if (!ExAcquireResourceSharedLite(FcbHeader->Resource, FALSE)) + { + FsRtlExitFileSystem(); + FsRtlIncrementCcFastReadResourceMiss(); + return FALSE; } } - /* Check if this is a fast I/O cached file */ if (!(FileObject->PrivateCacheMap) || - (FcbHeader->IsFastIoPossible == FastIoIsNotPossible)) { + (FcbHeader->IsFastIoPossible == FastIoIsNotPossible)) + { /* It's not, so fail */ - Result = FALSE; - goto Cleanup; + Result = FALSE; + goto Cleanup; } /* Check if we need to find out if fast I/O is available */ @@ -134,7 +138,7 @@ FsRtlCopyRead(IN PFILE_OBJECT FileObject, /* Get the Fast I/O table */ Device = IoGetRelatedDeviceObject(FileObject); - FastIoDispatch = Device->DriverObject->FastIoDispatch; + FastIoDispatch = Device->DriverObject->FastIoDispatch; /* Sanity check */ ASSERT(FastIoDispatch != NULL); @@ -154,12 +158,14 @@ FsRtlCopyRead(IN PFILE_OBJECT FileObject, Result = FALSE; goto Cleanup; } - } + } /* Check if we read too much */ - if (Offset.QuadPart > FcbHeader->FileSize.QuadPart){ + if (Offset.QuadPart > FcbHeader->FileSize.QuadPart) + { /* We did, check if the file offset is past the end */ - if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart){ + if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart) + { /* Set end of file */ IoStatus->Status = STATUS_END_OF_FILE; IoStatus->Information = 0; @@ -171,45 +177,67 @@ FsRtlCopyRead(IN PFILE_OBJECT FileObject, } /* Set this as top-level IRP */ - PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; - _SEH2_TRY - { - /* Make sure the IO and file size is below 4GB */ - if (Wait && !(Offset.HighPart | FcbHeader->FileSize.HighPart )) { - - /* Call the cache controller */ - CcFastCopyRead (FileObject,FileOffset->LowPart,Length,PageCount,Buffer,IoStatus); - /* File was accessed */ - FileObject->Flags |= FO_FILE_FAST_IO_READ; - if (IoStatus->Status != STATUS_END_OF_FILE) { - ASSERT(( FcbHeader->FileSize.QuadPart) >= (FileOffset->QuadPart + IoStatus->Information)); - } - - } else { + _SEH2_TRY + { + /* Make sure the IO and file size is below 4GB */ + if (Wait && !(Offset.HighPart | FcbHeader->FileSize.HighPart)) + { /* Call the cache controller */ - Result = CcCopyRead(FileObject, FileOffset, Length, Wait,Buffer, IoStatus); + CcFastCopyRead(FileObject, + FileOffset->LowPart, + Length, + PageCount, + Buffer, + IoStatus); + /* File was accessed */ - FileObject->Flags |= FO_FILE_FAST_IO_READ; - if (Result == TRUE) { - ASSERT( (IoStatus->Status == STATUS_END_OF_FILE) || - ((LONGLONG)(FileOffset->QuadPart + IoStatus->Information) <= FcbHeader->FileSize.QuadPart) - ); - } - } + FileObject->Flags |= FO_FILE_FAST_IO_READ; + + if (IoStatus->Status != STATUS_END_OF_FILE) + { + ASSERT(FcbHeader->FileSize.QuadPart >= + FileOffset->QuadPart + IoStatus->Information); + } + } + else + { + + /* Call the cache controller */ + Result = CcCopyRead(FileObject, + FileOffset, + Length, + Wait, + Buffer, + IoStatus); + + /* File was accessed */ + FileObject->Flags |= FO_FILE_FAST_IO_READ; + + if (Result == TRUE) + { + ASSERT((IoStatus->Status == STATUS_END_OF_FILE) || + ((LONGLONG)(FileOffset->QuadPart + IoStatus->Information) <= + FcbHeader->FileSize.QuadPart)); + } + } /* Update the current file offset */ - if (Result == TRUE) { - FileObject->CurrentByteOffset.QuadPart += IoStatus->Information; - } - } - _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + if (Result == TRUE) + { + FileObject->CurrentByteOffset.QuadPart += IoStatus->Information; + } + } + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END; - PsGetCurrentThread()->TopLevelIrp = 0; + PsGetCurrentThread()->TopLevelIrp = 0; /* Return to caller */ Cleanup: @@ -217,12 +245,12 @@ Cleanup: ExReleaseResourceLite(FcbHeader->Resource); FsRtlExitFileSystem(); - if (Result == FALSE) { + if (Result == FALSE) + { CcFastReadNotPossible += 1; - } + } return Result; - } @@ -240,22 +268,23 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) { - BOOLEAN Result = TRUE; PFAST_IO_DISPATCH FastIoDispatch; PDEVICE_OBJECT Device; PFSRTL_COMMON_FCB_HEADER FcbHeader; + PSHARED_CACHE_MAP SharedCacheMap; + + /* WDK doc. + * Offset == 0xffffffffffffffff indicates append to the end of file. + */ + BOOLEAN FileOffsetAppend = (FileOffset->HighPart == (LONG)0xffffffff) && + (FileOffset->LowPart == 0xffffffff); - /* WDK doc. Offset=0xffffffffffffffff indicates append to the end of file */ - BOOLEAN FileOffsetAppend = ((FileOffset->HighPart == (LONG)0xffffffff) && (FileOffset->LowPart == 0xffffffff)); BOOLEAN ResourceAquiredShared = FALSE; - BOOLEAN b_4GB = FALSE; - BOOLEAN FileSizeModified = FALSE; LARGE_INTEGER OldFileSize; LARGE_INTEGER OldValidDataLength; - LARGE_INTEGER NewSize; LARGE_INTEGER Offset; @@ -269,13 +298,14 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject, Offset.QuadPart = FileOffset->QuadPart + Length; FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; - /* Nagar p.544 -- Check with Cc if we can write and check if the IO > 64kB (WDK macro) */ - if ( (CcCanIWrite(FileObject, Length,Wait, FALSE) == FALSE) || - (CcCopyWriteWontFlush(FileObject,FileOffset,Length) == FALSE) || - ((FileObject->Flags & FO_WRITE_THROUGH )== TRUE) - ) + /* Nagar p.544. + * Check with Cc if we can write and check if the IO > 64kB (WDK macro). + */ + if ((CcCanIWrite(FileObject, Length, Wait, FALSE) == FALSE) || + (CcCopyWriteWontFlush(FileObject, FileOffset, Length) == FALSE) || + ((FileObject->Flags & FO_WRITE_THROUGH) == TRUE)) { - return FALSE; + return FALSE; } /* No actual read */ @@ -288,386 +318,478 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject, FsRtlEnterFileSystem(); - /* Nagar p.544/545 -- The CcFastCopyWrite doesn't deal with filesize beyond 4GB*/ + /* Nagar p.544/545. + * The CcFastCopyWrite doesn't deal with filesize beyond 4GB. + */ if (Wait && (FcbHeader->AllocationSize.HighPart == 0)) { - /* If the file offset is not past the file size, then we can acquire the lock shared */ - if ((FileOffsetAppend == FALSE) && (Offset.LowPart <= FcbHeader->ValidDataLength.LowPart)){ - ExAcquireResourceSharedLite(FcbHeader->Resource,TRUE); - ResourceAquiredShared = TRUE; - } else { - ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE); - } - - /* Nagar p.544/545 -- If we append, use the file size as offset. Also, check that we aren't crossing the 4GB boundary */ - if ((FileOffsetAppend == TRUE)) { - Offset.LowPart = FcbHeader->FileSize.LowPart; - NewSize.LowPart = FcbHeader->FileSize.LowPart + Length; - b_4GB = (NewSize.LowPart < FcbHeader->FileSize.LowPart); - - } else { - Offset.LowPart = FileOffset->LowPart; - NewSize.LowPart = FileOffset->LowPart + Length; - b_4GB = ((NewSize.LowPart < FileOffset->LowPart) || (FileOffset->HighPart != 0)); - } - - /* Nagar p.544/545 - Make sure that caching is initated. - That fast are allowed for this file stream. - That we are not extending past the allocated size - That we are not creating a hole bigger than 8k - That we are not crossing the 4GB boundary - */ - if ( (FileObject->PrivateCacheMap != NULL) && - (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && - (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) && - (Offset.LowPart < (FcbHeader->ValidDataLength.LowPart + 0x2000) ) && - !b_4GB - ) + /* If the file offset is not past the file size, + * then we can acquire the lock shared. + */ + if ((FileOffsetAppend == FALSE) && + (Offset.LowPart <= FcbHeader->ValidDataLength.LowPart)) { - /* If we are extending past the file size, we need to release the lock and acquire it - exclusively, because we are going to need to update the FcbHeader */ - if (ResourceAquiredShared && (NewSize.LowPart > (FcbHeader->ValidDataLength.LowPart + 0x2000))) { - /* Then we need to acquire the resource exclusive */ - ExReleaseResourceLite(FcbHeader->Resource); - ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE); - if (FileOffsetAppend == TRUE) { - Offset.LowPart = FcbHeader->FileSize.LowPart; // ?? - NewSize.LowPart = FcbHeader->FileSize.LowPart + Length; - /* Make sure we don't cross the 4GB boundary */ - b_4GB = (NewSize.LowPart < Offset.LowPart); - } + ExAcquireResourceSharedLite(FcbHeader->Resource, TRUE); + ResourceAquiredShared = TRUE; + } + else + { + ExAcquireResourceExclusiveLite(FcbHeader->Resource, TRUE); + } + + /* Nagar p.544/545. + * If we append, use the file size as offset. + * Also, check that we aren't crossing the 4GB boundary. + */ + if (FileOffsetAppend == TRUE) + { + Offset.LowPart = FcbHeader->FileSize.LowPart; + NewSize.LowPart = FcbHeader->FileSize.LowPart + Length; + b_4GB = (NewSize.LowPart < FcbHeader->FileSize.LowPart); + + } + else + { + Offset.LowPart = FileOffset->LowPart; + NewSize.LowPart = FileOffset->LowPart + Length; + b_4GB = (NewSize.LowPart < FileOffset->LowPart) || + (FileOffset->HighPart != 0); + } + + /* Nagar p.544/545. + * Make sure that caching is initated. + * That fast are allowed for this file stream. + * That we are not extending past the allocated size. + * That we are not creating a hole bigger than 8k. + * That we are not crossing the 4GB boundary. + */ + if ((FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) && + (Offset.LowPart < FcbHeader->ValidDataLength.LowPart + 0x2000) && + !b_4GB) + { + /* If we are extending past the file size, we need to + * release the lock and acquire it exclusively, because + * we are going to need to update the FcbHeader. + */ + if (ResourceAquiredShared && + (NewSize.LowPart > FcbHeader->ValidDataLength.LowPart + 0x2000)) + { + /* Then we need to acquire the resource exclusive */ + ExReleaseResourceLite(FcbHeader->Resource); + ExAcquireResourceExclusiveLite(FcbHeader->Resource, TRUE); + if (FileOffsetAppend == TRUE) + { + Offset.LowPart = FcbHeader->FileSize.LowPart; // ?? + NewSize.LowPart = FcbHeader->FileSize.LowPart + Length; + + /* Make sure we don't cross the 4GB boundary */ + b_4GB = (NewSize.LowPart < Offset.LowPart); + } /* Recheck some of the conditions since we let the lock go */ - if ( (FileObject->PrivateCacheMap != NULL) && - (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && - (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) && - (FcbHeader->AllocationSize.HighPart == 0) && - !b_4GB - ) - { - } else - { - goto FailAndCleanup; - } - } + if ((FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) && + (FcbHeader->AllocationSize.HighPart == 0) && + !b_4GB) + { + /* Do nothing? */ + } + else + { + goto FailAndCleanup; + } + } - }else + } + else { - goto FailAndCleanup; + goto FailAndCleanup; } - /* Check if we need to find out if fast I/O is available */ - if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) - { - IO_STATUS_BLOCK FastIoCheckIfPossibleStatus; + /* Check if we need to find out if fast I/O is available */ + if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) + { + IO_STATUS_BLOCK FastIoCheckIfPossibleStatus; - /* Sanity check */ - ASSERT(!KeIsExecutingDpc()); + /* Sanity check */ + ASSERT(!KeIsExecutingDpc()); - /* Get the Fast I/O table */ - Device = IoGetRelatedDeviceObject(FileObject); - FastIoDispatch = Device->DriverObject->FastIoDispatch; + /* Get the Fast I/O table */ + Device = IoGetRelatedDeviceObject(FileObject); + FastIoDispatch = Device->DriverObject->FastIoDispatch; - /* Sanity check */ - ASSERT(FastIoDispatch != NULL); - ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); + /* Sanity check */ + ASSERT(FastIoDispatch != NULL); + ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); - /* Ask the driver if we can do it */ - if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, - FileOffsetAppend? &FcbHeader->FileSize:FileOffset, - Length, - TRUE, - LockKey, - FALSE, - &FastIoCheckIfPossibleStatus, - Device)) - { - /* It's not, fail */ - goto FailAndCleanup; - } - } + /* Ask the driver if we can do it */ + if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, + FileOffsetAppend ? + &FcbHeader->FileSize : + FileOffset, + Length, + TRUE, + LockKey, + FALSE, + &FastIoCheckIfPossibleStatus, + Device)) + { + /* It's not, fail */ + goto FailAndCleanup; + } + } - /* If we are going to extend the file then save the old file size - in case the operation fails - */ - if (NewSize.LowPart > FcbHeader->FileSize.LowPart) { - FileSizeModified = TRUE; - OldFileSize.LowPart = FcbHeader->FileSize.LowPart; - OldValidDataLength.LowPart = FcbHeader->ValidDataLength.LowPart; - FcbHeader->FileSize.LowPart = NewSize.LowPart; - } + /* If we are going to extend the file then save + * the old file size in case the operation fails. + */ + if (NewSize.LowPart > FcbHeader->FileSize.LowPart) + { + FileSizeModified = TRUE; + OldFileSize.LowPart = FcbHeader->FileSize.LowPart; + OldValidDataLength.LowPart = FcbHeader->ValidDataLength.LowPart; + FcbHeader->FileSize.LowPart = NewSize.LowPart; + } - /* Set this as top-level IRP */ - PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + /* Set this as top-level IRP */ + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; - _SEH2_TRY - { - if (Offset.LowPart > FcbHeader->ValidDataLength.LowPart) { - LARGE_INTEGER OffsetVar; - OffsetVar.LowPart = Offset.LowPart; - OffsetVar.HighPart = 0; - CcZeroData(FileObject,&FcbHeader->ValidDataLength,&OffsetVar,TRUE); - } + _SEH2_TRY + { + if (Offset.LowPart > FcbHeader->ValidDataLength.LowPart) + { + LARGE_INTEGER OffsetVar; + OffsetVar.LowPart = Offset.LowPart; + OffsetVar.HighPart = 0; + CcZeroData(FileObject, &FcbHeader->ValidDataLength, &OffsetVar, TRUE); + } - /* Call the cache manager */ - CcFastCopyWrite(FileObject,Offset.LowPart,Length,Buffer); - } - _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + /* Call the cache manager */ + CcFastCopyWrite(FileObject, Offset.LowPart, Length, Buffer); + } + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END; /* Remove ourselves at the top level component after the IO is done */ - PsGetCurrentThread()->TopLevelIrp = 0; + PsGetCurrentThread()->TopLevelIrp = 0; - /* Did the operation succeed ? */ - if (Result == TRUE) { - /* Update the valid file size if necessary */ - if (NewSize.LowPart > FcbHeader->ValidDataLength.LowPart){ - FcbHeader->ValidDataLength.LowPart = NewSize.LowPart ; - } + /* Did the operation succeed? */ + if (Result == TRUE) + { + /* Update the valid file size if necessary */ + if (NewSize.LowPart > FcbHeader->ValidDataLength.LowPart) + { + FcbHeader->ValidDataLength.LowPart = NewSize.LowPart; + } /* Flag the file as modified */ - FileObject->Flags |= FO_FILE_MODIFIED; + FileObject->Flags |= FO_FILE_MODIFIED; - /* Update the strucutres if the file size changed */ - if (FileSizeModified) { - ((SHARED_CACHE_MAP*) FileObject->SectionObjectPointer->SharedCacheMap)->FileSize.LowPart = NewSize.LowPart; - FileObject->Flags |= FO_FILE_SIZE_CHANGED; - } + /* Update the strucutres if the file size changed */ + if (FileSizeModified) + { + SharedCacheMap = + (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; + SharedCacheMap->FileSize.LowPart = NewSize.LowPart; + FileObject->Flags |= FO_FILE_SIZE_CHANGED; + } /* Update the file object current file offset */ - FileObject->CurrentByteOffset.QuadPart = NewSize.LowPart; + FileObject->CurrentByteOffset.QuadPart = NewSize.LowPart; - } else { + } + else + { + /* Result == FALSE if we get here */ + if (FileSizeModified) + { + /* If the file size was modified then restore the old file size */ + if (FcbHeader->PagingIoResource != NULL) + { + /* Nagar P.544. + * Restore the old file size if operation didn't succeed. + */ + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->FileSize.LowPart = OldFileSize.LowPart; + FcbHeader->ValidDataLength.LowPart = OldValidDataLength.LowPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } + else + { + /* If there is no lock and do it without */ + FcbHeader->FileSize.LowPart = OldFileSize.LowPart; + FcbHeader->ValidDataLength.LowPart = OldValidDataLength.LowPart; + } + } + else + { + /* Do nothing? */ + } + } - /* Result == FALSE if we get here. */ - if (FileSizeModified) { - /* If the file size was modified then restore the old file size */ - if(FcbHeader->PagingIoResource != NULL) { - // Nagar P.544 Restore the old file size if operation didn't succeed. - ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource,TRUE); - FcbHeader->FileSize.LowPart = OldFileSize.LowPart; - FcbHeader->ValidDataLength.LowPart = OldValidDataLength.LowPart; - ExReleaseResourceLite(FcbHeader->PagingIoResource); - } else { - /* If there is no lock and do it without */ - FcbHeader->FileSize.LowPart = OldFileSize.LowPart; - FcbHeader->ValidDataLength.LowPart = OldValidDataLength.LowPart; - } - } else { - } - } + goto Cleanup; + } + else + { + LARGE_INTEGER OldFileSize; - goto Cleanup; + /* Sanity check */ + ASSERT(!KeIsExecutingDpc()); - } else { + /* Nagar P.544. + * Check if we need to acquire the resource exclusive. + */ + if ((FileOffsetAppend == FALSE) && + (FileOffset->QuadPart + Length <= FcbHeader->ValidDataLength.QuadPart)) + { + /* Acquire the resource shared */ + if (!ExAcquireResourceSharedLite(FcbHeader->Resource, Wait)) + { + goto LeaveCriticalAndFail; + } + ResourceAquiredShared = TRUE; + } + else + { + /* Acquire the resource exclusive */ + if (!ExAcquireResourceExclusiveLite(FcbHeader->Resource, Wait)) + { + goto LeaveCriticalAndFail; + } + } - LARGE_INTEGER OldFileSize; + /* Check if we are appending */ + if (FileOffsetAppend == TRUE) + { + Offset.QuadPart = FcbHeader->FileSize.QuadPart; + NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; + } + else + { + Offset.QuadPart = FileOffset->QuadPart; + NewSize.QuadPart += FileOffset->QuadPart + Length; + } - /* Sanity check */ - ASSERT(!KeIsExecutingDpc()); - - // Nagar P.544 - /* Check if we need to acquire the resource exclusive */ - if ( (FileOffsetAppend == FALSE) && - ( (FileOffset->QuadPart + Length) <= FcbHeader->ValidDataLength.QuadPart ) - ) - { - /* Acquire the resource shared */ - if (!ExAcquireResourceSharedLite(FcbHeader->Resource,Wait)) { - goto LeaveCriticalAndFail; - } - ResourceAquiredShared =TRUE; - } else { - /* Acquire the resource exclusive */ - if (!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait)) { - goto LeaveCriticalAndFail; - } - } - - /* Check if we are appending */ - if (FileOffsetAppend == TRUE) { - Offset.QuadPart = FcbHeader->FileSize.QuadPart; - NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; - } else { - Offset.QuadPart = FileOffset->QuadPart; - NewSize.QuadPart += FileOffset->QuadPart + Length; - } - - /* Nagar p.544/545 - Make sure that caching is initated. - That fast are allowed for this file stream. - That we are not extending past the allocated size - That we are not creating a hole bigger than 8k - */ - if ( (FileObject->PrivateCacheMap != NULL) && - (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && - ((FcbHeader->ValidDataLength.QuadPart + 0x2000) > Offset.QuadPart) && - (MAXLONGLONG > (Offset.QuadPart + Length)) && - (FcbHeader->AllocationSize.QuadPart >= NewSize.QuadPart) - ) - { - /* Check if we can keep the lock shared */ - if (ResourceAquiredShared && (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) ) { - ExReleaseResourceLite(FcbHeader->Resource); - if(!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait)) - { - goto LeaveCriticalAndFail; - } + /* Nagar p.544/545. + * Make sure that caching is initated. + * That fast are allowed for this file stream. + * That we are not extending past the allocated size. + * That we are not creating a hole bigger than 8k. + */ + if ((FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->ValidDataLength.QuadPart + 0x2000 > Offset.QuadPart) && + (MAXLONGLONG > Offset.QuadPart + Length) && + (FcbHeader->AllocationSize.QuadPart >= NewSize.QuadPart)) + { + /* Check if we can keep the lock shared */ + if (ResourceAquiredShared && + (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart)) + { + ExReleaseResourceLite(FcbHeader->Resource); + if (!ExAcquireResourceExclusiveLite(FcbHeader->Resource, Wait)) + { + goto LeaveCriticalAndFail; + } /* Compute the offset and the new filesize */ - if (FileOffsetAppend) { - Offset.QuadPart = FcbHeader->FileSize.QuadPart; - NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; - } + if (FileOffsetAppend) + { + Offset.QuadPart = FcbHeader->FileSize.QuadPart; + NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; + } - /* Recheck the above points since we released and reacquire the lock */ - if ( (FileObject->PrivateCacheMap != NULL) && - (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && - (FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart) - ) - { - /* Do nothing */ - } else { - goto FailAndCleanup; - } - } + /* Recheck the above points since we released and reacquire the lock */ + if ((FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart)) + { + /* Do nothing */ + } + else + { + goto FailAndCleanup; + } + } - /* Check if we need to find out if fast I/O is available */ - if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) - { - IO_STATUS_BLOCK FastIoCheckIfPossibleStatus; + /* Check if we need to find out if fast I/O is available */ + if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) + { + IO_STATUS_BLOCK FastIoCheckIfPossibleStatus; - /* Sanity check */ - ASSERT(!KeIsExecutingDpc()); + /* Sanity check */ + ASSERT(!KeIsExecutingDpc()); - /* Get the Fast I/O table */ - Device = IoGetRelatedDeviceObject(FileObject); - FastIoDispatch = Device->DriverObject->FastIoDispatch; + /* Get the Fast I/O table */ + Device = IoGetRelatedDeviceObject(FileObject); + FastIoDispatch = Device->DriverObject->FastIoDispatch; - /* Sanity check */ - ASSERT(FastIoDispatch != NULL); - ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); + /* Sanity check */ + ASSERT(FastIoDispatch != NULL); + ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); - /* Ask the driver if we can do it */ - if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, - FileOffsetAppend? &FcbHeader->FileSize:FileOffset, - Length, - TRUE, - LockKey, - FALSE, - &FastIoCheckIfPossibleStatus, - Device)) - { - /* It's not, fail */ - goto FailAndCleanup; - } - } + /* Ask the driver if we can do it */ + if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, + FileOffsetAppend ? + &FcbHeader->FileSize : + FileOffset, + Length, + TRUE, + LockKey, + FALSE, + &FastIoCheckIfPossibleStatus, + Device)) + { + /* It's not, fail */ + goto FailAndCleanup; + } + } + /* If we are going to modify the filesize, + * save the old fs in case the operation fails. + */ + if (NewSize.QuadPart > FcbHeader->FileSize.QuadPart) + { + FileSizeModified = TRUE; + OldFileSize.QuadPart = FcbHeader->FileSize.QuadPart; + OldValidDataLength.QuadPart = FcbHeader->ValidDataLength.QuadPart; - /* If we are going to modify the filesize, save the old fs in case the operation fails */ - if (NewSize.QuadPart > FcbHeader->FileSize.QuadPart) { - FileSizeModified = TRUE; - OldFileSize.QuadPart = FcbHeader->FileSize.QuadPart; - OldValidDataLength.QuadPart = FcbHeader->ValidDataLength.QuadPart; + /* If the high part of the filesize is going + * to change, grab the Paging IoResouce. + */ + if (NewSize.HighPart != FcbHeader->FileSize.HighPart && + FcbHeader->PagingIoResource) + { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->FileSize.QuadPart = NewSize.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } + else + { + FcbHeader->FileSize.QuadPart = NewSize.QuadPart; + } + } - /* If the high part of the filesize is going to change, grab the Paging IoResouce */ - if (NewSize.HighPart != FcbHeader->FileSize.HighPart && FcbHeader->PagingIoResource) { - ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); - FcbHeader->FileSize.QuadPart = NewSize.QuadPart; - ExReleaseResourceLite(FcbHeader->PagingIoResource); - } else { - FcbHeader->FileSize.QuadPart = NewSize.QuadPart; - } - } + /* Nagar p.544. + * Set ourselves as top component. + */ + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; - /* Nagar p.544 */ - /* Set ourselves as top component */ - PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; - _SEH2_TRY - { - BOOLEAN CallCc = TRUE; - /* Check if there is a gap between the end of the file and the offset - If yes, then we have to zero the data - */ - if (Offset.QuadPart > FcbHeader->ValidDataLength.QuadPart) { - if (!(Result = CcZeroData(FileObject,&FcbHeader->ValidDataLength,&Offset,Wait))) { - /* If this operation fails, then we have to exit - We can jump outside the SEH, so I a using a variable to exit - normally - */ - CallCc = FALSE; - } - } + _SEH2_TRY + { + BOOLEAN CallCc = TRUE; + + /* Check if there is a gap between the end of the file + * and the offset. If yes, then we have to zero the data. + */ + if (Offset.QuadPart > FcbHeader->ValidDataLength.QuadPart) + { + if (!(Result = CcZeroData(FileObject, + &FcbHeader->ValidDataLength, + &Offset, + Wait))) + { + /* If this operation fails, then we have to exit. We can jump + * outside the SEH, so I a using a variable to exit normally. + */ + CallCc = FALSE; + } + } /* Unless the CcZeroData failed, call the cache manager */ - if (CallCc) { - Result = CcCopyWrite(FileObject,&Offset,Length, Wait, Buffer); - } - }_SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + if (CallCc) + { + Result = CcCopyWrite(FileObject, &Offset, Length, Wait, Buffer); + } + } + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END; /* Reset the top component */ - PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; /* Did the operation suceeded */ - if (Result) { - /* Check if we need to update the filesize */ - if (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) { - if (NewSize.HighPart != FcbHeader->ValidDataLength.HighPart && FcbHeader->PagingIoResource) { - ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); - FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; - ExReleaseResourceLite(FcbHeader->PagingIoResource); - } else { - FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; - } - } + if (Result) + { + /* Check if we need to update the filesize */ + if (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) + { + if (NewSize.HighPart != FcbHeader->ValidDataLength.HighPart && + FcbHeader->PagingIoResource) + { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } + else + { + FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; + } + } /* Flag the file as modified */ - FileObject->Flags |= FO_FILE_MODIFIED; - /* Check if the filesize has changed */ - if (FileSizeModified) { - /* Update the file sizes */ - ((SHARED_CACHE_MAP*) FileObject->SectionObjectPointer->SharedCacheMap)->FileSize.QuadPart = NewSize.QuadPart; - FileObject->Flags |= FO_FILE_SIZE_CHANGED; - } - /* Update the current FO byte offset */ - FileObject->CurrentByteOffset.QuadPart = NewSize.QuadPart; - } - else - { - /* The operation did not succeed - Reset the file size to what it should be - */ - if (FileSizeModified) { - if (FcbHeader->PagingIoResource) { - ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); - FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; - FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; - ExReleaseResourceLite(FcbHeader->PagingIoResource); - }else{ - FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; - FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; - } - } - } - goto Cleanup; - } else { - goto FailAndCleanup; - } + FileObject->Flags |= FO_FILE_MODIFIED; - ASSERT(0); - } + /* Check if the filesize has changed */ + if (FileSizeModified) + { + /* Update the file sizes */ + SharedCacheMap = + (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; + SharedCacheMap->FileSize.QuadPart = NewSize.QuadPart; + FileObject->Flags |= FO_FILE_SIZE_CHANGED; + } + + /* Update the current FO byte offset */ + FileObject->CurrentByteOffset.QuadPart = NewSize.QuadPart; + } + else + { + /* The operation did not succeed. + * Reset the file size to what it should be. + */ + if (FileSizeModified) + { + if (FcbHeader->PagingIoResource) + { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; + FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } + else + { + FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; + FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; + } + } + } + + goto Cleanup; + } + else + { + goto FailAndCleanup; + } + } LeaveCriticalAndFail: + FsRtlExitFileSystem(); return FALSE; - FailAndCleanup: ExReleaseResourceLite(FcbHeader->Resource); @@ -686,7 +808,7 @@ Cleanup: */ NTSTATUS NTAPI -FsRtlGetFileSize(IN PFILE_OBJECT FileObject, +FsRtlGetFileSize(IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize) { FILE_STANDARD_INFORMATION Info; @@ -699,31 +821,36 @@ FsRtlGetFileSize(IN PFILE_OBJECT FileObject, PIRP Irp; BOOLEAN OldHardError; - PAGED_CODE(); /* Get Device Object and Fast Calls */ DeviceObject = IoGetRelatedDeviceObject(FileObject); FastDispatch = DeviceObject->DriverObject->FastIoDispatch; - /* Check if we support Fast Calls, and check FastIoQueryStandardInfo */ - /* Call the function and see if it succeeds */ - if ( !FastDispatch || - !FastDispatch->FastIoQueryStandardInfo || - !FastDispatch->FastIoQueryStandardInfo(FileObject,TRUE, - &Info,&IoStatus,DeviceObject)) + /* Check if we support Fast Calls, and check FastIoQueryStandardInfo. + * Call the function and see if it succeeds. + */ + if (!FastDispatch || + !FastDispatch->FastIoQueryStandardInfo || + !FastDispatch->FastIoQueryStandardInfo(FileObject, + TRUE, + &Info, + &IoStatus, + DeviceObject)) { - /* If any of the above failed, then we are going to send an IRP to the device object */ - /* Initialize the even for the IO */ - KeInitializeEvent(&Event,NotificationEvent,FALSE); + /* If any of the above failed, then we are going to send an + * IRP to the device object. Initialize the event for the IO. + */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + /* Allocate the IRP */ - Irp = IoAllocateIrp(DeviceObject->StackSize,FALSE); + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (Irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } - /* Don't process hard error */ OldHardError = IoSetThreadHardErrorMode(FALSE); @@ -742,16 +869,18 @@ FsRtlGetFileSize(IN PFILE_OBJECT FileObject, IoStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION; IoStackLocation->FileObject = FileObject; IoStackLocation->DeviceObject = DeviceObject; - IoStackLocation->Parameters.QueryFile.Length = ALIGN_UP(sizeof(FILE_INFORMATION_CLASS),ULONG); - IoStackLocation->Parameters.QueryFile.FileInformationClass = FileStandardInformation; + IoStackLocation->Parameters.QueryFile.Length = + ALIGN_UP(sizeof(FILE_INFORMATION_CLASS), ULONG); + IoStackLocation->Parameters.QueryFile.FileInformationClass = + FileStandardInformation; /* Send the IRP to the related device object */ - Status = IoCallDriver(DeviceObject,Irp); + Status = IoCallDriver(DeviceObject, Irp); /* Standard DDK IRP result processing */ if (Status == STATUS_PENDING) { - KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); } /* If there was a synchronous error, signal it */ @@ -766,7 +895,7 @@ FsRtlGetFileSize(IN PFILE_OBJECT FileObject, /* Check the sync/async IO result */ if (NT_SUCCESS(IoStatus.Status)) { - /* Was the request for a directory ? */ + /* Was the request for a directory? */ if (Info.Directory) { IoStatus.Status = STATUS_FILE_IS_A_DIRECTORY; @@ -780,7 +909,6 @@ FsRtlGetFileSize(IN PFILE_OBJECT FileObject, return IoStatus.Status; } - /* * @implemented */ @@ -818,8 +946,7 @@ FsRtlMdlRead(IN PFILE_OBJECT FileObject, FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; /* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->MdlRead && - BaseDeviceObject != DeviceObject) + if (FastDispatch && FastDispatch->MdlRead && BaseDeviceObject != DeviceObject) { return FALSE; } @@ -853,9 +980,7 @@ FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject, if (FastDispatch && FastDispatch->MdlReadComplete) { /* Use the fast path */ - return FastDispatch->MdlReadComplete(FileObject, - MdlChain, - DeviceObject); + return FastDispatch->MdlReadComplete(FileObject, MdlChain, DeviceObject); } /* Get the Base File System (Volume) and Fast Calls */ @@ -863,8 +988,9 @@ FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject, FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; /* If the Base Device Object has its own FastDispatch Routine, fail */ - if ((BaseDeviceObject != DeviceObject) && FastDispatch - && FastDispatch->MdlReadComplete) + if ((BaseDeviceObject != DeviceObject) && + FastDispatch && + FastDispatch->MdlReadComplete) { return FALSE; } @@ -876,8 +1002,8 @@ FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject, /* * @implemented */ - BOOLEAN - NTAPI +BOOLEAN +NTAPI FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, IN PMDL MemoryDescriptorList, IN PDEVICE_OBJECT DeviceObject) @@ -887,7 +1013,6 @@ FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, return TRUE; } - /* * @implemented */ @@ -995,10 +1120,13 @@ FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, CcMdlRead(FileObject, FileOffset, Length, MdlChain, IoStatus); FileObject->Flags |= FO_FILE_FAST_IO_READ; } - _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END; /* Remove the top-level IRP flag */ @@ -1006,8 +1134,10 @@ FsRtlMdlReadDev(IN PFILE_OBJECT FileObject, /* Return to caller */ Cleanup: + ExReleaseResourceLite(FcbHeader->Resource); FsRtlExitFileSystem(); + return Result; } @@ -1042,7 +1172,8 @@ FsRtlMdlWriteComplete(IN PFILE_OBJECT FileObject, FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; /* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->MdlWriteComplete && + if (FastDispatch && + FastDispatch->MdlWriteComplete && BaseDeviceObject != DeviceObject) { return FALSE; @@ -1067,12 +1198,11 @@ FsRtlMdlWriteCompleteDev(IN PFILE_OBJECT FileObject, { if (FileObject->Flags & FO_WRITE_THROUGH) { - return FALSE; + return FALSE; } - /* Call the Cache Manager */ - CcMdlWriteComplete2(FileObject,FileOffset,MdlChain); + CcMdlWriteComplete2(FileObject, FileOffset, MdlChain); return TRUE; } @@ -1113,7 +1243,8 @@ FsRtlPrepareMdlWrite(IN PFILE_OBJECT FileObject, FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch; /* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->PrepareMdlWrite && + if (FastDispatch && + FastDispatch->PrepareMdlWrite && BaseDeviceObject != DeviceObject) { return FALSE; @@ -1146,14 +1277,19 @@ FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, PFAST_IO_DISPATCH FastIoDispatch; PDEVICE_OBJECT Device; PFSRTL_COMMON_FCB_HEADER FcbHeader; + PSHARED_CACHE_MAP SharedCacheMap; LARGE_INTEGER OldFileSize; LARGE_INTEGER OldValidDataLength; LARGE_INTEGER NewSize; LARGE_INTEGER Offset; - /* WDK doc. Offset=0xffffffffffffffff indicates append to the end of file */ - BOOLEAN FileOffsetAppend = ((FileOffset->HighPart == (LONG)0xffffffff) && (FileOffset->LowPart == 0xffffffff)); + /* WDK doc. + * Offset == 0xffffffffffffffff indicates append to the end of file. + */ + BOOLEAN FileOffsetAppend = (FileOffset->HighPart == (LONG)0xffffffff) && + (FileOffset->LowPart == 0xffffffff); + BOOLEAN FileSizeModified = FALSE; BOOLEAN ResourceAquiredShared = FALSE; @@ -1165,11 +1301,13 @@ FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, Offset.QuadPart = FileOffset->QuadPart + Length; - /* Nagar p.544 -- Check with Cc if we can write */ - if ( (!CcCanIWrite(FileObject, Length,TRUE,FALSE))|| - (FileObject->Flags & FO_WRITE_THROUGH)) + /* Nagar p.544. + * Check with Cc if we can write. + */ + if (!CcCanIWrite(FileObject, Length, TRUE, FALSE) || + (FileObject->Flags & FO_WRITE_THROUGH)) { - return FALSE; + return FALSE; } IoStatus->Status = STATUS_SUCCESS; @@ -1184,181 +1322,219 @@ FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, FsRtlEnterFileSystem(); /* Check we are going to extend the file */ - if ( (FileOffsetAppend == FALSE) && - ( (FileOffset->QuadPart + Length) <= FcbHeader->ValidDataLength.QuadPart ) - ) - { - /* Acquire the resource shared */ - ExAcquireResourceSharedLite(FcbHeader->Resource,TRUE); - ResourceAquiredShared =TRUE; - } else - { - /* Acquire the resource exclusive */ - ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE); - } + if ((FileOffsetAppend == FALSE) && + (FileOffset->QuadPart + Length <= FcbHeader->ValidDataLength.QuadPart)) + { + /* Acquire the resource shared */ + ExAcquireResourceSharedLite(FcbHeader->Resource, TRUE); + ResourceAquiredShared = TRUE; + } + else + { + /* Acquire the resource exclusive */ + ExAcquireResourceExclusiveLite(FcbHeader->Resource, TRUE); + } - /* Check if we are appending */ - if (FileOffsetAppend == TRUE) { - Offset.QuadPart = FcbHeader->FileSize.QuadPart; - NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; - } else - { - Offset.QuadPart = FileOffset->QuadPart; - NewSize.QuadPart = FileOffset->QuadPart + Length; - } + /* Check if we are appending */ + if (FileOffsetAppend == TRUE) + { + Offset.QuadPart = FcbHeader->FileSize.QuadPart; + NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; + } + else + { + Offset.QuadPart = FileOffset->QuadPart; + NewSize.QuadPart = FileOffset->QuadPart + Length; + } - if ( (FileObject->PrivateCacheMap) && - (FcbHeader->IsFastIoPossible) && - (MAXLONGLONG >= (LONGLONG) FileOffset->QuadPart + Length) && - (NewSize.QuadPart <= FcbHeader->AllocationSize.QuadPart) ) + if ((FileObject->PrivateCacheMap) && + (FcbHeader->IsFastIoPossible) && + (MAXLONGLONG >= (LONGLONG) FileOffset->QuadPart + Length) && + (NewSize.QuadPart <= FcbHeader->AllocationSize.QuadPart)) { /* Check if we can keep the lock shared */ - if (ResourceAquiredShared && (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) ) { - ExReleaseResourceLite(FcbHeader->Resource); - ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE); + if (ResourceAquiredShared && + (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart)) + { + ExReleaseResourceLite(FcbHeader->Resource); + ExAcquireResourceExclusiveLite(FcbHeader->Resource, TRUE); /* Compute the offset and the new filesize */ - if (FileOffsetAppend) { - Offset.QuadPart = FcbHeader->FileSize.QuadPart; - NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; - } + if (FileOffsetAppend) + { + Offset.QuadPart = FcbHeader->FileSize.QuadPart; + NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; + } - /* Recheck the above points since we released and reacquire the lock */ - if ( (FileObject->PrivateCacheMap != NULL) && - (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && - (FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart) - ) - { - /* Do nothing */ - } else { - goto FailAndCleanup; - } - } + /* Recheck the above points since we released and reacquire the lock */ + if ((FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart)) + { + /* Do nothing */ + } + else + { + goto FailAndCleanup; + } + } - /* Check if we need to find out if fast I/O is available */ - if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) - { - /* Sanity check */ - /* ASSERT(!KeIsExecutingDpc()); */ + /* Check if we need to find out if fast I/O is available */ + if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) + { + /* Sanity check */ + /* ASSERT(!KeIsExecutingDpc()); */ - /* Get the Fast I/O table */ - Device = IoGetRelatedDeviceObject(FileObject); - FastIoDispatch = Device->DriverObject->FastIoDispatch; + /* Get the Fast I/O table */ + Device = IoGetRelatedDeviceObject(FileObject); + FastIoDispatch = Device->DriverObject->FastIoDispatch; - /* Sanity check */ - ASSERT(FastIoDispatch != NULL); - ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); + /* Sanity check */ + ASSERT(FastIoDispatch != NULL); + ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); - /* Ask the driver if we can do it */ - if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, - FileOffset, - Length, - TRUE, - LockKey, - FALSE, - IoStatus, - Device)) - { - /* It's not, fail */ - goto FailAndCleanup; - } - } + /* Ask the driver if we can do it */ + if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, + FileOffset, + Length, + TRUE, + LockKey, + FALSE, + IoStatus, + Device)) + { + /* It's not, fail */ + goto FailAndCleanup; + } + } - /* If we are going to modify the filesize, save the old fs in case the operation fails */ - if (NewSize.QuadPart > FcbHeader->FileSize.QuadPart) - { - FileSizeModified = TRUE; - OldFileSize.QuadPart = FcbHeader->FileSize.QuadPart; - OldValidDataLength.QuadPart = FcbHeader->ValidDataLength.QuadPart; + /* If we are going to modify the filesize, + * save the old fs in case the operation fails. + */ + if (NewSize.QuadPart > FcbHeader->FileSize.QuadPart) + { + FileSizeModified = TRUE; + OldFileSize.QuadPart = FcbHeader->FileSize.QuadPart; + OldValidDataLength.QuadPart = FcbHeader->ValidDataLength.QuadPart; - /* If the high part of the filesize is going to change, grab the Paging IoResouce */ - if (NewSize.HighPart != FcbHeader->FileSize.HighPart && FcbHeader->PagingIoResource) - { - ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); - FcbHeader->FileSize.QuadPart = NewSize.QuadPart; - ExReleaseResourceLite(FcbHeader->PagingIoResource); - } else { - FcbHeader->FileSize.QuadPart = NewSize.QuadPart; - } - } + /* If the high part of the filesize is going + * to change, grab the Paging IoResouce. + */ + if (NewSize.HighPart != FcbHeader->FileSize.HighPart && + FcbHeader->PagingIoResource) + { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->FileSize.QuadPart = NewSize.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } + else + { + FcbHeader->FileSize.QuadPart = NewSize.QuadPart; + } + } - /* Nagar p.544 */ - /* Set ourselves as top component */ - PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; - _SEH2_TRY - { - /* Check if there is a gap between the end of the file and the offset - If yes, then we have to zero the data - */ - if (Offset.QuadPart > FcbHeader->ValidDataLength.QuadPart) { - Result = CcZeroData(FileObject,&FcbHeader->ValidDataLength,&Offset,TRUE); - if (Result) - { - CcPrepareMdlWrite(FileObject,&Offset,Length,MdlChain,IoStatus); - } - } else { - CcPrepareMdlWrite(FileObject,&Offset,Length,MdlChain,IoStatus); - } + /* Nagar p.544. + * Set ourselves as top component. + */ + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + _SEH2_TRY + { + /* Check if there is a gap between the end of the file and the offset. + * If yes, then we have to zero the data. + */ + if (Offset.QuadPart > FcbHeader->ValidDataLength.QuadPart) + { + Result = CcZeroData(FileObject, + &FcbHeader->ValidDataLength, + &Offset, + TRUE); + if (Result) + { + CcPrepareMdlWrite(FileObject, + &Offset, + Length, + MdlChain, + IoStatus); + } + } + else + { + CcPrepareMdlWrite(FileObject, &Offset, Length, MdlChain, IoStatus); + } - }_SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + } + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END; /* Reset the top component */ - PsGetCurrentThread()->TopLevelIrp = 0; + PsGetCurrentThread()->TopLevelIrp = 0; /* Did the operation suceeded */ - if (Result) { - /* Check if we need to update the filesize */ - if (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) { - if (NewSize.HighPart != FcbHeader->ValidDataLength.HighPart && FcbHeader->PagingIoResource) { - ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); - FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; - ExReleaseResourceLite(FcbHeader->PagingIoResource); - } else { - FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; - } - } + if (Result) + { + /* Check if we need to update the filesize */ + if (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) + { + if (NewSize.HighPart != FcbHeader->ValidDataLength.HighPart && + FcbHeader->PagingIoResource) + { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } + else + { + FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; + } + } /* Flag the file as modified */ - FileObject->Flags |= FO_FILE_MODIFIED; - /* Check if the filesize has changed */ - if (FileSizeModified) { - /* Update the file sizes */ - ((SHARED_CACHE_MAP*) FileObject->SectionObjectPointer->SharedCacheMap)->FileSize.QuadPart = NewSize.QuadPart; - FileObject->Flags |= FO_FILE_SIZE_CHANGED; - } + FileObject->Flags |= FO_FILE_MODIFIED; - } - else - { - /* The operation did not succeed - Reset the file size to what it should be - */ - if (FileSizeModified) { - if (FcbHeader->PagingIoResource) { - ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); - FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; - FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; - ExReleaseResourceLite(FcbHeader->PagingIoResource); - }else{ - FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; - FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; - } - } - } - - goto Cleanup; + /* Check if the filesize has changed */ + if (FileSizeModified) + { + SharedCacheMap = + (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; + SharedCacheMap->FileSize.QuadPart = NewSize.QuadPart; + FileObject->Flags |= FO_FILE_SIZE_CHANGED; + } + } + else + { + /* The operation did not succeed. + * Reset the file size to what it should be. + */ + if (FileSizeModified) + { + if (FcbHeader->PagingIoResource) + { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; + FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } + else + { + FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; + FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; + } + } + } + goto Cleanup; } else { goto FailAndCleanup; } - FailAndCleanup: ExReleaseResourceLite(FcbHeader->Resource); @@ -1370,7 +1546,6 @@ Cleanup: ExReleaseResourceLite(FcbHeader->Resource); FsRtlExitFileSystem(); return Result; - } /* @@ -1380,10 +1555,8 @@ VOID NTAPI FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject) { - /* - PAGED_CODE(); - FsRtlAcquireFileExclusiveCommon(FileObject,0,0); - */ + /* PAGED_CODE(); */ + /* FsRtlAcquireFileExclusiveCommon(FileObject, 0, 0); */ KeBugCheck(FILE_SYSTEM); } @@ -1394,7 +1567,6 @@ VOID NTAPI FsRtlReleaseFile(IN PFILE_OBJECT FileObject) { - KeBugCheck(FILE_SYSTEM); } @@ -1423,4 +1595,3 @@ FsRtlRegisterFileSystemFilterCallbacks(IN PDRIVER_OBJECT FilterDriverObject, UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } - From e31f753c701b541c1e8f2242efb9b34aefd5b9f7 Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Mon, 16 Nov 2009 01:57:24 +0000 Subject: [PATCH 069/140] Fix a bug, silence GCC 4.5.x warnings. svn path=/trunk/; revision=44197 --- reactos/ntoskrnl/fsrtl/fastio.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/reactos/ntoskrnl/fsrtl/fastio.c b/reactos/ntoskrnl/fsrtl/fastio.c index 068c45ea546..78ac48e57bd 100644 --- a/reactos/ntoskrnl/fsrtl/fastio.c +++ b/reactos/ntoskrnl/fsrtl/fastio.c @@ -89,7 +89,7 @@ FsRtlCopyRead(IN PFILE_OBJECT FileObject, return TRUE; } - if (MAXLONGLONG < (LONGLONG) FileOffset->QuadPart + Length) + if (Length > MAXLONGLONG - FileOffset->QuadPart) { IoStatus->Status = STATUS_INVALID_PARAMETER; IoStatus->Information = 0; @@ -293,6 +293,11 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject, ASSERT(FileObject); ASSERT(FileObject->FsContext); +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ == 405) + /* Silence incorrect GCC 4.5.x warning */ + OldFileSize.LowPart = 0; +#endif + /* Initialize some of the vars and pointers */ NewSize.QuadPart = 0; Offset.QuadPart = FileOffset->QuadPart + Length; @@ -540,6 +545,11 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject, { LARGE_INTEGER OldFileSize; +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ == 405) + /* Silence incorrect GCC 4.5.x warning */ + OldFileSize.QuadPart = 0; +#endif + /* Sanity check */ ASSERT(!KeIsExecutingDpc()); @@ -586,7 +596,7 @@ FsRtlCopyWrite(IN PFILE_OBJECT FileObject, if ((FileObject->PrivateCacheMap != NULL) && (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && (FcbHeader->ValidDataLength.QuadPart + 0x2000 > Offset.QuadPart) && - (MAXLONGLONG > Offset.QuadPart + Length) && + (Length <= MAXLONGLONG - Offset.QuadPart) && (FcbHeader->AllocationSize.QuadPart >= NewSize.QuadPart)) { /* Check if we can keep the lock shared */ @@ -1349,7 +1359,7 @@ FsRtlPrepareMdlWriteDev(IN PFILE_OBJECT FileObject, if ((FileObject->PrivateCacheMap) && (FcbHeader->IsFastIoPossible) && - (MAXLONGLONG >= (LONGLONG) FileOffset->QuadPart + Length) && + (Length <= MAXLONGLONG - FileOffset->QuadPart) && (NewSize.QuadPart <= FcbHeader->AllocationSize.QuadPart)) { /* Check if we can keep the lock shared */ From 55d1ffb64278d8162f77202da5db9c73555ef761 Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Mon, 16 Nov 2009 01:57:59 +0000 Subject: [PATCH 070/140] Remove MmVerifierData. svn path=/trunk/; revision=44198 --- reactos/ntoskrnl/mm/sysldr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/ntoskrnl/mm/sysldr.c b/reactos/ntoskrnl/mm/sysldr.c index 26f36f8ee20..3f644261f81 100644 --- a/reactos/ntoskrnl/mm/sysldr.c +++ b/reactos/ntoskrnl/mm/sysldr.c @@ -38,7 +38,6 @@ PVOID MmUnloadedDrivers; PVOID MmLastUnloadedDrivers; PVOID MmTriageActionTaken; PVOID KernelVerifier; -MM_DRIVER_VERIFIER_DATA MmVerifierData; /* FUNCTIONS *****************************************************************/ From a2350b62d846340923560663c6882772a5e3fad9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 16 Nov 2009 07:39:52 +0000 Subject: [PATCH 071/140] - Implement OskitTCPGetSocketError which retreives so->so_error - Use OskitTCPGetSocketError to get the actual socket error which occurred when get SEL_FIN - Add more cases to TCPTranslateError svn path=/trunk/; revision=44199 --- reactos/lib/drivers/ip/transport/tcp/tcp.c | 27 ++++++++++++++----- .../lib/drivers/oskittcp/include/oskittcp.h | 2 ++ .../lib/drivers/oskittcp/oskittcp/interface.c | 14 ++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index c978bebf298..25c8d4d8657 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -27,6 +27,7 @@ static VOID DrainSignals() { PLIST_ENTRY Entry; PIRP Irp; PMDL Mdl; + ULONG SocketError; KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); CurrentEntry = ConnectionEndpointListHead.Flink; @@ -44,16 +45,27 @@ static VOID DrainSignals() { Connection, Connection->SocketContext)); if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); + Connection->SignalState = 0; + + /* If OskitTCP initiated the disconnect, try to read the socket error that occurred */ + if (Connection->SocketContext) + SocketError = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext)); + + /* Default to STATUS_CANCELLED if we initiated the disconnect or no socket error was reported */ + if (!Connection->SocketContext || !SocketError) + SocketError = STATUS_CANCELLED; + + KeReleaseSpinLock(&Connection->Lock, OldIrql); + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, &Connection->Lock )) != NULL) { Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + Complete( Bucket->Request.RequestContext, SocketError, 0 ); exFreePool(Bucket); } @@ -64,7 +76,7 @@ static VOID DrainSignals() { Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + Complete( Bucket->Request.RequestContext, SocketError, 0 ); exFreePool(Bucket); } @@ -75,7 +87,7 @@ static VOID DrainSignals() { Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + Complete( Bucket->Request.RequestContext, SocketError, 0 ); exFreePool(Bucket); } @@ -86,7 +98,7 @@ static VOID DrainSignals() { Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + Complete( Bucket->Request.RequestContext, SocketError, 0 ); exFreePool(Bucket); } @@ -573,8 +585,9 @@ NTSTATUS TCPTranslateError( int OskitError ) { case 0: Status = STATUS_SUCCESS; break; case OSK_EADDRNOTAVAIL: Status = STATUS_INVALID_ADDRESS; break; case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break; - case OSK_ECONNREFUSED: - case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break; + case OSK_ECONNREFUSED: Status = STATUS_REMOTE_NOT_LISTENING; break; + case OSK_ECONNRESET: + case OSK_ECONNABORTED: Status = STATUS_REMOTE_DISCONNECT; break; case OSK_EWOULDBLOCK: case OSK_EINPROGRESS: Status = STATUS_PENDING; break; case OSK_EINVAL: Status = STATUS_INVALID_PARAMETER; break; diff --git a/reactos/lib/drivers/oskittcp/include/oskittcp.h b/reactos/lib/drivers/oskittcp/include/oskittcp.h index b8c008e2172..64e587b7dad 100644 --- a/reactos/lib/drivers/oskittcp/include/oskittcp.h +++ b/reactos/lib/drivers/oskittcp/include/oskittcp.h @@ -164,6 +164,8 @@ int OskitTCPSetSockOpt(void *socket, int OskitTCPDisconnect(void *socket); +int OskitTCPGetSocketError(void *socket); + #undef errno void *fbsd_malloc( unsigned int bytes, char *file, unsigned line, ... ); diff --git a/reactos/lib/drivers/oskittcp/oskittcp/interface.c b/reactos/lib/drivers/oskittcp/oskittcp/interface.c index ef6f521cd58..685e4bffc64 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/interface.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/interface.c @@ -595,6 +595,20 @@ int OskitTCPGetAddress( void *socket, return 0; } +int OskitTCPGetSocketError(void *socket) { + struct socket *so = socket; + int error; + + if (!socket) + return OSK_ESHUTDOWN; + + OSKLock(); + error = so->so_error; + OSKUnlock(); + + return error; +} + struct ifaddr *ifa_iffind(struct sockaddr *addr, int type) { if( OtcpEvent.FindInterface ) From 8e33ff3436666ca8a240be148467c2ffbd89dcba Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 16 Nov 2009 18:13:56 +0000 Subject: [PATCH 072/140] - Various bugfixes found by Amine48rz svn path=/trunk/; revision=44201 --- reactos/dll/directx/directx.rbuild | 4 ++-- reactos/dll/directx/dsound_new/devicelist.c | 2 +- reactos/dll/directx/dsound_new/enum.c | 6 +++++- reactos/dll/directx/dsound_new/notify.c | 1 - 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/reactos/dll/directx/directx.rbuild b/reactos/dll/directx/directx.rbuild index 1f5718d37c6..6521275d0c6 100644 --- a/reactos/dll/directx/directx.rbuild +++ b/reactos/dll/directx/directx.rbuild @@ -25,8 +25,8 @@ - - + + diff --git a/reactos/dll/directx/dsound_new/devicelist.c b/reactos/dll/directx/dsound_new/devicelist.c index 87ca9339e8e..8441eb99146 100644 --- a/reactos/dll/directx/dsound_new/devicelist.c +++ b/reactos/dll/directx/dsound_new/devicelist.c @@ -408,7 +408,7 @@ EnumAudioDeviceInterfaces( } /* sanity check */ - ASSERT(OutRootInfo); + ASSERT(*OutRootInfo); CurInfo = *OutRootInfo; diff --git a/reactos/dll/directx/dsound_new/enum.c b/reactos/dll/directx/dsound_new/enum.c index 163c19ff2dc..777168fb27a 100644 --- a/reactos/dll/directx/dsound_new/enum.c +++ b/reactos/dll/directx/dsound_new/enum.c @@ -91,7 +91,11 @@ DoDSoundCallback( } DriverNameA[0] = 0; - WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL); + if (ProductName) + { + WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL); + DriverNameA[(sizeof(DriverNameA) / sizeof(char))-1] = 0; + } return lpDSEnumCallbackA(DeviceGuid, (LPSTR)Buffer, DriverNameA, lpContext); } diff --git a/reactos/dll/directx/dsound_new/notify.c b/reactos/dll/directx/dsound_new/notify.c index e3e31da7855..8028b48a60c 100644 --- a/reactos/dll/directx/dsound_new/notify.c +++ b/reactos/dll/directx/dsound_new/notify.c @@ -157,7 +157,6 @@ IDirectSoundNotify_fnSetNotificationPositions( if (Result != ERROR_SUCCESS) { DPRINT1("Failed to enable event %p Position %u\n", pcPositionNotifies[Index].hEventNotify, pcPositionNotifies[Index].dwOffset); - return DSERR_GENERIC; } } } From 9d604a73e10ac3c2474f8203fca20d20a53d3fb5 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 16 Nov 2009 18:24:36 +0000 Subject: [PATCH 073/140] - Build fix by Pigglesworth svn path=/trunk/; revision=44202 --- reactos/dll/directx/directx.rbuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/dll/directx/directx.rbuild b/reactos/dll/directx/directx.rbuild index 6521275d0c6..1f5718d37c6 100644 --- a/reactos/dll/directx/directx.rbuild +++ b/reactos/dll/directx/directx.rbuild @@ -25,8 +25,8 @@ - - + + From 84e0310943d62652a5e97bdb41deeddd594bb05b Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Mon, 16 Nov 2009 18:32:30 +0000 Subject: [PATCH 074/140] Revert yesterday's fix for now. svn path=/trunk/; revision=44203 --- reactos/tools/rbuild/backend/mingw/linkers/ld.mak | 8 +++----- reactos/tools/rbuild/backend/mingw/mingw.cpp | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak index f90947d4aa9..812f30ec874 100644 --- a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak +++ b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak @@ -5,7 +5,7 @@ LDFLAG_CONSOLE:=--subsystem=console LDFLAG_WINDOWS:=--subsystem=windows LDFLAG_NATIVE:=--subsystem=native -#(module, objs, deps, ldflags, output, def, libs, entry, base, extralibs) +#(module, objs, deps, ldflags, output, def, libs, entry, base) define RBUILD_LINK ifneq ($(6),) @@ -29,7 +29,7 @@ endif $(5): $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(7) $(3) $$(RSYM_TARGET) $$(PEFIXUP_TARGET) | ${call RBUILD_dir,$(5)} $$(ECHO_LD) - $${ld} --entry=$(8) --image-base=$(9) $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(10) $(7) $(10) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ + $${ld} --entry=$(8) --image-base=$(9) $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(7) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ ifneq ($(or $(6),$$(MODULETYPE$$($(1)_TYPE)_KMODE)),) $$(ECHO_PEFIXUP) $$(Q)$$(PEFIXUP_TARGET) $$@ $(if $(6),-exports) $$(if $$(MODULETYPE$($(1)_TYPE)_KMODE),-sections) @@ -67,6 +67,4 @@ endif endef #(module, def, deps, ldflags, libs, entry, base) -#~ RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(5) $(value $(1)_LIBS) $(5),$(6),$(7)} -#(module, def, deps, ldflags, libs, entry, base, extralibs) -RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(value $(1)_LIBS),$(6),$(7),$(5)} +RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(5) $(value $(1)_LIBS) $(5),$(6),$(7)} diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index aa4c3fec427..472e5960dac 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -479,8 +479,8 @@ MingwBackend::GenerateGlobalVariables () const // Would be nice to have our own C++ runtime fputs ( "BUILTIN_CXXINCLUDES+= $(TARGET_CPPFLAGS)\n", fMakefile ); - fprintf ( fMakefile, "PROJECT_CCLIBS := \"$(shell ${TARGET_CC} -print-libgcc-file-name)\"\n" ); - fprintf ( fMakefile, "PROJECT_CXXLIBS := \"$(shell ${TARGET_CPP} -print-file-name=libstdc++.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libgcc.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libmingw32.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libmingwex.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libcoldname.a)\"\n" ); + fprintf ( fMakefile, "PROJECT_CCLIBS := $(shell ${TARGET_CC} -print-libgcc-file-name)\n" ); + fprintf ( fMakefile, "PROJECT_CXXLIBS := $(shell ${TARGET_CPP} -print-file-name=libstdc++.a) $(shell ${TARGET_CPP} -print-file-name=libgcc.a) $(shell ${TARGET_CPP} -print-file-name=libmingw32.a) $(shell ${TARGET_CPP} -print-file-name=libmingwex.a) $(shell ${TARGET_CPP} -print-file-name=libcoldname.a)\n" ); /* hack to get libgcc_eh.a, should check mingw version or something */ if (Environment::GetArch() == "amd64") From 70faa1388dd0dc2e115dc657a88492003e6bf0f8 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Tue, 17 Nov 2009 02:54:29 +0000 Subject: [PATCH 075/140] modified Makefile $(ECHO_DLLTOOL) -> $(ECHO_IMPLIB) New status line ECHO_RSP for built-in response file generator rule $(NL) variable that expands to a newline -- only known way to escape the newline character in GNU make modified tools/rbuild/backend/mingw/linkers/ld.mak $(ECHO DLLTOOL) -> $(ECHO_DLLTOOL) -> $(ECHO_IMPLIB) Generate a response file with the list of object files, instead of passing every single object file on the linker command line. Our really long linker command lines should no longer be an issue modified tools/rbuild/backend/mingw/modulehandler.cpp Clean files generated by externally-defined rules Build issues fix 1/2 (1/3?) svn path=/trunk/; revision=44208 --- reactos/Makefile | 11 +++++++++-- .../tools/rbuild/backend/mingw/linkers/ld.mak | 19 ++++++++++++++----- .../rbuild/backend/mingw/modulehandler.cpp | 3 +++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/reactos/Makefile b/reactos/Makefile index e6a7d58b371..a2a184725ae 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -152,6 +152,11 @@ $(error ReactOS's makefiles use GNU Make 3.80+ features, you have $(MAKE_VERSION endif # END of code borrowed from GMSL ( http://gmsl.sourceforge.net/ ) +define NL + + +endef + .PHONY: all .PHONY: clean .PHONY: world @@ -234,7 +239,7 @@ ifeq ($(HALFVERBOSEECHO),yes) ECHO_CVTRES =@echo $(QUOTE)[CVTRES] $@$(QUOTE) ECHO_WIDL =@echo $(QUOTE)[WIDL] $@$(QUOTE) ECHO_BIN2RES =@echo $(QUOTE)[BIN2RES] $<$(QUOTE) - ECHO_DLLTOOL =@echo $(QUOTE)[DLLTOOL] $@$(QUOTE) + ECHO_IMPLIB =@echo $(QUOTE)[IMPLIB] $@$(QUOTE) ECHO_LD =@echo $(QUOTE)[LD] $@$(QUOTE) ECHO_HOSTLD =@echo $(QUOTE)[HOST-LD] $@$(QUOTE) ECHO_LINK =@echo $(QUOTE)[LINK] $@$(QUOTE) @@ -254,6 +259,7 @@ ifeq ($(HALFVERBOSEECHO),yes) ECHO_STRIP =@echo $(QUOTE)[STRIP] $@$(QUOTE) ECHO_RGENSTAT=@echo $(QUOTE)[RGENSTAT] $@$(QUOTE) ECHO_DEPENDS =@echo $(QUOTE)[DEPENDS] $<$(QUOTE) + ECHO_RSP =@echo $(QUOTE)[RSP] $@$(QUOTE) else ECHO_CP = ECHO_MKDIR = @@ -273,7 +279,7 @@ else ECHO_CVTRES = ECHO_WIDL = ECHO_BIN2RES = - ECHO_DLLTOOL = + ECHO_IMPLIB = ECHO_LD = ECHO_HOSTLD = ECHO_NM = @@ -291,6 +297,7 @@ else ECHO_STRIP = ECHO_RGENSTAT= ECHO_DEPENDS = + ECHO_RSP = endif # Set host compiler/linker diff --git a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak index 812f30ec874..b458109dcf7 100644 --- a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak +++ b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak @@ -10,15 +10,15 @@ define RBUILD_LINK ifneq ($(6),) ${call RBUILD_intermediate_dir,$(5)}$$(SEP)lib${call RBUILD_name,$(5)}.a: $(6) | ${call RBUILD_intermediate_path,$(5)} - $$(ECHO DLLTOOL) + $$(ECHO_IMPLIB) $${dlltool} --def $(6) --kill-at --output-lib=$$@ ${call RBUILD_intermediate_dir,$(5)}$$(SEP)lib${call RBUILD_name,$(5)}.delayimp.a: $(6) | ${call RBUILD_intermediate_path,$(5)} - $$(ECHO DLLTOOL) + $$(ECHO_IMPLIB) $${dlltool} --def $(6) --kill-at --output-delaylib=$$@ ${call RBUILD_intermediate_path_noext,$(5)}.exp: $(6) | ${call RBUILD_intermediate_path,$(5)} - $$(ECHO DLLTOOL) + $$(ECHO_IMPLIB) $${dlltool} --def $(6) --kill-at --output-exp=$$@ $(1)_CLEANFILES+=\ @@ -27,9 +27,18 @@ $(1)_CLEANFILES+=\ ${call RBUILD_intermediate_path_noext,$(5)}.exp endif -$(5): $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(7) $(3) $$(RSYM_TARGET) $$(PEFIXUP_TARGET) | ${call RBUILD_dir,$(5)} +# TODO: refactor this out of here and into rules.mak +${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp: $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(3) | ${call RBUILD_intermediate_dir,$(5)} + $$(ECHO_RSP) + -@$${rm} $$@ 2>$$(NUL) + $${cp} $$(NUL) $$@ >$$(NUL) + $$(foreach obj,$(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp),$$(Q)echo $$(QUOTE)$$(subst \,\\,$$(obj))$$(QUOTE)>>$$@$$(NL)) + +$(1)_CLEANFILES+=${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp + +$(5): ${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp $(7) $(3) $$(RSYM_TARGET) $$(PEFIXUP_TARGET) | ${call RBUILD_dir,$(5)} $$(ECHO_LD) - $${ld} --entry=$(8) --image-base=$(9) $(2) $$(if $(6),${call RBUILD_intermediate_path_noext,$(5)}.exp) $(7) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ + $${ld} --entry=$(8) --image-base=$(9) @${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp $(7) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ ifneq ($(or $(6),$$(MODULETYPE$$($(1)_TYPE)_KMODE)),) $$(ECHO_PEFIXUP) $$(Q)$$(PEFIXUP_TARGET) $$@ $(if $(6),-exports) $$(if $$(MODULETYPE$($(1)_TYPE)_KMODE),-sections) diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp index 1609d63ec9c..a372a71b24e 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp @@ -516,6 +516,9 @@ MingwModuleHandler::GenerateCleanTarget () const } fprintf ( fMakefile, " 2>$(NUL)\n" ); + // Clean files generated by external rules + fprintf ( fMakefile, "\t-@${rm} $(%s_CLEANFILES) 2>$(NUL)\n", module.name.c_str() ); + if( ProxyMakefile::GenerateProxyMakefile(module) ) { DirectoryLocation root; From 590c766281ab177b78ec2e05d8b5a1ab7facf18a Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Tue, 17 Nov 2009 16:18:34 +0000 Subject: [PATCH 076/140] Reapplying r44182. Thanks to r44208, it should actually work this time svn path=/trunk/; revision=44215 --- reactos/tools/rbuild/backend/mingw/linkers/ld.mak | 12 ++++++++---- reactos/tools/rbuild/backend/mingw/mingw.cpp | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak index b458109dcf7..dbba33ea4f6 100644 --- a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak +++ b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak @@ -5,7 +5,8 @@ LDFLAG_CONSOLE:=--subsystem=console LDFLAG_WINDOWS:=--subsystem=windows LDFLAG_NATIVE:=--subsystem=native -#(module, objs, deps, ldflags, output, def, libs, entry, base) +#~ #(module, objs, deps, ldflags, output, def, libs, entry, base) +#(module, objs, deps, ldflags, output, def, libs, entry, base, extralibs) define RBUILD_LINK ifneq ($(6),) @@ -38,7 +39,8 @@ $(1)_CLEANFILES+=${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp $(5): ${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp $(7) $(3) $$(RSYM_TARGET) $$(PEFIXUP_TARGET) | ${call RBUILD_dir,$(5)} $$(ECHO_LD) - $${ld} --entry=$(8) --image-base=$(9) @${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp $(7) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ +#~ $${ld} --entry=$(8) --image-base=$(9) @${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp $(7) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ + $${ld} --entry=$(8) --image-base=$(9) @${call RBUILD_intermediate_dir,$(5)}$$(SEP)$(1)_objs.rsp $(10) $(7) $(10) ${call RBUILD_ldflags,$(1),$(4)} -o $$@ ifneq ($(or $(6),$$(MODULETYPE$$($(1)_TYPE)_KMODE)),) $$(ECHO_PEFIXUP) $$(Q)$$(PEFIXUP_TARGET) $$@ $(if $(6),-exports) $$(if $$(MODULETYPE$($(1)_TYPE)_KMODE),-sections) @@ -75,5 +77,7 @@ endif endef -#(module, def, deps, ldflags, libs, entry, base) -RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(5) $(value $(1)_LIBS) $(5),$(6),$(7)} +#~ #(module, def, deps, ldflags, libs, entry, base) +#~ RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(5) $(value $(1)_LIBS) $(5),$(6),$(7)} +#(module, def, deps, ldflags, libs, entry, base, extralibs) +RBUILD_LINK_RULE=${call RBUILD_LINK,$(1),$(value $(1)_OBJS),$(3),$(4),$(value $(1)_TARGET),$(2),$(value $(1)_LIBS),$(6),$(7),$(5)} diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index 472e5960dac..aa4c3fec427 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -479,8 +479,8 @@ MingwBackend::GenerateGlobalVariables () const // Would be nice to have our own C++ runtime fputs ( "BUILTIN_CXXINCLUDES+= $(TARGET_CPPFLAGS)\n", fMakefile ); - fprintf ( fMakefile, "PROJECT_CCLIBS := $(shell ${TARGET_CC} -print-libgcc-file-name)\n" ); - fprintf ( fMakefile, "PROJECT_CXXLIBS := $(shell ${TARGET_CPP} -print-file-name=libstdc++.a) $(shell ${TARGET_CPP} -print-file-name=libgcc.a) $(shell ${TARGET_CPP} -print-file-name=libmingw32.a) $(shell ${TARGET_CPP} -print-file-name=libmingwex.a) $(shell ${TARGET_CPP} -print-file-name=libcoldname.a)\n" ); + fprintf ( fMakefile, "PROJECT_CCLIBS := \"$(shell ${TARGET_CC} -print-libgcc-file-name)\"\n" ); + fprintf ( fMakefile, "PROJECT_CXXLIBS := \"$(shell ${TARGET_CPP} -print-file-name=libstdc++.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libgcc.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libmingw32.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libmingwex.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libcoldname.a)\"\n" ); /* hack to get libgcc_eh.a, should check mingw version or something */ if (Environment::GetArch() == "amd64") From 4e2f21b12bfabdac88843bfea9cf1da4a8c203ee Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Tue, 17 Nov 2009 17:00:01 +0000 Subject: [PATCH 077/140] Goodbye win32k_base, you won't be missed svn path=/trunk/; revision=44216 --- reactos/subsystems/win32/win32k/win32k.rbuild | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/reactos/subsystems/win32/win32k/win32k.rbuild b/reactos/subsystems/win32/win32k/win32k.rbuild index b91c8072ea3..b5658babf67 100644 --- a/reactos/subsystems/win32/win32k/win32k.rbuild +++ b/reactos/subsystems/win32/win32k/win32k.rbuild @@ -1,10 +1,17 @@ - - . - include - . + + + pseh + ntoskrnl + hal + ftfd + dxguid + win32k.rc + . + include + . include include include/reactos/subsys @@ -202,14 +209,4 @@ -fno-unit-at-a-time - - - win32k_base - pseh - ntoskrnl - hal - ftfd - dxguid - win32k.rc - From b5a0cbacfbe99104a0b5c0b0b0e003bc6dea32c6 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 18 Nov 2009 14:16:34 +0000 Subject: [PATCH 078/140] - Properly convert mswsock.def to mswsock.spec (we have all functions properly stubbed). - Remove WSPStartup from ws2_32, it doesn't belong there. Spotted by Gabriel Ilardi. See issue #4956 for more details. svn path=/trunk/; revision=44224 --- reactos/dll/win32/mswsock/mswsock.def | 39 ------------------- reactos/dll/win32/mswsock/mswsock.spec | 52 +++++++++++++------------- reactos/dll/win32/ws2_32/misc/stubs.c | 17 --------- 3 files changed, 26 insertions(+), 82 deletions(-) delete mode 100644 reactos/dll/win32/mswsock/mswsock.def diff --git a/reactos/dll/win32/mswsock/mswsock.def b/reactos/dll/win32/mswsock/mswsock.def deleted file mode 100644 index 3fca87120a5..00000000000 --- a/reactos/dll/win32/mswsock/mswsock.def +++ /dev/null @@ -1,39 +0,0 @@ -; $Id$ -; -; MSWSOCK.DLL - Windows Sockets 2 DLL - -LIBRARY mswsock.dll - -EXPORTS -ServiceMain@8 @0 -SvchostPushServiceGlobals@4 @1 -AcceptEx@32 @2 -EnumProtocolsA@12 @3 -EnumProtocolsW@12 @4 -GetAcceptExSockaddrs@32 @5 -GetAddressByNameA@40 @6 -GetAddressByNameW@40 @7 -GetNameByTypeA@12 @8 -GetNameByTypeW@12 @9 -GetServiceA@28 @10 -GetServiceW@28 @11 -GetTypeByNameA@8 @12 -GetTypeByNameW@8 @13 -MigrateWinsockConfiguration@12 @14 -NPLoadNameSpaces@12 @15 -NSPStartup@8 @16 -SetServiceA@24 @17 -SetServiceW@24 @18 -StartWsdpService@0 @19 -StopWsdpService@0 @20 -TransmitFile@28 @21 -WSARecvEx@16 @22 -WSPStartup@76 @23 -dn_expand@20 @24 -getnetbyname@4 @25 -inet_network@4 @26 -rcmd@24 @27 -rexec@24 @28 -rresvport@4 @29 -s_perror@4 @30 -sethostname@8 @31 diff --git a/reactos/dll/win32/mswsock/mswsock.spec b/reactos/dll/win32/mswsock/mswsock.spec index 1f2bd7824af..0fef34d96d9 100644 --- a/reactos/dll/win32/mswsock/mswsock.spec +++ b/reactos/dll/win32/mswsock/mswsock.spec @@ -2,31 +2,31 @@ @ stdcall EnumProtocolsA(ptr ptr ptr) ws2_32.WSAEnumProtocolsA @ stdcall EnumProtocolsW(ptr ptr ptr) ws2_32.WSAEnumProtocolsW @ stdcall GetAcceptExSockaddrs(ptr long long long ptr ptr ptr ptr) -@ stub GetAddressByNameA -@ stub GetAddressByNameW -@ stub GetNameByTypeA -@ stub GetNameByTypeW -@ stub GetServiceA -@ stub GetServiceW -@ stub GetTypeByNameA -@ stub GetTypeByNameW -@ stub MigrateWinsockConfiguration -@ stub NPLoadNameSpaces -@ stub NSPStartup -@ stub ServiceMain -@ stub SetServiceA -@ stub SetServiceW -@ stub StartWsdpService -@ stub StopWsdpService -@ stub SvchostPushServiceGlobals +@ stdcall GetAddressByNameA(long ptr ptr ptr long ptr ptr ptr ptr ptr) +@ stdcall GetAddressByNameW(long ptr ptr ptr long ptr ptr ptr ptr ptr) +@ stdcall GetNameByTypeA(ptr ptr long) +@ stdcall GetNameByTypeW(ptr ptr long) +@ stdcall GetServiceA(long ptr ptr long ptr ptr ptr) +@ stdcall GetServiceW(long ptr ptr long ptr ptr ptr) +@ stdcall GetTypeByNameA(ptr ptr) +@ stdcall GetTypeByNameW(ptr ptr) +@ stdcall MigrateWinsockConfiguration(long long long) +@ stdcall NPLoadNameSpaces(ptr ptr ptr) +@ stdcall NSPStartup(ptr ptr) +@ stdcall ServiceMain(long long) +@ stdcall SetServiceA(long long long ptr ptr ptr) +@ stdcall SetServiceW(long long long ptr ptr ptr) +@ stdcall StartWsdpService() +@ stdcall StopWsdpService() +@ stdcall SvchostPushServiceGlobals(long) @ stdcall TransmitFile(long long long long ptr ptr long) @ stdcall WSARecvEx(long ptr long ptr) -@ stub WSPStartup -@ stub dn_expand -@ stub getnetbyname -@ stub inet_network -@ stub rcmd -@ stub rexec -@ stub rresvport -@ stub s_perror -@ stub sethostname +@ stdcall WSPStartup(long ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) +@ stdcall dn_expand(ptr ptr ptr ptr long) +@ stdcall getnetbyname(ptr) +@ stdcall inet_network(ptr) +@ stdcall rcmd(ptr long ptr ptr ptr ptr) +@ stdcall rexec(ptr long ptr ptr ptr ptr) +@ stdcall rresvport(ptr) +@ stdcall s_perror(ptr) +@ stdcall sethostname(ptr long) diff --git a/reactos/dll/win32/ws2_32/misc/stubs.c b/reactos/dll/win32/ws2_32/misc/stubs.c index a5fe5a3d510..408f28294a6 100644 --- a/reactos/dll/win32/ws2_32/misc/stubs.c +++ b/reactos/dll/win32/ws2_32/misc/stubs.c @@ -703,23 +703,6 @@ WPUCompleteOverlappedRequest(IN SOCKET s, } -/* - * @unimplemented - */ -INT -EXPORT -WSPStartup(IN WORD wVersionRequested, - OUT LPWSPDATA lpWSPData, - IN LPWSAPROTOCOL_INFOW lpProtocolInfo, - IN WSPUPCALLTABLE UpcallTable, - OUT LPWSPPROC_TABLE lpProcTable) -{ - UNIMPLEMENTED - - return WSASYSCALLFAILURE; -} - - /* * @unimplemented */ From f0fa2f117f563812b89c6281e224145fe6a151c2 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 18 Nov 2009 14:37:31 +0000 Subject: [PATCH 079/140] [rapps] Andrey Yastrebov - Fix app uninstallation feature (wrong lparam usage - it's pointer to PINSTALLED_INFO and not an hkey). See issue #4961 for more details. svn path=/trunk/; revision=44225 --- reactos/base/applications/rapps/installed.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/reactos/base/applications/rapps/installed.c b/reactos/base/applications/rapps/installed.c index 80991c91df7..8c8cb33f172 100644 --- a/reactos/base/applications/rapps/installed.c +++ b/reactos/base/applications/rapps/installed.c @@ -89,6 +89,7 @@ UninstallApplication(INT Index, BOOL bModify) INT ItemIndex; LVITEM Item; HKEY hKey; + PINSTALLED_INFO ItemInfo; if (!IS_INSTALLED_ENUM(SelectedEnumType)) return FALSE; @@ -114,7 +115,8 @@ UninstallApplication(INT Index, BOOL bModify) if (!ListView_GetItem(hListView, &Item)) return FALSE; - hKey = (HKEY)Item.lParam; + ItemInfo = (PINSTALLED_INFO)Item.lParam; + hKey = ItemInfo->hSubKey; dwType = REG_SZ; dwSize = MAX_PATH; From d6c7749eba958a324d90d2dc28c9b91a8cbe0fe2 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 18 Nov 2009 18:15:49 +0000 Subject: [PATCH 080/140] Fixed typo (lost patch found in the dust) svn path=/trunk/; revision=44227 --- reactos/drivers/filesystems/fastfat_new/fsctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/drivers/filesystems/fastfat_new/fsctl.c b/reactos/drivers/filesystems/fastfat_new/fsctl.c index 6059c1bc6f3..2953836cc45 100644 --- a/reactos/drivers/filesystems/fastfat_new/fsctl.c +++ b/reactos/drivers/filesystems/fastfat_new/fsctl.c @@ -99,7 +99,7 @@ FatMountVolume(PFAT_IRP_CONTEXT IrpContext, /* Make sure this IRP is waitable */ ASSERT(IrpContext->Flags & IRPCONTEXT_CANWAIT); - /* Request media changes count, mostly usefull for removable devices */ + /* Request media changes count, mostly useful for removable devices */ Status = FatPerformDevIoCtrl(TargetDeviceObject, IOCTL_STORAGE_CHECK_VERIFY, NULL, From ad2dffe03010a7ba694c09d1c136583659ef9761 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 20 Nov 2009 14:22:05 +0000 Subject: [PATCH 081/140] [wininet] - Update wininet to Wine-1.1.33. svn path=/trunk/; revision=44236 --- reactos/dll/win32/wininet/cookie.c | 29 ++++++---- reactos/dll/win32/wininet/ftp.c | 1 + reactos/dll/win32/wininet/http.c | 12 +++- reactos/dll/win32/wininet/internet.c | 9 ++- reactos/dll/win32/wininet/netconnection.c | 14 ++--- reactos/dll/win32/wininet/urlcache.c | 22 ++++++++ reactos/dll/win32/wininet/wininet.spec | 4 +- reactos/dll/win32/wininet/wininet_Lt.rc | 69 +++++++++++++++++++++++ 8 files changed, 133 insertions(+), 27 deletions(-) create mode 100644 reactos/dll/win32/wininet/wininet_Lt.rc diff --git a/reactos/dll/win32/wininet/cookie.c b/reactos/dll/win32/wininet/cookie.c index 30e0b99ee92..75cf049308b 100644 --- a/reactos/dll/win32/wininet/cookie.c +++ b/reactos/dll/win32/wininet/cookie.c @@ -163,7 +163,6 @@ static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path) static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostNameLen, LPWSTR path, int pathLen) { URL_COMPONENTSW UrlComponents; - BOOL rc; UrlComponents.lpszExtraInfo = NULL; UrlComponents.lpszPassword = NULL; @@ -178,22 +177,28 @@ static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostName UrlComponents.dwHostNameLength = hostNameLen; UrlComponents.dwUrlPathLength = pathLen; - rc = InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents); + if (!InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents)) return FALSE; /* discard the webpage off the end of the path */ - if (pathLen > 0 && path[pathLen-1] != '/') + if (UrlComponents.dwUrlPathLength) { - LPWSTR ptr; - ptr = strrchrW(path,'/'); - if (ptr) - *(++ptr) = 0; - else + if (path[UrlComponents.dwUrlPathLength - 1] != '/') { - path[0] = '/'; - path[1] = 0; + WCHAR *ptr; + if ((ptr = strrchrW(path, '/'))) *(++ptr) = 0; + else + { + path[0] = '/'; + path[1] = 0; + } } } - return rc; + else if (pathLen >= 2) + { + path[0] = '/'; + path[1] = 0; + } + return TRUE; } /* match a domain. domain must match if the domain is not NULL. path must match if the path is not NULL */ @@ -569,7 +574,7 @@ BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, return FALSE; } - hostName[0] = path[0] = 0; + hostName[0] = 0; ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0])); if (!ret || !hostName[0]) return FALSE; diff --git a/reactos/dll/win32/wininet/ftp.c b/reactos/dll/win32/wininet/ftp.c index b0dc695f1af..f0c3cbd02c4 100644 --- a/reactos/dll/win32/wininet/ftp.c +++ b/reactos/dll/win32/wininet/ftp.c @@ -1293,6 +1293,7 @@ HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs, lpwh->hdr.vtbl = &FTPFILEVtbl; lpwh->hdr.dwFlags = dwFlags; lpwh->hdr.dwContext = dwContext; + lpwh->hdr.dwInternalFlags = 0; lpwh->hdr.refs = 1; lpwh->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB; lpwh->nDataSocket = nDataSocket; diff --git a/reactos/dll/win32/wininet/http.c b/reactos/dll/win32/wininet/http.c index 87d5e721571..3a14f7ad844 100644 --- a/reactos/dll/win32/wininet/http.c +++ b/reactos/dll/win32/wininet/http.c @@ -3340,8 +3340,16 @@ BOOL WINAPI HttpSendRequestExW(HINTERNET hRequest, req = &workRequest.u.HttpSendRequestW; if (lpBuffersIn) { - /* FIXME: this should use dwHeadersLength or may not be necessary at all */ - req->lpszHeader = heap_strdupW(lpBuffersIn->lpcszHeader); + DWORD size; + + if (lpBuffersIn->dwHeadersLength == ~0u) + size = (strlenW( lpBuffersIn->lpcszHeader ) + 1) * sizeof(WCHAR); + else + size = lpBuffersIn->dwHeadersLength * sizeof(WCHAR); + + req->lpszHeader = HeapAlloc( GetProcessHeap(), 0, size ); + memcpy( req->lpszHeader, lpBuffersIn->lpcszHeader, size ); + req->dwHeaderLength = lpBuffersIn->dwHeadersLength; req->lpOptional = lpBuffersIn->lpvBuffer; req->dwOptionalLength = lpBuffersIn->dwBufferLength; diff --git a/reactos/dll/win32/wininet/internet.c b/reactos/dll/win32/wininet/internet.c index ca7b982326e..f61074c438f 100644 --- a/reactos/dll/win32/wininet/internet.c +++ b/reactos/dll/win32/wininet/internet.c @@ -1133,11 +1133,14 @@ static void ConvertUrlComponentValue(LPSTR* lppszComponent, LPDWORD dwComponentL DWORD nASCIILength=WideCharToMultiByte(CP_ACP,0,lpwszComponent,dwwComponentLen,NULL,0,NULL,NULL); if (*lppszComponent == NULL) { - int nASCIIOffset=WideCharToMultiByte(CP_ACP,0,lpwszStart,lpwszComponent-lpwszStart,NULL,0,NULL,NULL); if (lpwszComponent) - *lppszComponent = (LPSTR)lpszStart+nASCIIOffset; + { + int offset = WideCharToMultiByte(CP_ACP, 0, lpwszStart, lpwszComponent-lpwszStart, NULL, 0, NULL, NULL); + *lppszComponent = (LPSTR)lpszStart + offset; + } else *lppszComponent = NULL; + *dwComponentLen = nASCIILength; } else @@ -1184,7 +1187,7 @@ BOOL WINAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, InternetCrackUrlW should not include it */ if (dwUrlLength == -1) nLength--; - lpwszUrl=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR)*nLength); + lpwszUrl = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR)); MultiByteToWideChar(CP_ACP,0,lpszUrl,dwUrlLength,lpwszUrl,nLength); memset(&UCW,0,sizeof(UCW)); diff --git a/reactos/dll/win32/wininet/netconnection.c b/reactos/dll/win32/wininet/netconnection.c index 97c764fc345..16cce406533 100644 --- a/reactos/dll/win32/wininet/netconnection.c +++ b/reactos/dll/win32/wininet/netconnection.c @@ -289,14 +289,6 @@ void NETCON_unload(void) #if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO) if (OpenSSL_crypto_handle) { - if (ssl_locks) - { - int i; - - for (i = 0; i < pCRYPTO_num_locks(); i++) - DeleteCriticalSection(&ssl_locks[i]); - HeapFree(GetProcessHeap(), 0, ssl_locks); - } wine_dlclose(OpenSSL_crypto_handle, NULL, 0); } if (OpenSSL_ssl_handle) @@ -305,6 +297,12 @@ void NETCON_unload(void) pSSL_CTX_free(ctx); wine_dlclose(OpenSSL_ssl_handle, NULL, 0); } + if (ssl_locks) + { + int i; + for (i = 0; i < pCRYPTO_num_locks(); i++) DeleteCriticalSection(&ssl_locks[i]); + HeapFree(GetProcessHeap(), 0, ssl_locks); + } #endif } diff --git a/reactos/dll/win32/wininet/urlcache.c b/reactos/dll/win32/wininet/urlcache.c index 37d7b259fd6..29d26ab0b6b 100644 --- a/reactos/dll/win32/wininet/urlcache.c +++ b/reactos/dll/win32/wininet/urlcache.c @@ -1448,6 +1448,28 @@ static BOOL URLCache_EnumHashTableEntries(LPCURLCACHE_HEADER pHeader, const HASH return FALSE; } +/*********************************************************************** + * FreeUrlCacheSpaceA (WININET.@) + * + */ +BOOL WINAPI FreeUrlCacheSpaceA(LPCSTR lpszCachePath, DWORD dwSize, DWORD dwFilter) +{ + FIXME("stub!\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + + /*********************************************************************** + * FreeUrlCacheSpaceW (WININET.@) + * + */ +BOOL WINAPI FreeUrlCacheSpaceW(LPCWSTR lpszCachePath, DWORD dwSize, DWORD dwFilter) +{ + FIXME("stub!\n"); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + /*********************************************************************** * GetUrlCacheEntryInfoExA (WININET.@) * diff --git a/reactos/dll/win32/wininet/wininet.spec b/reactos/dll/win32/wininet/wininet.spec index d5995eb3cc3..46dd04334e6 100644 --- a/reactos/dll/win32/wininet/wininet.spec +++ b/reactos/dll/win32/wininet/wininet.spec @@ -50,8 +50,8 @@ @ stdcall FindNextUrlCacheGroup(long ptr ptr) @ stub ForceNexusLookup @ stub ForceNexusLookupExW -@ stub FreeUrlCacheSpaceA -@ stub FreeUrlCacheSpaceW +@ stdcall FreeUrlCacheSpaceA(str long long) +@ stdcall FreeUrlCacheSpaceW(wstr long long) @ stdcall FtpCommandA(long long long str ptr ptr) @ stdcall FtpCommandW(long long long wstr ptr ptr) @ stdcall FtpCreateDirectoryA(ptr str) diff --git a/reactos/dll/win32/wininet/wininet_Lt.rc b/reactos/dll/win32/wininet/wininet_Lt.rc new file mode 100644 index 00000000000..cd4bf482e35 --- /dev/null +++ b/reactos/dll/win32/wininet/wininet_Lt.rc @@ -0,0 +1,69 @@ +/* + * Copyright 2009 Aurimas Fišeras + * + * 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 + */ + +#include "resource.h" + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL + +IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Ä®veskite tinklo slaptaĹľodÄŻ" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Ä®veskite savo naudotojo vardÄ… ir slaptaĹľodÄŻ:", -1, 40, 6, 150, 15 + LTEXT "Ä®galiot. serv.", -1, 40, 26, 50, 10 + LTEXT "Sritis", -1, 40, 46, 50, 10 + LTEXT "Naudotojas", -1, 40, 66, 50, 10 + LTEXT "SlaptaĹľodis", -1, 40, 86, 50, 10 + LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 + LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 + EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD + CHECKBOX "Ä®&rašyti šį slaptaĹľodÄŻ (nesaugu)", IDC_SAVEPASSWORD, + 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Gerai", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Atsisakyti", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} + +IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Reikalingas tapatumo nustatymas" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Ä®veskite savo naudotojo vardÄ… ir slaptaĹľodÄŻ:", -1, 40, 6, 150, 15 + LTEXT "Serveris", -1, 40, 26, 50, 10 + LTEXT "Sritis", -1, 40, 46, 50, 10 + LTEXT "Naudotojas", -1, 40, 66, 50, 10 + LTEXT "SlaptaĹľodis", -1, 40, 86, 50, 10 + LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 + LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 + EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD + CHECKBOX "Ä®&rašyti šį slaptaĹľodÄŻ (nesaugu)", IDC_SAVEPASSWORD, + 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Gerai", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Atsisakyti", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP +} + +STRINGTABLE DISCARDABLE +{ + IDS_LANCONNECTION "Vietinio tinklo ryšys" +} From fda7cf929ae01a0e2f14ee725000563b99096f61 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 20 Nov 2009 16:50:05 +0000 Subject: [PATCH 082/140] [wininet] - Revert 44236 (sync wininet to Wine-1.1.33) and 43948 (sync wininet to Wine-1.1.32). Part 1/3 of rapps unregressing. See issue #4934 for more details. svn path=/trunk/; revision=44239 --- reactos/dll/win32/wininet/cookie.c | 295 +-- reactos/dll/win32/wininet/dialogs.c | 252 +-- reactos/dll/win32/wininet/ftp.c | 919 ++++---- reactos/dll/win32/wininet/http.c | 2413 ++++++++------------- reactos/dll/win32/wininet/internet.c | 508 ++--- reactos/dll/win32/wininet/internet.h | 168 +- reactos/dll/win32/wininet/netconnection.c | 285 ++- reactos/dll/win32/wininet/resource.h | 5 - reactos/dll/win32/wininet/urlcache.c | 192 +- reactos/dll/win32/wininet/utility.c | 88 +- reactos/dll/win32/wininet/wininet.rbuild | 1 - reactos/dll/win32/wininet/wininet.spec | 16 +- reactos/dll/win32/wininet/wininet_Bg.rc | 2 - reactos/dll/win32/wininet/wininet_Cs.rc | 2 - reactos/dll/win32/wininet/wininet_Da.rc | 2 - reactos/dll/win32/wininet/wininet_De.rc | 30 +- reactos/dll/win32/wininet/wininet_En.rc | 22 - reactos/dll/win32/wininet/wininet_Eo.rc | 2 - reactos/dll/win32/wininet/wininet_Es.rc | 2 - reactos/dll/win32/wininet/wininet_Fi.rc | 2 - reactos/dll/win32/wininet/wininet_Fr.rc | 61 +- reactos/dll/win32/wininet/wininet_Hu.rc | 2 - reactos/dll/win32/wininet/wininet_It.rc | 22 - reactos/dll/win32/wininet/wininet_Ja.rc | 3 +- reactos/dll/win32/wininet/wininet_Ko.rc | 2 - reactos/dll/win32/wininet/wininet_Lt.rc | 69 - reactos/dll/win32/wininet/wininet_Nl.rc | 22 - reactos/dll/win32/wininet/wininet_No.rc | 29 +- reactos/dll/win32/wininet/wininet_Pl.rc | 2 - reactos/dll/win32/wininet/wininet_Pt.rc | 34 +- reactos/dll/win32/wininet/wininet_Ro.rc | 26 +- reactos/dll/win32/wininet/wininet_Ru.rc | 44 +- reactos/dll/win32/wininet/wininet_Si.rc | 3 +- reactos/dll/win32/wininet/wininet_Sv.rc | 2 - reactos/dll/win32/wininet/wininet_Tr.rc | 2 - reactos/dll/win32/wininet/wininet_Uk.rc | 2 - reactos/dll/win32/wininet/wininet_Zh.rc | 4 +- 37 files changed, 1991 insertions(+), 3544 deletions(-) delete mode 100644 reactos/dll/win32/wininet/wininet_Lt.rc diff --git a/reactos/dll/win32/wininet/cookie.c b/reactos/dll/win32/wininet/cookie.c index 75cf049308b..12d841bc7b9 100644 --- a/reactos/dll/win32/wininet/cookie.c +++ b/reactos/dll/win32/wininet/cookie.c @@ -23,10 +23,6 @@ #include "config.h" #include "wine/port.h" -#if defined(__MINGW32__) || defined (_MSC_VER) -#include -#endif - #include #include #include @@ -52,6 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet); * Cookies are currently memory only. * Cookies are NOT THREAD SAFE * Cookies could use A LOT OF MEMORY. We need some kind of memory management here! + * Cookies should care about the expiry time */ typedef struct _cookie_domain cookie_domain; @@ -65,7 +62,7 @@ struct _cookie LPWSTR lpCookieName; LPWSTR lpCookieData; - FILETIME expiry; + time_t expiry; /* FIXME: not used */ }; struct _cookie_domain @@ -79,7 +76,7 @@ struct _cookie_domain static struct list domain_list = LIST_INIT(domain_list); -static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data, FILETIME expiry); +static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data); static cookie *COOKIE_findCookie(cookie_domain *domain, LPCWSTR lpszCookieName); static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain); static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path); @@ -87,16 +84,24 @@ static void COOKIE_deleteDomain(cookie_domain *deadDomain); /* adds a cookie to the domain */ -static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data, FILETIME expiry) +static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data) { cookie *newCookie = HeapAlloc(GetProcessHeap(), 0, sizeof(cookie)); list_init(&newCookie->entry); newCookie->lpCookieName = NULL; newCookie->lpCookieData = NULL; - newCookie->expiry = expiry; - newCookie->lpCookieName = heap_strdupW(name); - newCookie->lpCookieData = heap_strdupW(data); + + if (name) + { + newCookie->lpCookieName = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1)*sizeof(WCHAR)); + lstrcpyW(newCookie->lpCookieName, name); + } + if (data) + { + newCookie->lpCookieData = HeapAlloc(GetProcessHeap(), 0, (strlenW(data) + 1)*sizeof(WCHAR)); + lstrcpyW(newCookie->lpCookieData, data); + } TRACE("added cookie %p (data is %s)\n", newCookie, debugstr_w(data) ); @@ -151,8 +156,17 @@ static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path) list_init(&newDomain->cookie_list); newDomain->lpCookieDomain = NULL; newDomain->lpCookiePath = NULL; - newDomain->lpCookieDomain = heap_strdupW(domain); - newDomain->lpCookiePath = heap_strdupW(path); + + if (domain) + { + newDomain->lpCookieDomain = HeapAlloc(GetProcessHeap(), 0, (strlenW(domain) + 1)*sizeof(WCHAR)); + strcpyW(newDomain->lpCookieDomain, domain); + } + if (path) + { + newDomain->lpCookiePath = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1)*sizeof(WCHAR)); + lstrcpyW(newDomain->lpCookiePath, path); + } list_add_tail(&domain_list, &newDomain->entry); @@ -177,28 +191,7 @@ static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostName UrlComponents.dwHostNameLength = hostNameLen; UrlComponents.dwUrlPathLength = pathLen; - if (!InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents)) return FALSE; - - /* discard the webpage off the end of the path */ - if (UrlComponents.dwUrlPathLength) - { - if (path[UrlComponents.dwUrlPathLength - 1] != '/') - { - WCHAR *ptr; - if ((ptr = strrchrW(path, '/'))) *(++ptr) = 0; - else - { - path[0] = '/'; - path[1] = 0; - } - } - } - else if (pathLen >= 2) - { - path[0] = '/'; - path[1] = 0; - } - return TRUE; + return InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents); } /* match a domain. domain must match if the domain is not NULL. path must match if the path is not NULL */ @@ -222,22 +215,11 @@ static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath, } if (lpszCookiePath) { - INT len; TRACE("comparing paths: %s with %s\n", debugstr_w(lpszCookiePath), debugstr_w(searchDomain->lpCookiePath)); - /* paths match at the beginning. so a path of /foo would match - * /foobar and /foo/bar - */ if (!searchDomain->lpCookiePath) return FALSE; - if (allow_partial) - { - len = lstrlenW(searchDomain->lpCookiePath); - if (strncmpiW(searchDomain->lpCookiePath, lpszCookiePath, len)!=0) - return FALSE; - } - else if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath)) + if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath)) return FALSE; - } return TRUE; } @@ -280,7 +262,6 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, struct list * cursor; unsigned int cnt = 0, domain_count = 0, cookie_count = 0; WCHAR hostName[2048], path[2048]; - FILETIME tm; TRACE("(%s, %s, %p, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName), lpCookieData, lpdwSize); @@ -295,12 +276,10 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0])); if (!ret || !hostName[0]) return FALSE; - GetSystemTimeAsFileTime(&tm); - LIST_FOR_EACH(cursor, &domain_list) { cookie_domain *cookiesDomain = LIST_ENTRY(cursor, cookie_domain, entry); - if (COOKIE_matchDomain(hostName, path, cookiesDomain, TRUE)) + if (COOKIE_matchDomain(hostName, NULL /* FIXME: path */, cookiesDomain, TRUE)) { struct list * cursor; domain_count++; @@ -309,14 +288,6 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, LIST_FOR_EACH(cursor, &cookiesDomain->cookie_list) { cookie *thisCookie = LIST_ENTRY(cursor, cookie, entry); - /* check for expiry */ - if ((thisCookie->expiry.dwLowDateTime != 0 || thisCookie->expiry.dwHighDateTime != 0) && CompareFileTime(&tm,&thisCookie->expiry) > 0) - { - TRACE("Found expired cookie. deleting\n"); - COOKIE_deleteCookie(thisCookie, FALSE); - continue; - } - if (lpCookieData == NULL) /* return the size of the buffer required to lpdwSize */ { unsigned int len; @@ -385,16 +356,27 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName, LPSTR lpCookieData, LPDWORD lpdwSize) { DWORD len; - LPWSTR szCookieData = NULL, url, name; + LPWSTR szCookieData = NULL, szUrl = NULL, szCookieName = NULL; BOOL r; TRACE("(%s,%s,%p)\n", debugstr_a(lpszUrl), debugstr_a(lpszCookieName), lpCookieData); - url = heap_strdupAtoW(lpszUrl); - name = heap_strdupAtoW(lpszCookieName); + if( lpszUrl ) + { + len = MultiByteToWideChar( CP_ACP, 0, lpszUrl, -1, NULL, 0 ); + szUrl = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, lpszUrl, -1, szUrl, len ); + } - r = InternetGetCookieW( url, name, NULL, &len ); + if( lpszCookieName ) + { + len = MultiByteToWideChar( CP_ACP, 0, lpszCookieName, -1, NULL, 0 ); + szCookieName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, lpszCookieName, -1, szCookieName, len ); + } + + r = InternetGetCookieW( szUrl, szCookieName, NULL, &len ); if( r ) { szCookieData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); @@ -404,7 +386,7 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName, } else { - r = InternetGetCookieW( url, name, szCookieData, &len ); + r = InternetGetCookieW( szUrl, szCookieName, szCookieData, &len ); *lpdwSize = WideCharToMultiByte( CP_ACP, 0, szCookieData, len, lpCookieData, *lpdwSize, NULL, NULL ); @@ -412,8 +394,8 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName, } HeapFree( GetProcessHeap(), 0, szCookieData ); - HeapFree( GetProcessHeap(), 0, name ); - HeapFree( GetProcessHeap(), 0, url ); + HeapFree( GetProcessHeap(), 0, szCookieName ); + HeapFree( GetProcessHeap(), 0, szUrl ); return r; } @@ -423,129 +405,27 @@ static BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWST cookie_domain *thisCookieDomain = NULL; cookie *thisCookie; struct list *cursor; - LPWSTR data, value; - WCHAR *ptr; - FILETIME expiry; - BOOL expired = FALSE; - - value = data = heap_strdupW(cookie_data); - if (!data) - { - ERR("could not allocate %zu bytes for the cookie data buffer\n", (strlenW(cookie_data) + 1) * sizeof(WCHAR)); - return FALSE; - } - - memset(&expiry,0,sizeof(expiry)); - - /* lots of information can be parsed out of the cookie value */ - - ptr = data; - for (;;) - { - static const WCHAR szDomain[] = {'d','o','m','a','i','n','=',0}; - static const WCHAR szPath[] = {'p','a','t','h','=',0}; - static const WCHAR szExpires[] = {'e','x','p','i','r','e','s','=',0}; - static const WCHAR szSecure[] = {'s','e','c','u','r','e',0}; - static const WCHAR szHttpOnly[] = {'h','t','t','p','o','n','l','y',0}; - - if (!(ptr = strchrW(ptr,';'))) break; - *ptr++ = 0; - - if (value != data) - HeapFree(GetProcessHeap(), 0, value); - value = HeapAlloc(GetProcessHeap(), 0, (ptr - data) * sizeof(WCHAR)); - if (value == NULL) - { - HeapFree(GetProcessHeap(), 0, data); - ERR("could not allocate %zu bytes for the cookie value buffer\n", (ptr - data) * sizeof(WCHAR)); - return FALSE; - } - strcpyW(value, data); - - while (*ptr == ' ') ptr++; /* whitespace */ - - if (strncmpiW(ptr, szDomain, 7) == 0) - { - ptr+=strlenW(szDomain); - domain = ptr; - TRACE("Parsing new domain %s\n",debugstr_w(domain)); - } - else if (strncmpiW(ptr, szPath, 5) == 0) - { - ptr+=strlenW(szPath); - path = ptr; - TRACE("Parsing new path %s\n",debugstr_w(path)); - } - else if (strncmpiW(ptr, szExpires, 8) == 0) - { - FILETIME ft; - SYSTEMTIME st; - FIXME("persistent cookies not handled (%s)\n",debugstr_w(ptr)); - ptr+=strlenW(szExpires); - if (InternetTimeToSystemTimeW(ptr, &st, 0)) - { - SystemTimeToFileTime(&st, &expiry); - GetSystemTimeAsFileTime(&ft); - - if (CompareFileTime(&ft,&expiry) > 0) - { - TRACE("Cookie already expired.\n"); - expired = TRUE; - } - } - } - else if (strncmpiW(ptr, szSecure, 6) == 0) - { - FIXME("secure not handled (%s)\n",debugstr_w(ptr)); - ptr += strlenW(szSecure); - } - else if (strncmpiW(ptr, szHttpOnly, 8) == 0) - { - FIXME("httponly not handled (%s)\n",debugstr_w(ptr)); - ptr += strlenW(szHttpOnly); - } - else if (*ptr) - { - FIXME("Unknown additional option %s\n",debugstr_w(ptr)); - break; - } - } LIST_FOR_EACH(cursor, &domain_list) { thisCookieDomain = LIST_ENTRY(cursor, cookie_domain, entry); - if (COOKIE_matchDomain(domain, path, thisCookieDomain, FALSE)) + if (COOKIE_matchDomain(domain, NULL /* FIXME: path */, thisCookieDomain, FALSE)) break; thisCookieDomain = NULL; } if (!thisCookieDomain) - { - if (!expired) - thisCookieDomain = COOKIE_addDomain(domain, path); - else - { - HeapFree(GetProcessHeap(),0,data); - if (value != data) HeapFree(GetProcessHeap(), 0, value); - return TRUE; - } - } + thisCookieDomain = COOKIE_addDomain(domain, path); if ((thisCookie = COOKIE_findCookie(thisCookieDomain, cookie_name))) COOKIE_deleteCookie(thisCookie, FALSE); - TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_w(cookie_name), - debugstr_w(value), debugstr_w(thisCookieDomain->lpCookieDomain),debugstr_w(thisCookieDomain->lpCookiePath)); + TRACE("setting cookie %s=%s for domain %s\n", debugstr_w(cookie_name), + debugstr_w(cookie_data), debugstr_w(thisCookieDomain->lpCookieDomain)); - if (!expired && !COOKIE_addCookie(thisCookieDomain, cookie_name, value, expiry)) - { - HeapFree(GetProcessHeap(),0,data); - if (value != data) HeapFree(GetProcessHeap(), 0, value); + if (!COOKIE_addCookie(thisCookieDomain, cookie_name, cookie_data)) return FALSE; - } - HeapFree(GetProcessHeap(),0,data); - if (value != data) HeapFree(GetProcessHeap(), 0, value); return TRUE; } @@ -574,26 +454,28 @@ BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, return FALSE; } - hostName[0] = 0; + hostName[0] = path[0] = 0; ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0])); if (!ret || !hostName[0]) return FALSE; if (!lpszCookieName) { + unsigned int len; WCHAR *cookie, *data; - cookie = heap_strdupW(lpCookieData); - if (!cookie) + len = strlenW(lpCookieData); + if (!(cookie = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)))) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } + strcpyW(cookie, lpCookieData); /* some apps (or is it us??) try to add a cookie with no cookie name, but * the cookie data in the form of name[=data]. */ - if (!(data = strchrW(cookie, '='))) data = cookie + strlenW(cookie); - else *data++ = 0; + if (!(data = strchrW(cookie, '='))) data = cookie + len; + else data++; ret = set_cookie(hostName, path, cookie, data); @@ -617,21 +499,39 @@ BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName, BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName, LPCSTR lpCookieData) { - LPWSTR data, url, name; + DWORD len; + LPWSTR szCookieData = NULL, szUrl = NULL, szCookieName = NULL; BOOL r; TRACE("(%s,%s,%s)\n", debugstr_a(lpszUrl), debugstr_a(lpszCookieName), debugstr_a(lpCookieData)); - url = heap_strdupAtoW(lpszUrl); - name = heap_strdupAtoW(lpszCookieName); - data = heap_strdupAtoW(lpCookieData); + if( lpszUrl ) + { + len = MultiByteToWideChar( CP_ACP, 0, lpszUrl, -1, NULL, 0 ); + szUrl = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, lpszUrl, -1, szUrl, len ); + } - r = InternetSetCookieW( url, name, data ); + if( lpszCookieName ) + { + len = MultiByteToWideChar( CP_ACP, 0, lpszCookieName, -1, NULL, 0 ); + szCookieName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, lpszCookieName, -1, szCookieName, len ); + } - HeapFree( GetProcessHeap(), 0, data ); - HeapFree( GetProcessHeap(), 0, name ); - HeapFree( GetProcessHeap(), 0, url ); + if( lpCookieData ) + { + len = MultiByteToWideChar( CP_ACP, 0, lpCookieData, -1, NULL, 0 ); + szCookieData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, lpCookieData, -1, szCookieData, len ); + } + + r = InternetSetCookieW( szUrl, szCookieName, szCookieData ); + + HeapFree( GetProcessHeap(), 0, szCookieData ); + HeapFree( GetProcessHeap(), 0, szCookieName ); + HeapFree( GetProcessHeap(), 0, szUrl ); return r; } @@ -792,28 +692,3 @@ BOOL WINAPI InternetSetPerSiteCookieDecisionW( LPCWSTR pchHostName, DWORD dwDeci FIXME("(%s, 0x%08x) stub\n", debugstr_w(pchHostName), dwDecision); return FALSE; } - -/*********************************************************************** - * IsDomainLegalCookieDomainW (WININET.@) - */ -BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 ) -{ - const WCHAR *p; - - FIXME("(%s, %s)\n", debugstr_w(s1), debugstr_w(s2)); - - if (!s1 || !s2) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (s1[0] == '.' || !s1[0] || s2[0] == '.' || !s2[0]) - { - SetLastError(ERROR_INVALID_NAME); - return FALSE; - } - if (!(p = strchrW(s2, '.'))) return FALSE; - if (strchrW(p + 1, '.') && !strcmpW(p + 1, s1)) return TRUE; - else if (!strcmpW(s1, s2)) return TRUE; - return FALSE; -} diff --git a/reactos/dll/win32/wininet/dialogs.c b/reactos/dll/win32/wininet/dialogs.c index 2c4a5278569..dd5aa315a63 100644 --- a/reactos/dll/win32/wininet/dialogs.c +++ b/reactos/dll/win32/wininet/dialogs.c @@ -21,10 +21,6 @@ #include "config.h" #include "wine/port.h" -#if defined(__MINGW32__) || defined (_MSC_VER) -#include -#endif - #include #include "windef.h" @@ -62,23 +58,22 @@ struct WININET_ErrorDlgParams */ static BOOL WININET_GetProxyServer( HINTERNET hRequest, LPWSTR szBuf, DWORD sz ) { - http_request_t *lpwhr; - http_session_t *lpwhs = NULL; - appinfo_t *hIC = NULL; - BOOL ret = FALSE; + LPWININETHTTPREQW lpwhr; + LPWININETHTTPSESSIONW lpwhs = NULL; + LPWININETAPPINFOW hIC = NULL; LPWSTR p; - lpwhr = (http_request_t*) WININET_GetObject( hRequest ); + lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest ); if (NULL == lpwhr) - return FALSE; + return FALSE; lpwhs = lpwhr->lpHttpSession; if (NULL == lpwhs) - goto done; + return FALSE; hIC = lpwhs->lpAppInfo; if (NULL == hIC) - goto done; + return FALSE; lstrcpynW(szBuf, hIC->lpszProxy, sz); @@ -87,39 +82,7 @@ static BOOL WININET_GetProxyServer( HINTERNET hRequest, LPWSTR szBuf, DWORD sz ) if (p) *p = 0; - ret = TRUE; - -done: - WININET_Release( &lpwhr->hdr ); - return ret; -} - -/*********************************************************************** - * WININET_GetServer - * - * Determine the name of the web server - */ -static BOOL WININET_GetServer( HINTERNET hRequest, LPWSTR szBuf, DWORD sz ) -{ - http_request_t *lpwhr; - http_session_t *lpwhs = NULL; - BOOL ret = FALSE; - - lpwhr = (http_request_t*) WININET_GetObject( hRequest ); - if (NULL == lpwhr) - return FALSE; - - lpwhs = lpwhr->lpHttpSession; - if (NULL == lpwhs) - goto done; - - lstrcpynW(szBuf, lpwhs->lpszHostName, sz); - - ret = TRUE; - -done: - WININET_Release( &lpwhr->hdr ); - return ret; + return TRUE; } /*********************************************************************** @@ -127,20 +90,16 @@ done: * * Determine the name of the (basic) Authentication realm */ -static BOOL WININET_GetAuthRealm( HINTERNET hRequest, LPWSTR szBuf, DWORD sz, BOOL proxy ) +static BOOL WININET_GetAuthRealm( HINTERNET hRequest, LPWSTR szBuf, DWORD sz ) { LPWSTR p, q; - DWORD index, query; + DWORD index; static const WCHAR szRealm[] = { 'r','e','a','l','m','=',0 }; - if (proxy) - query = HTTP_QUERY_PROXY_AUTHENTICATE; - else - query = HTTP_QUERY_WWW_AUTHENTICATE; - - /* extract the Realm from the response and show it */ + /* extract the Realm from the proxy response and show it */ index = 0; - if( !HttpQueryInfoW( hRequest, query, szBuf, &sz, &index) ) + if( !HttpQueryInfoW( hRequest, HTTP_QUERY_PROXY_AUTHENTICATE, + szBuf, &sz, &index) ) return FALSE; /* @@ -150,10 +109,11 @@ static BOOL WININET_GetAuthRealm( HINTERNET hRequest, LPWSTR szBuf, DWORD sz, BO p = strchrW( szBuf, ' ' ); if( !p || strncmpW( p+1, szRealm, strlenW(szRealm) ) ) { - ERR("response wrong? (%s)\n", debugstr_w(szBuf)); + ERR("proxy response wrong? (%s)\n", debugstr_w(szBuf)); return FALSE; } + /* remove quotes */ p += 7; if( *p == '"' ) @@ -234,62 +194,44 @@ static BOOL WININET_GetSetPassword( HWND hdlg, LPCWSTR szServer, } /*********************************************************************** - * WININET_SetAuthorization + * WININET_SetProxyAuthorization */ -static BOOL WININET_SetAuthorization( HINTERNET hRequest, LPWSTR username, - LPWSTR password, BOOL proxy ) +static BOOL WININET_SetProxyAuthorization( HINTERNET hRequest, + LPWSTR username, LPWSTR password ) { - http_request_t *lpwhr; - http_session_t *lpwhs; - BOOL ret = FALSE; - LPWSTR p, q; + LPWININETHTTPREQW lpwhr; + LPWININETHTTPSESSIONW lpwhs; + LPWININETAPPINFOW hIC; + LPWSTR p; - lpwhr = (http_request_t*) WININET_GetObject( hRequest ); + lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest ); if( !lpwhr ) - return FALSE; - + return FALSE; + lpwhs = lpwhr->lpHttpSession; if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); - goto done; + return FALSE; } - p = heap_strdupW(username); + hIC = lpwhs->lpAppInfo; + + p = HeapAlloc( GetProcessHeap(), 0, (strlenW( username ) + 1)*sizeof(WCHAR) ); if( !p ) - goto done; + return FALSE; + + lstrcpyW( p, username ); + hIC->lpszProxyUsername = p; - q = heap_strdupW(password); - if( !q ) - { - HeapFree(GetProcessHeap(), 0, username); - goto done; - } + p = HeapAlloc( GetProcessHeap(), 0, (strlenW( password ) + 1)*sizeof(WCHAR) ); + if( !p ) + return FALSE; + + lstrcpyW( p, password ); + hIC->lpszProxyPassword = p; - if (proxy) - { - appinfo_t *hIC = lpwhs->lpAppInfo; - - HeapFree(GetProcessHeap(), 0, hIC->lpszProxyUsername); - hIC->lpszProxyUsername = p; - - HeapFree(GetProcessHeap(), 0, hIC->lpszProxyPassword); - hIC->lpszProxyPassword = q; - } - else - { - HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName); - lpwhs->lpszUserName = p; - - HeapFree(GetProcessHeap(), 0, lpwhs->lpszPassword); - lpwhs->lpszPassword = q; - } - - ret = TRUE; - -done: - WININET_Release( &lpwhr->hdr ); - return ret; + return TRUE; } /*********************************************************************** @@ -312,7 +254,7 @@ static INT_PTR WINAPI WININET_ProxyPasswordDialog( /* extract the Realm from the proxy response and show it */ if( WININET_GetAuthRealm( params->hRequest, - szRealm, sizeof szRealm/sizeof(WCHAR), TRUE ) ) + szRealm, sizeof szRealm/sizeof(WCHAR)) ) { hitem = GetDlgItem( hdlg, IDC_REALM ); SetWindowTextW( hitem, szRealm ); @@ -355,97 +297,13 @@ static INT_PTR WINAPI WININET_ProxyPasswordDialog( if( hitem && SendMessageW( hitem, BM_GETSTATE, 0, 0 ) && WININET_GetAuthRealm( params->hRequest, - szRealm, sizeof szRealm/sizeof(WCHAR), TRUE ) && + szRealm, sizeof szRealm/sizeof(WCHAR)) && WININET_GetProxyServer( params->hRequest, szServer, sizeof szServer/sizeof(WCHAR)) ) { WININET_GetSetPassword( hdlg, szServer, szRealm, TRUE ); } - WININET_SetAuthorization( params->hRequest, username, password, TRUE ); - - EndDialog( hdlg, ERROR_INTERNET_FORCE_RETRY ); - return TRUE; - } - if( wParam == IDCANCEL ) - { - EndDialog( hdlg, 0 ); - return TRUE; - } - break; - } - return FALSE; -} - -/*********************************************************************** - * WININET_PasswordDialog - */ -static INT_PTR WINAPI WININET_PasswordDialog( - HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) -{ - HWND hitem; - struct WININET_ErrorDlgParams *params; - WCHAR szRealm[0x80], szServer[0x80]; - - if( uMsg == WM_INITDIALOG ) - { - TRACE("WM_INITDIALOG (%08lx)\n", lParam); - - /* save the parameter list */ - params = (struct WININET_ErrorDlgParams*) lParam; - SetWindowLongPtrW( hdlg, GWLP_USERDATA, lParam ); - - /* extract the Realm from the response and show it */ - if( WININET_GetAuthRealm( params->hRequest, - szRealm, sizeof szRealm/sizeof(WCHAR), FALSE ) ) - { - hitem = GetDlgItem( hdlg, IDC_REALM ); - SetWindowTextW( hitem, szRealm ); - } - - /* extract the name of the server */ - if( WININET_GetServer( params->hRequest, - szServer, sizeof szServer/sizeof(WCHAR)) ) - { - hitem = GetDlgItem( hdlg, IDC_SERVER ); - SetWindowTextW( hitem, szServer ); - } - - WININET_GetSetPassword( hdlg, szServer, szRealm, FALSE ); - - return TRUE; - } - - params = (struct WININET_ErrorDlgParams*) - GetWindowLongPtrW( hdlg, GWLP_USERDATA ); - - switch( uMsg ) - { - case WM_COMMAND: - if( wParam == IDOK ) - { - WCHAR username[0x20], password[0x20]; - - username[0] = 0; - hitem = GetDlgItem( hdlg, IDC_USERNAME ); - if( hitem ) - GetWindowTextW( hitem, username, sizeof username/sizeof(WCHAR) ); - - password[0] = 0; - hitem = GetDlgItem( hdlg, IDC_PASSWORD ); - if( hitem ) - GetWindowTextW( hitem, password, sizeof password/sizeof(WCHAR) ); - - hitem = GetDlgItem( hdlg, IDC_SAVEPASSWORD ); - if( hitem && - SendMessageW( hitem, BM_GETSTATE, 0, 0 ) && - WININET_GetAuthRealm( params->hRequest, - szRealm, sizeof szRealm/sizeof(WCHAR), FALSE ) && - WININET_GetServer( params->hRequest, - szServer, sizeof szServer/sizeof(WCHAR)) ) - { - WININET_GetSetPassword( hdlg, szServer, szRealm, TRUE ); - } - WININET_SetAuthorization( params->hRequest, username, password, FALSE ); + WININET_SetProxyAuthorization( params->hRequest, username, password ); EndDialog( hdlg, ERROR_INTERNET_FORCE_RETRY ); return TRUE; @@ -504,23 +362,17 @@ DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest, switch( dwError ) { case ERROR_SUCCESS: - case ERROR_INTERNET_INCORRECT_PASSWORD: - if( !dwError && !(dwFlags & FLAGS_ERROR_UI_FILTER_FOR_ERRORS ) ) + if( !(dwFlags & FLAGS_ERROR_UI_FILTER_FOR_ERRORS ) ) return 0; - dwStatus = WININET_GetConnectionStatus( hRequest ); - switch (dwStatus) - { - case HTTP_STATUS_PROXY_AUTH_REQ: - return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ), - hWnd, WININET_ProxyPasswordDialog, (LPARAM) ¶ms ); - case HTTP_STATUS_DENIED: - return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_AUTHDLG ), - hWnd, WININET_PasswordDialog, (LPARAM) ¶ms ); - default: - WARN("unhandled status %u\n", dwStatus); - return 0; - } + if( HTTP_STATUS_PROXY_AUTH_REQ != dwStatus ) + return ERROR_SUCCESS; + return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ), + hWnd, WININET_ProxyPasswordDialog, (LPARAM) ¶ms ); + + case ERROR_INTERNET_INCORRECT_PASSWORD: + return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ), + hWnd, WININET_ProxyPasswordDialog, (LPARAM) ¶ms ); case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR: case ERROR_INTERNET_INVALID_CA: diff --git a/reactos/dll/win32/wininet/ftp.c b/reactos/dll/win32/wininet/ftp.c index f0c3cbd02c4..770fef2886a 100644 --- a/reactos/dll/win32/wininet/ftp.c +++ b/reactos/dll/win32/wininet/ftp.c @@ -30,10 +30,6 @@ #include "config.h" #include "wine/port.h" -#if defined(__MINGW32__) || defined (_MSC_VER) -#include -#endif - #include #include #include @@ -46,9 +42,6 @@ #ifdef HAVE_UNISTD_H # include #endif -#ifdef HAVE_SYS_IOCTL_H -# include -#endif #include #include @@ -68,43 +61,43 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet); -typedef struct _ftp_session_t ftp_session_t; +typedef struct _WININETFTPSESSIONW WININETFTPSESSIONW; typedef struct { - object_header_t hdr; - ftp_session_t *lpFtpSession; + WININETHANDLEHEADER hdr; + WININETFTPSESSIONW *lpFtpSession; BOOL session_deleted; int nDataSocket; -} ftp_file_t; +} WININETFTPFILE, *LPWININETFTPFILE; -struct _ftp_session_t +typedef struct _WININETFTPSESSIONW { - object_header_t hdr; - appinfo_t *lpAppInfo; + WININETHANDLEHEADER hdr; + WININETAPPINFOW *lpAppInfo; int sndSocket; int lstnSocket; int pasvSocket; /* data socket connected by us in case of passive FTP */ - ftp_file_t *download_in_progress; + LPWININETFTPFILE download_in_progress; struct sockaddr_in socketAddress; struct sockaddr_in lstnSocketAddress; LPWSTR lpszPassword; LPWSTR lpszUserName; -}; +} *LPWININETFTPSESSIONW; typedef struct { BOOL bIsDirectory; LPWSTR lpszName; DWORD nSize; - SYSTEMTIME tmLastModified; + struct tm tmLastModified; unsigned short permissions; } FILEPROPERTIESW, *LPFILEPROPERTIESW; typedef struct { - object_header_t hdr; - ftp_session_t *lpFtpSession; + WININETHANDLEHEADER hdr; + WININETFTPSESSIONW *lpFtpSession; DWORD index; DWORD size; LPFILEPROPERTIESW lpafp; @@ -172,41 +165,43 @@ static const CHAR szMonths[] = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"; static const WCHAR szNoAccount[] = {'n','o','a','c','c','o','u','n','t','\0'}; static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam, - INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext); -static BOOL FTP_SendStore(ftp_session_t*, LPCWSTR lpszRemoteFile, DWORD dwType); -static BOOL FTP_GetDataSocket(ftp_session_t*, LPINT nDataSocket); -static BOOL FTP_SendData(ftp_session_t*, INT nDataSocket, HANDLE hFile); -static INT FTP_ReceiveResponse(ftp_session_t*, DWORD_PTR dwContext); -static BOOL FTP_SendRetrieve(ftp_session_t*, LPCWSTR lpszRemoteFile, DWORD dwType); -static BOOL FTP_RetrieveFileData(ftp_session_t*, INT nDataSocket, HANDLE hFile); -static BOOL FTP_InitListenSocket(ftp_session_t*); -static BOOL FTP_ConnectToHost(ftp_session_t*); -static BOOL FTP_SendPassword(ftp_session_t*); -static BOOL FTP_SendAccount(ftp_session_t*); -static BOOL FTP_SendType(ftp_session_t*, DWORD dwType); -static BOOL FTP_SendPort(ftp_session_t*); -static BOOL FTP_DoPassive(ftp_session_t*); -static BOOL FTP_SendPortOrPasv(ftp_session_t*); + INTERNET_STATUS_CALLBACK lpfnStatusCB, LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext); +static BOOL FTP_SendStore(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType); +static BOOL FTP_GetDataSocket(LPWININETFTPSESSIONW lpwfs, LPINT nDataSocket); +static BOOL FTP_SendData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile); +static INT FTP_ReceiveResponse(LPWININETFTPSESSIONW lpwfs, DWORD_PTR dwContext); +static BOOL FTP_SendRetrieve(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType); +static BOOL FTP_RetrieveFileData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile); +static BOOL FTP_InitListenSocket(LPWININETFTPSESSIONW lpwfs); +static BOOL FTP_ConnectToHost(LPWININETFTPSESSIONW lpwfs); +static BOOL FTP_SendPassword(LPWININETFTPSESSIONW lpwfs); +static BOOL FTP_SendAccount(LPWININETFTPSESSIONW lpwfs); +static BOOL FTP_SendType(LPWININETFTPSESSIONW lpwfs, DWORD dwType); +static BOOL FTP_SendPort(LPWININETFTPSESSIONW lpwfs); +static BOOL FTP_DoPassive(LPWININETFTPSESSIONW lpwfs); +static BOOL FTP_SendPortOrPasv(LPWININETFTPSESSIONW lpwfs); static BOOL FTP_ParsePermission(LPCSTR lpszPermission, LPFILEPROPERTIESW lpfp); static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW fileprop); -static BOOL FTP_ParseDirectory(ftp_session_t*, INT nSocket, LPCWSTR lpszSearchFile, +static BOOL FTP_ParseDirectory(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW *lpafp, LPDWORD dwfp); -static HINTERNET FTP_ReceiveFileList(ftp_session_t*, INT nSocket, LPCWSTR lpszSearchFile, +static HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext); static DWORD FTP_SetResponseError(DWORD dwResponse); static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData); -static BOOL FTP_FtpPutFileW(ftp_session_t*, LPCWSTR lpszLocalFile, +static BOOL FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile, LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext); -static BOOL FTP_FtpSetCurrentDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory); -static BOOL FTP_FtpCreateDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory); -static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t*, +static BOOL FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory); +static BOOL FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory); +static HINTERNET FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext); -static BOOL FTP_FtpGetCurrentDirectoryW(ftp_session_t*, LPWSTR lpszCurrentDirectory, +static BOOL FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory, LPDWORD lpdwCurrentDirectory); -static BOOL FTP_FtpRenameFileW(ftp_session_t*, LPCWSTR lpszSrc, LPCWSTR lpszDest); -static BOOL FTP_FtpRemoveDirectoryW(ftp_session_t*, LPCWSTR lpszDirectory); -static BOOL FTP_FtpDeleteFileW(ftp_session_t*, LPCWSTR lpszFileName); -static BOOL FTP_FtpGetFileW(ftp_session_t*, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile, +static BOOL FTP_FtpRenameFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest); +static BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory); +static BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName); +static HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName, + DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext); +static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile, BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags, DWORD_PTR dwContext); @@ -228,8 +223,8 @@ BOOL WINAPI FtpPutFileA(HINTERNET hConnect, LPCSTR lpszLocalFile, LPWSTR lpwzNewRemoteFile; BOOL ret; - lpwzLocalFile = heap_strdupAtoW(lpszLocalFile); - lpwzNewRemoteFile = heap_strdupAtoW(lpszNewRemoteFile); + lpwzLocalFile = lpszLocalFile?WININET_strdup_AtoW(lpszLocalFile):NULL; + lpwzNewRemoteFile = lpszNewRemoteFile?WININET_strdup_AtoW(lpszNewRemoteFile):NULL; ret = FtpPutFileW(hConnect, lpwzLocalFile, lpwzNewRemoteFile, dwFlags, dwContext); HeapFree(GetProcessHeap(), 0, lpwzLocalFile); @@ -240,7 +235,7 @@ BOOL WINAPI FtpPutFileA(HINTERNET hConnect, LPCSTR lpszLocalFile, static void AsyncFtpPutFileProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPPUTFILEW const *req = &workRequest->u.FtpPutFileW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -264,8 +259,8 @@ static void AsyncFtpPutFileProc(WORKREQUEST *workRequest) BOOL WINAPI FtpPutFileW(HINTERNET hConnect, LPCWSTR lpszLocalFile, LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; BOOL r = FALSE; if (!lpszLocalFile || !lpszNewRemoteFile) @@ -274,7 +269,7 @@ BOOL WINAPI FtpPutFileW(HINTERNET hConnect, LPCWSTR lpszLocalFile, return FALSE; } - lpwfs = (ftp_session_t*) WININET_GetObject( hConnect ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect ); if (!lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -307,8 +302,8 @@ BOOL WINAPI FtpPutFileW(HINTERNET hConnect, LPCWSTR lpszLocalFile, workRequest.asyncproc = AsyncFtpPutFileProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); - req->lpszLocalFile = heap_strdupW(lpszLocalFile); - req->lpszNewRemoteFile = heap_strdupW(lpszNewRemoteFile); + req->lpszLocalFile = WININET_strdupW(lpszLocalFile); + req->lpszNewRemoteFile = WININET_strdupW(lpszNewRemoteFile); req->dwFlags = dwFlags; req->dwContext = dwContext; @@ -336,12 +331,12 @@ lend: * FALSE on failure * */ -static BOOL FTP_FtpPutFileW(ftp_session_t *lpwfs, LPCWSTR lpszLocalFile, +static BOOL FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile, LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD_PTR dwContext) { HANDLE hFile; BOOL bSuccess = FALSE; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; INT nResCode; TRACE(" lpszLocalFile(%s) lpszNewRemoteFile(%s)\n", debugstr_w(lpszLocalFile), debugstr_w(lpszNewRemoteFile)); @@ -380,10 +375,7 @@ static BOOL FTP_FtpPutFileW(ftp_session_t *lpwfs, LPCWSTR lpszLocalFile, } if (lpwfs->lstnSocket != -1) - { closesocket(lpwfs->lstnSocket); - lpwfs->lstnSocket = -1; - } if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) { @@ -416,7 +408,7 @@ BOOL WINAPI FtpSetCurrentDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory) LPWSTR lpwzDirectory; BOOL ret; - lpwzDirectory = heap_strdupAtoW(lpszDirectory); + lpwzDirectory = lpszDirectory?WININET_strdup_AtoW(lpszDirectory):NULL; ret = FtpSetCurrentDirectoryW(hConnect, lpwzDirectory); HeapFree(GetProcessHeap(), 0, lpwzDirectory); return ret; @@ -426,7 +418,7 @@ BOOL WINAPI FtpSetCurrentDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory) static void AsyncFtpSetCurrentDirectoryProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPSETCURRENTDIRECTORYW const *req = &workRequest->u.FtpSetCurrentDirectoryW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -446,8 +438,8 @@ static void AsyncFtpSetCurrentDirectoryProc(WORKREQUEST *workRequest) */ BOOL WINAPI FtpSetCurrentDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory) { - ftp_session_t *lpwfs = NULL; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs = NULL; + LPWININETAPPINFOW hIC = NULL; BOOL r = FALSE; if (!lpszDirectory) @@ -456,7 +448,7 @@ BOOL WINAPI FtpSetCurrentDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory) goto lend; } - lpwfs = (ftp_session_t*) WININET_GetObject( hConnect ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect ); if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); @@ -480,7 +472,7 @@ BOOL WINAPI FtpSetCurrentDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory) workRequest.asyncproc = AsyncFtpSetCurrentDirectoryProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); req = &workRequest.u.FtpSetCurrentDirectoryW; - req->lpszDirectory = heap_strdupW(lpszDirectory); + req->lpszDirectory = WININET_strdupW(lpszDirectory); r = INTERNET_AsyncCall(&workRequest); } @@ -507,10 +499,10 @@ lend: * FALSE on failure * */ -static BOOL FTP_FtpSetCurrentDirectoryW(ftp_session_t *lpwfs, LPCWSTR lpszDirectory) +static BOOL FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory) { INT nResCode; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; DWORD bSuccess = FALSE; TRACE("lpszDirectory(%s)\n", debugstr_w(lpszDirectory)); @@ -562,7 +554,7 @@ BOOL WINAPI FtpCreateDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory) LPWSTR lpwzDirectory; BOOL ret; - lpwzDirectory = heap_strdupAtoW(lpszDirectory); + lpwzDirectory = lpszDirectory?WININET_strdup_AtoW(lpszDirectory):NULL; ret = FtpCreateDirectoryW(hConnect, lpwzDirectory); HeapFree(GetProcessHeap(), 0, lpwzDirectory); return ret; @@ -572,7 +564,7 @@ BOOL WINAPI FtpCreateDirectoryA(HINTERNET hConnect, LPCSTR lpszDirectory) static void AsyncFtpCreateDirectoryProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPCREATEDIRECTORYW const *req = &workRequest->u.FtpCreateDirectoryW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE(" %p\n", lpwfs); @@ -592,11 +584,11 @@ static void AsyncFtpCreateDirectoryProc(WORKREQUEST *workRequest) */ BOOL WINAPI FtpCreateDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; BOOL r = FALSE; - lpwfs = (ftp_session_t*) WININET_GetObject( hConnect ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect ); if (!lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -630,7 +622,7 @@ BOOL WINAPI FtpCreateDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory) workRequest.asyncproc = AsyncFtpCreateDirectoryProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); req = &workRequest.u.FtpCreateDirectoryW; - req->lpszDirectory = heap_strdupW(lpszDirectory); + req->lpszDirectory = WININET_strdupW(lpszDirectory); r = INTERNET_AsyncCall(&workRequest); } @@ -655,11 +647,11 @@ lend: * FALSE on failure * */ -static BOOL FTP_FtpCreateDirectoryW(ftp_session_t *lpwfs, LPCWSTR lpszDirectory) +static BOOL FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory) { INT nResCode; BOOL bSuccess = FALSE; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; TRACE("lpszDirectory(%s)\n", debugstr_w(lpszDirectory)); @@ -711,14 +703,14 @@ HINTERNET WINAPI FtpFindFirstFileA(HINTERNET hConnect, LPWIN32_FIND_DATAW lpFindFileDataW; HINTERNET ret; - lpwzSearchFile = heap_strdupAtoW(lpszSearchFile); + lpwzSearchFile = lpszSearchFile?WININET_strdup_AtoW(lpszSearchFile):NULL; lpFindFileDataW = lpFindFileData?&wfd:NULL; ret = FtpFindFirstFileW(hConnect, lpwzSearchFile, lpFindFileDataW, dwFlags, dwContext); HeapFree(GetProcessHeap(), 0, lpwzSearchFile); if (ret && lpFindFileData) WININET_find_data_WtoA(lpFindFileDataW, lpFindFileData); - + return ret; } @@ -726,7 +718,7 @@ HINTERNET WINAPI FtpFindFirstFileA(HINTERNET hConnect, static void AsyncFtpFindFirstFileProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPFINDFIRSTFILEW const *req = &workRequest->u.FtpFindFirstFileW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -748,11 +740,11 @@ static void AsyncFtpFindFirstFileProc(WORKREQUEST *workRequest) HINTERNET WINAPI FtpFindFirstFileW(HINTERNET hConnect, LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; HINTERNET r = NULL; - lpwfs = (ftp_session_t*) WININET_GetObject( hConnect ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect ); if (NULL == lpwfs || WH_HFTPSESSION != lpwfs->hdr.htype) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); @@ -774,7 +766,7 @@ HINTERNET WINAPI FtpFindFirstFileW(HINTERNET hConnect, workRequest.asyncproc = AsyncFtpFindFirstFileProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); req = &workRequest.u.FtpFindFirstFileW; - req->lpszSearchFile = (lpszSearchFile == NULL) ? NULL : heap_strdupW(lpszSearchFile); + req->lpszSearchFile = (lpszSearchFile == NULL) ? NULL : WININET_strdupW(lpszSearchFile); req->lpFindFileData = lpFindFileData; req->dwFlags = dwFlags; req->dwContext= dwContext; @@ -805,11 +797,11 @@ lend: * NULL on failure * */ -static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs, +static HINTERNET FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD_PTR dwContext) { INT nResCode; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; HINTERNET hFindNext = NULL; TRACE("\n"); @@ -853,10 +845,7 @@ static HINTERNET FTP_FtpFindFirstFileW(ftp_session_t *lpwfs, lend: if (lpwfs->lstnSocket != -1) - { closesocket(lpwfs->lstnSocket); - lpwfs->lstnSocket = -1; - } hIC = lpwfs->lpAppInfo; if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) @@ -865,13 +854,13 @@ lend: if (hFindNext) { - iar.dwResult = (DWORD_PTR)hFindNext; + iar.dwResult = (DWORD)hFindNext; iar.dwError = ERROR_SUCCESS; SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED, &iar, sizeof(INTERNET_ASYNC_RESULT)); } - iar.dwResult = (DWORD_PTR)hFindNext; + iar.dwResult = (DWORD)hFindNext; iar.dwError = hFindNext ? ERROR_SUCCESS : INTERNET_GetLastError(); SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar, sizeof(INTERNET_ASYNC_RESULT)); @@ -924,7 +913,7 @@ BOOL WINAPI FtpGetCurrentDirectoryA(HINTERNET hFtpSession, LPSTR lpszCurrentDire static void AsyncFtpGetCurrentDirectoryProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPGETCURRENTDIRECTORYW const *req = &workRequest->u.FtpGetCurrentDirectoryW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -944,13 +933,13 @@ static void AsyncFtpGetCurrentDirectoryProc(WORKREQUEST *workRequest) BOOL WINAPI FtpGetCurrentDirectoryW(HINTERNET hFtpSession, LPWSTR lpszCurrentDirectory, LPDWORD lpdwCurrentDirectory) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; BOOL r = FALSE; TRACE("%p %p %p\n", hFtpSession, lpszCurrentDirectory, lpdwCurrentDirectory); - lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession ); if (NULL == lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -1019,11 +1008,11 @@ lend: * FALSE on failure * */ -static BOOL FTP_FtpGetCurrentDirectoryW(ftp_session_t *lpwfs, LPWSTR lpszCurrentDirectory, +static BOOL FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory, LPDWORD lpdwCurrentDirectory) { INT nResCode; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; DWORD bSuccess = FALSE; /* Clear any error information */ @@ -1040,7 +1029,7 @@ static BOOL FTP_FtpGetCurrentDirectoryW(ftp_session_t *lpwfs, LPWSTR lpszCurrent if (nResCode == 257) /* Extract directory name */ { DWORD firstpos, lastpos, len; - LPWSTR lpszResponseBuffer = heap_strdupAtoW(INTERNET_GetResponseBuffer()); + LPWSTR lpszResponseBuffer = WININET_strdup_AtoW(INTERNET_GetResponseBuffer()); for (firstpos = 0, lastpos = 0; lpszResponseBuffer[lastpos]; lastpos++) { @@ -1082,272 +1071,6 @@ lend: return bSuccess; } - -/*********************************************************************** - * FTPFILE_Destroy(internal) - * - * Closes the file transfer handle. This also 'cleans' the data queue of - * the 'transfer complete' message (this is a bit of a hack though :-/ ) - * - */ -static void FTPFILE_Destroy(object_header_t *hdr) -{ - ftp_file_t *lpwh = (ftp_file_t*) hdr; - ftp_session_t *lpwfs = lpwh->lpFtpSession; - INT nResCode; - - TRACE("\n"); - - if (!lpwh->session_deleted) - lpwfs->download_in_progress = NULL; - - if (lpwh->nDataSocket != -1) - closesocket(lpwh->nDataSocket); - - nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext); - if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n"); - - WININET_Release(&lpwh->lpFtpSession->hdr); - - HeapFree(GetProcessHeap(), 0, lpwh); -} - -static DWORD FTPFILE_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) -{ - switch(option) { - case INTERNET_OPTION_HANDLE_TYPE: - TRACE("INTERNET_OPTION_HANDLE_TYPE\n"); - - if (*size < sizeof(ULONG)) - return ERROR_INSUFFICIENT_BUFFER; - - *size = sizeof(DWORD); - *(DWORD*)buffer = INTERNET_HANDLE_TYPE_FTP_FILE; - return ERROR_SUCCESS; - } - - return INET_QueryOption(option, buffer, size, unicode); -} - -static DWORD FTPFILE_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read) -{ - ftp_file_t *file = (ftp_file_t*)hdr; - int res; - - if (file->nDataSocket == -1) - return ERROR_INTERNET_DISCONNECTED; - - /* FIXME: FTP should use NETCON_ stuff */ - res = recv(file->nDataSocket, buffer, size, MSG_WAITALL); - *read = res>0 ? res : 0; - - return res>=0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME*/ -} - -static DWORD FTPFILE_ReadFileExA(object_header_t *hdr, INTERNET_BUFFERSA *buffers, - DWORD flags, DWORD_PTR context) -{ - return FTPFILE_ReadFile(hdr, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength); -} - -static DWORD FTPFILE_ReadFileExW(object_header_t *hdr, INTERNET_BUFFERSW *buffers, - DWORD flags, DWORD_PTR context) -{ - return FTPFILE_ReadFile(hdr, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength); -} - -static BOOL FTPFILE_WriteFile(object_header_t *hdr, const void *buffer, DWORD size, DWORD *written) -{ - ftp_file_t *lpwh = (ftp_file_t*) hdr; - int res; - - res = send(lpwh->nDataSocket, buffer, size, 0); - - *written = res>0 ? res : 0; - return res >= 0; -} - -static void FTP_ReceiveRequestData(ftp_file_t *file, BOOL first_notif) -{ - INTERNET_ASYNC_RESULT iar; - BYTE buffer[4096]; - int available; - - TRACE("%p\n", file); - - available = recv(file->nDataSocket, buffer, sizeof(buffer), MSG_PEEK); - - if(available != -1) { - iar.dwResult = (DWORD_PTR)file->hdr.hInternet; - iar.dwError = first_notif ? 0 : available; - }else { - iar.dwResult = 0; - iar.dwError = INTERNET_GetLastError(); - } - - INTERNET_SendCallback(&file->hdr, file->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar, - sizeof(INTERNET_ASYNC_RESULT)); -} - -static void FTPFILE_AsyncQueryDataAvailableProc(WORKREQUEST *workRequest) -{ - ftp_file_t *file = (ftp_file_t*)workRequest->hdr; - - FTP_ReceiveRequestData(file, FALSE); -} - -static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx) -{ - ftp_file_t *file = (ftp_file_t*) hdr; - int retval, unread = 0; - - TRACE("(%p %p %x %lx)\n", file, available, flags, ctx); - -#ifdef FIONREAD - retval = ioctlsocket(file->nDataSocket, FIONREAD, &unread); - if (!retval) - TRACE("%d bytes of queued, but unread data\n", unread); -#else - FIXME("FIONREAD not available\n"); -#endif - - *available = unread; - - if(!unread) { - BYTE byte; - - *available = 0; - - retval = recv(file->nDataSocket, &byte, 1, MSG_PEEK); - if(retval > 0) { - WORKREQUEST workRequest; - - *available = 0; - workRequest.asyncproc = FTPFILE_AsyncQueryDataAvailableProc; - workRequest.hdr = WININET_AddRef( &file->hdr ); - - INTERNET_AsyncCall(&workRequest); - - return ERROR_IO_PENDING; - } - } - - return ERROR_SUCCESS; -} - - -static const object_vtbl_t FTPFILEVtbl = { - FTPFILE_Destroy, - NULL, - FTPFILE_QueryOption, - NULL, - FTPFILE_ReadFile, - FTPFILE_ReadFileExA, - FTPFILE_ReadFileExW, - FTPFILE_WriteFile, - FTPFILE_QueryDataAvailable, - NULL -}; - -/*********************************************************************** - * FTP_FtpOpenFileW (Internal) - * - * Open a remote file for writing or reading - * - * RETURNS - * HINTERNET handle on success - * NULL on failure - * - */ -HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs, - LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags, - DWORD_PTR dwContext) -{ - INT nDataSocket; - BOOL bSuccess = FALSE; - ftp_file_t *lpwh = NULL; - appinfo_t *hIC = NULL; - HINTERNET handle = NULL; - - TRACE("\n"); - - /* Clear any error information */ - INTERNET_SetLastError(0); - - if (GENERIC_READ == fdwAccess) - { - /* Set up socket to retrieve data */ - bSuccess = FTP_SendRetrieve(lpwfs, lpszFileName, dwFlags); - } - else if (GENERIC_WRITE == fdwAccess) - { - /* Set up socket to send data */ - bSuccess = FTP_SendStore(lpwfs, lpszFileName, dwFlags); - } - - /* Get data socket to server */ - if (bSuccess && FTP_GetDataSocket(lpwfs, &nDataSocket)) - { - lpwh = HeapAlloc(GetProcessHeap(), 0, sizeof(ftp_file_t)); - lpwh->hdr.htype = WH_HFILE; - lpwh->hdr.vtbl = &FTPFILEVtbl; - lpwh->hdr.dwFlags = dwFlags; - lpwh->hdr.dwContext = dwContext; - lpwh->hdr.dwInternalFlags = 0; - lpwh->hdr.refs = 1; - lpwh->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB; - lpwh->nDataSocket = nDataSocket; - lpwh->session_deleted = FALSE; - - WININET_AddRef( &lpwfs->hdr ); - lpwh->lpFtpSession = lpwfs; - list_add_head( &lpwfs->hdr.children, &lpwh->hdr.entry ); - - handle = WININET_AllocHandle( &lpwh->hdr ); - if( !handle ) - goto lend; - - /* Indicate that a download is currently in progress */ - lpwfs->download_in_progress = lpwh; - } - - if (lpwfs->lstnSocket != -1) - { - closesocket(lpwfs->lstnSocket); - lpwfs->lstnSocket = -1; - } - - hIC = lpwfs->lpAppInfo; - if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) - { - INTERNET_ASYNC_RESULT iar; - - if (lpwh) - { - iar.dwResult = (DWORD_PTR)handle; - iar.dwError = ERROR_SUCCESS; - SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED, - &iar, sizeof(INTERNET_ASYNC_RESULT)); - } - - if(bSuccess) { - FTP_ReceiveRequestData(lpwh, TRUE); - }else { - iar.dwResult = 0; - iar.dwError = INTERNET_GetLastError(); - SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, - &iar, sizeof(INTERNET_ASYNC_RESULT)); - } - } - -lend: - if( lpwh ) - WININET_Release( &lpwh->hdr ); - - return handle; -} - - /*********************************************************************** * FtpOpenFileA (WININET.@) * @@ -1364,8 +1087,8 @@ HINTERNET WINAPI FtpOpenFileA(HINTERNET hFtpSession, { LPWSTR lpwzFileName; HINTERNET ret; - - lpwzFileName = heap_strdupAtoW(lpszFileName); + + lpwzFileName = lpszFileName?WININET_strdup_AtoW(lpszFileName):NULL; ret = FtpOpenFileW(hFtpSession, lpwzFileName, fdwAccess, dwFlags, dwContext); HeapFree(GetProcessHeap(), 0, lpwzFileName); return ret; @@ -1375,7 +1098,7 @@ HINTERNET WINAPI FtpOpenFileA(HINTERNET hFtpSession, static void AsyncFtpOpenFileProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPOPENFILEW const *req = &workRequest->u.FtpOpenFileW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -1398,14 +1121,14 @@ HINTERNET WINAPI FtpOpenFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags, DWORD_PTR dwContext) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; HINTERNET r = NULL; - + TRACE("(%p,%s,0x%08x,0x%08x,0x%08lx)\n", hFtpSession, debugstr_w(lpszFileName), fdwAccess, dwFlags, dwContext); - lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession ); if (!lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -1441,7 +1164,7 @@ HINTERNET WINAPI FtpOpenFileW(HINTERNET hFtpSession, workRequest.asyncproc = AsyncFtpOpenFileProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); req = &workRequest.u.FtpOpenFileW; - req->lpszFilename = heap_strdupW(lpszFileName); + req->lpszFilename = WININET_strdupW(lpszFileName); req->dwAccess = fdwAccess; req->dwFlags = dwFlags; req->dwContext = dwContext; @@ -1461,6 +1184,181 @@ lend: } +/*********************************************************************** + * FTPFILE_Destroy(internal) + * + * Closes the file transfer handle. This also 'cleans' the data queue of + * the 'transfer complete' message (this is a bit of a hack though :-/ ) + * + */ +static void FTPFILE_Destroy(WININETHANDLEHEADER *hdr) +{ + LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr; + LPWININETFTPSESSIONW lpwfs = lpwh->lpFtpSession; + INT nResCode; + + TRACE("\n"); + + WININET_Release(&lpwh->lpFtpSession->hdr); + + if (!lpwh->session_deleted) + lpwfs->download_in_progress = NULL; + + if (lpwh->nDataSocket != -1) + closesocket(lpwh->nDataSocket); + + nResCode = FTP_ReceiveResponse(lpwfs, lpwfs->hdr.dwContext); + if (nResCode > 0 && nResCode != 226) WARN("server reports failed transfer\n"); + + HeapFree(GetProcessHeap(), 0, lpwh); +} + +static DWORD FTPFILE_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) +{ + switch(option) { + case INTERNET_OPTION_HANDLE_TYPE: + TRACE("INTERNET_OPTION_HANDLE_TYPE\n"); + + if (*size < sizeof(ULONG)) + return ERROR_INSUFFICIENT_BUFFER; + + *size = sizeof(DWORD); + *(DWORD*)buffer = INTERNET_HANDLE_TYPE_FTP_FILE; + return ERROR_SUCCESS; + } + + return INET_QueryOption(option, buffer, size, unicode); +} + +static DWORD FTPFILE_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read) +{ + WININETFTPFILE *file = (WININETFTPFILE*)hdr; + int res; + + if (file->nDataSocket == -1) + return ERROR_INTERNET_DISCONNECTED; + + /* FIXME: FTP should use NETCON_ stuff */ + res = recv(file->nDataSocket, buffer, size, MSG_WAITALL); + *read = res>0 ? res : 0; + + return res>=0 ? ERROR_SUCCESS : INTERNET_ERROR_BASE; /* FIXME*/ +} + +static BOOL FTPFILE_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written) +{ + LPWININETFTPFILE lpwh = (LPWININETFTPFILE) hdr; + int res; + + res = send(lpwh->nDataSocket, buffer, size, 0); + + *written = res>0 ? res : 0; + return res >= 0; +} + +static const HANDLEHEADERVtbl FTPFILEVtbl = { + FTPFILE_Destroy, + NULL, + FTPFILE_QueryOption, + NULL, + FTPFILE_ReadFile, + NULL, + FTPFILE_WriteFile, + NULL, + NULL +}; + +/*********************************************************************** + * FTP_FtpOpenFileW (Internal) + * + * Open a remote file for writing or reading + * + * RETURNS + * HINTERNET handle on success + * NULL on failure + * + */ +HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs, + LPCWSTR lpszFileName, DWORD fdwAccess, DWORD dwFlags, + DWORD_PTR dwContext) +{ + INT nDataSocket; + BOOL bSuccess = FALSE; + LPWININETFTPFILE lpwh = NULL; + LPWININETAPPINFOW hIC = NULL; + HINTERNET handle = NULL; + + TRACE("\n"); + + /* Clear any error information */ + INTERNET_SetLastError(0); + + if (GENERIC_READ == fdwAccess) + { + /* Set up socket to retrieve data */ + bSuccess = FTP_SendRetrieve(lpwfs, lpszFileName, dwFlags); + } + else if (GENERIC_WRITE == fdwAccess) + { + /* Set up socket to send data */ + bSuccess = FTP_SendStore(lpwfs, lpszFileName, dwFlags); + } + + /* Get data socket to server */ + if (bSuccess && FTP_GetDataSocket(lpwfs, &nDataSocket)) + { + lpwh = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPFILE)); + lpwh->hdr.htype = WH_HFILE; + lpwh->hdr.vtbl = &FTPFILEVtbl; + lpwh->hdr.dwFlags = dwFlags; + lpwh->hdr.dwContext = dwContext; + lpwh->hdr.refs = 1; + lpwh->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB; + lpwh->nDataSocket = nDataSocket; + lpwh->session_deleted = FALSE; + + WININET_AddRef( &lpwfs->hdr ); + lpwh->lpFtpSession = lpwfs; + list_add_head( &lpwfs->hdr.children, &lpwh->hdr.entry ); + + handle = WININET_AllocHandle( &lpwh->hdr ); + if( !handle ) + goto lend; + + /* Indicate that a download is currently in progress */ + lpwfs->download_in_progress = lpwh; + } + + if (lpwfs->lstnSocket != -1) + closesocket(lpwfs->lstnSocket); + + hIC = lpwfs->lpAppInfo; + if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) + { + INTERNET_ASYNC_RESULT iar; + + if (lpwh) + { + iar.dwResult = (DWORD)handle; + iar.dwError = ERROR_SUCCESS; + SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED, + &iar, sizeof(INTERNET_ASYNC_RESULT)); + } + + iar.dwResult = (DWORD)bSuccess; + iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError(); + SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, + &iar, sizeof(INTERNET_ASYNC_RESULT)); + } + +lend: + if( lpwh ) + WININET_Release( &lpwh->hdr ); + + return handle; +} + + /*********************************************************************** * FtpGetFileA (WININET.@) * @@ -1479,8 +1377,8 @@ BOOL WINAPI FtpGetFileA(HINTERNET hInternet, LPCSTR lpszRemoteFile, LPCSTR lpszN LPWSTR lpwzNewFile; BOOL ret; - lpwzRemoteFile = heap_strdupAtoW(lpszRemoteFile); - lpwzNewFile = heap_strdupAtoW(lpszNewFile); + lpwzRemoteFile = lpszRemoteFile?WININET_strdup_AtoW(lpszRemoteFile):NULL; + lpwzNewFile = lpszNewFile?WININET_strdup_AtoW(lpszNewFile):NULL; ret = FtpGetFileW(hInternet, lpwzRemoteFile, lpwzNewFile, fFailIfExists, dwLocalFlagsAttribute, dwInternetFlags, dwContext); HeapFree(GetProcessHeap(), 0, lpwzRemoteFile); @@ -1492,7 +1390,7 @@ BOOL WINAPI FtpGetFileA(HINTERNET hInternet, LPCSTR lpszRemoteFile, LPCSTR lpszN static void AsyncFtpGetFileProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPGETFILEW const *req = &workRequest->u.FtpGetFileW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -1518,8 +1416,8 @@ BOOL WINAPI FtpGetFileW(HINTERNET hInternet, LPCWSTR lpszRemoteFile, LPCWSTR lps BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags, DWORD_PTR dwContext) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; BOOL r = FALSE; if (!lpszRemoteFile || !lpszNewFile) @@ -1528,7 +1426,7 @@ BOOL WINAPI FtpGetFileW(HINTERNET hInternet, LPCWSTR lpszRemoteFile, LPCWSTR lps return FALSE; } - lpwfs = (ftp_session_t*) WININET_GetObject( hInternet ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hInternet ); if (!lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -1562,8 +1460,8 @@ BOOL WINAPI FtpGetFileW(HINTERNET hInternet, LPCWSTR lpszRemoteFile, LPCWSTR lps workRequest.asyncproc = AsyncFtpGetFileProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); req = &workRequest.u.FtpGetFileW; - req->lpszRemoteFile = heap_strdupW(lpszRemoteFile); - req->lpszNewFile = heap_strdupW(lpszNewFile); + req->lpszRemoteFile = WININET_strdupW(lpszRemoteFile); + req->lpszNewFile = WININET_strdupW(lpszNewFile); req->dwLocalFlagsAttribute = dwLocalFlagsAttribute; req->fFailIfExists = fFailIfExists; req->dwFlags = dwInternetFlags; @@ -1594,13 +1492,13 @@ lend: * FALSE on failure * */ -static BOOL FTP_FtpGetFileW(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile, +static BOOL FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile, BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags, DWORD_PTR dwContext) { BOOL bSuccess = FALSE; HANDLE hFile; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; TRACE("lpszRemoteFile(%s) lpszNewFile(%s)\n", debugstr_w(lpszRemoteFile), debugstr_w(lpszNewFile)); @@ -1639,10 +1537,7 @@ static BOOL FTP_FtpGetFileW(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, LPCWST } if (lpwfs->lstnSocket != -1) - { closesocket(lpwfs->lstnSocket); - lpwfs->lstnSocket = -1; - } CloseHandle(hFile); @@ -1689,7 +1584,7 @@ BOOL WINAPI FtpDeleteFileA(HINTERNET hFtpSession, LPCSTR lpszFileName) LPWSTR lpwzFileName; BOOL ret; - lpwzFileName = heap_strdupAtoW(lpszFileName); + lpwzFileName = lpszFileName?WININET_strdup_AtoW(lpszFileName):NULL; ret = FtpDeleteFileW(hFtpSession, lpwzFileName); HeapFree(GetProcessHeap(), 0, lpwzFileName); return ret; @@ -1698,7 +1593,7 @@ BOOL WINAPI FtpDeleteFileA(HINTERNET hFtpSession, LPCSTR lpszFileName) static void AsyncFtpDeleteFileProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPDELETEFILEW const *req = &workRequest->u.FtpDeleteFileW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -1718,11 +1613,11 @@ static void AsyncFtpDeleteFileProc(WORKREQUEST *workRequest) */ BOOL WINAPI FtpDeleteFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; BOOL r = FALSE; - lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession ); if (!lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -1756,7 +1651,7 @@ BOOL WINAPI FtpDeleteFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName) workRequest.asyncproc = AsyncFtpDeleteFileProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); req = &workRequest.u.FtpDeleteFileW; - req->lpszFilename = heap_strdupW(lpszFileName); + req->lpszFilename = WININET_strdupW(lpszFileName); r = INTERNET_AsyncCall(&workRequest); } @@ -1781,11 +1676,11 @@ lend: * FALSE on failure * */ -BOOL FTP_FtpDeleteFileW(ftp_session_t *lpwfs, LPCWSTR lpszFileName) +BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName) { INT nResCode; BOOL bSuccess = FALSE; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; TRACE("%p\n", lpwfs); @@ -1834,7 +1729,7 @@ BOOL WINAPI FtpRemoveDirectoryA(HINTERNET hFtpSession, LPCSTR lpszDirectory) LPWSTR lpwzDirectory; BOOL ret; - lpwzDirectory = heap_strdupAtoW(lpszDirectory); + lpwzDirectory = lpszDirectory?WININET_strdup_AtoW(lpszDirectory):NULL; ret = FtpRemoveDirectoryW(hFtpSession, lpwzDirectory); HeapFree(GetProcessHeap(), 0, lpwzDirectory); return ret; @@ -1843,7 +1738,7 @@ BOOL WINAPI FtpRemoveDirectoryA(HINTERNET hFtpSession, LPCSTR lpszDirectory) static void AsyncFtpRemoveDirectoryProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPREMOVEDIRECTORYW const *req = &workRequest->u.FtpRemoveDirectoryW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -1863,11 +1758,11 @@ static void AsyncFtpRemoveDirectoryProc(WORKREQUEST *workRequest) */ BOOL WINAPI FtpRemoveDirectoryW(HINTERNET hFtpSession, LPCWSTR lpszDirectory) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; BOOL r = FALSE; - lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession ); if (!lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -1901,7 +1796,7 @@ BOOL WINAPI FtpRemoveDirectoryW(HINTERNET hFtpSession, LPCWSTR lpszDirectory) workRequest.asyncproc = AsyncFtpRemoveDirectoryProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); req = &workRequest.u.FtpRemoveDirectoryW; - req->lpszDirectory = heap_strdupW(lpszDirectory); + req->lpszDirectory = WININET_strdupW(lpszDirectory); r = INTERNET_AsyncCall(&workRequest); } @@ -1926,11 +1821,11 @@ lend: * FALSE on failure * */ -BOOL FTP_FtpRemoveDirectoryW(ftp_session_t *lpwfs, LPCWSTR lpszDirectory) +BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory) { INT nResCode; BOOL bSuccess = FALSE; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; TRACE("\n"); @@ -1981,8 +1876,8 @@ BOOL WINAPI FtpRenameFileA(HINTERNET hFtpSession, LPCSTR lpszSrc, LPCSTR lpszDes LPWSTR lpwzDest; BOOL ret; - lpwzSrc = heap_strdupAtoW(lpszSrc); - lpwzDest = heap_strdupAtoW(lpszDest); + lpwzSrc = lpszSrc?WININET_strdup_AtoW(lpszSrc):NULL; + lpwzDest = lpszDest?WININET_strdup_AtoW(lpszDest):NULL; ret = FtpRenameFileW(hFtpSession, lpwzSrc, lpwzDest); HeapFree(GetProcessHeap(), 0, lpwzSrc); HeapFree(GetProcessHeap(), 0, lpwzDest); @@ -1992,7 +1887,7 @@ BOOL WINAPI FtpRenameFileA(HINTERNET hFtpSession, LPCSTR lpszSrc, LPCSTR lpszDes static void AsyncFtpRenameFileProc(WORKREQUEST *workRequest) { struct WORKREQ_FTPRENAMEFILEW const *req = &workRequest->u.FtpRenameFileW; - ftp_session_t *lpwfs = (ftp_session_t*) workRequest->hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest->hdr; TRACE("%p\n", lpwfs); @@ -2013,11 +1908,11 @@ static void AsyncFtpRenameFileProc(WORKREQUEST *workRequest) */ BOOL WINAPI FtpRenameFileW(HINTERNET hFtpSession, LPCWSTR lpszSrc, LPCWSTR lpszDest) { - ftp_session_t *lpwfs; - appinfo_t *hIC = NULL; + LPWININETFTPSESSIONW lpwfs; + LPWININETAPPINFOW hIC = NULL; BOOL r = FALSE; - lpwfs = (ftp_session_t*) WININET_GetObject( hFtpSession ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hFtpSession ); if (!lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -2051,8 +1946,8 @@ BOOL WINAPI FtpRenameFileW(HINTERNET hFtpSession, LPCWSTR lpszSrc, LPCWSTR lpszD workRequest.asyncproc = AsyncFtpRenameFileProc; workRequest.hdr = WININET_AddRef( &lpwfs->hdr ); req = &workRequest.u.FtpRenameFileW; - req->lpszSrcFile = heap_strdupW(lpszSrc); - req->lpszDestFile = heap_strdupW(lpszDest); + req->lpszSrcFile = WININET_strdupW(lpszSrc); + req->lpszDestFile = WININET_strdupW(lpszDest); r = INTERNET_AsyncCall(&workRequest); } @@ -2077,11 +1972,12 @@ lend: * FALSE on failure * */ -BOOL FTP_FtpRenameFileW(ftp_session_t *lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest) +BOOL FTP_FtpRenameFileW( LPWININETFTPSESSIONW lpwfs, + LPCWSTR lpszSrc, LPCWSTR lpszDest) { INT nResCode; BOOL bSuccess = FALSE; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; TRACE("\n"); @@ -2144,7 +2040,7 @@ BOOL WINAPI FtpCommandA( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags return FALSE; } - if (!(cmdW = heap_strdupAtoW(lpszCommand))) + if (!(cmdW = WININET_strdup_AtoW(lpszCommand))) { INTERNET_SetLastError(ERROR_OUTOFMEMORY); return FALSE; @@ -2163,7 +2059,7 @@ BOOL WINAPI FtpCommandW( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags LPCWSTR lpszCommand, DWORD_PTR dwContext, HINTERNET* phFtpCommand ) { BOOL r = FALSE; - ftp_session_t *lpwfs; + LPWININETFTPSESSIONW lpwfs; LPSTR cmd = NULL; DWORD len, nBytesSent= 0; INT nResCode, nRC = 0; @@ -2183,7 +2079,7 @@ BOOL WINAPI FtpCommandW( HINTERNET hConnect, BOOL fExpectResponse, DWORD dwFlags return FALSE; } - lpwfs = (ftp_session_t*) WININET_GetObject( hConnect ); + lpwfs = (LPWININETFTPSESSIONW) WININET_GetObject( hConnect ); if (!lpwfs) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -2246,9 +2142,9 @@ lend: * * Deallocate session handle */ -static void FTPSESSION_Destroy(object_header_t *hdr) +static void FTPSESSION_Destroy(WININETHANDLEHEADER *hdr) { - ftp_session_t *lpwfs = (ftp_session_t*) hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) hdr; TRACE("\n"); @@ -2259,9 +2155,9 @@ static void FTPSESSION_Destroy(object_header_t *hdr) HeapFree(GetProcessHeap(), 0, lpwfs); } -static void FTPSESSION_CloseConnection(object_header_t *hdr) +static void FTPSESSION_CloseConnection(WININETHANDLEHEADER *hdr) { - ftp_session_t *lpwfs = (ftp_session_t*) hdr; + LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) hdr; TRACE("\n"); @@ -2284,7 +2180,7 @@ static void FTPSESSION_CloseConnection(object_header_t *hdr) INTERNET_STATUS_CONNECTION_CLOSED, 0, 0); } -static DWORD FTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) +static DWORD FTPSESSION_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { switch(option) { case INTERNET_OPTION_HANDLE_TYPE: @@ -2301,7 +2197,7 @@ static DWORD FTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *bu return INET_QueryOption(option, buffer, size, unicode); } -static const object_vtbl_t FTPSESSIONVtbl = { +static const HANDLEHEADERVtbl FTPSESSIONVtbl = { FTPSESSION_Destroy, FTPSESSION_CloseConnection, FTPSESSION_QueryOption, @@ -2334,7 +2230,7 @@ static const object_vtbl_t FTPSESSIONVtbl = { * */ -HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, +HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext, DWORD dwInternalFlags) @@ -2351,7 +2247,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, INT nsocket = -1; UINT sock_namelen; BOOL bSuccess = FALSE; - ftp_session_t *lpwfs = NULL; + LPWININETFTPSESSIONW lpwfs = NULL; HINTERNET handle = NULL; TRACE("%p Server(%s) Port(%d) User(%s) Paswd(%s)\n", @@ -2360,13 +2256,13 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, assert( hIC->hdr.htype == WH_HINIT ); - if ((!lpszUserName || !*lpszUserName) && lpszPassword && *lpszPassword) + if (NULL == lpszUserName && NULL != lpszPassword) { INTERNET_SetLastError(ERROR_INVALID_PARAMETER); goto lerror; } - lpwfs = HeapAlloc(GetProcessHeap(), 0, sizeof(ftp_session_t)); + lpwfs = HeapAlloc(GetProcessHeap(), 0, sizeof(WININETFTPSESSIONW)); if (NULL == lpwfs) { INTERNET_SetLastError(ERROR_OUTOFMEMORY); @@ -2406,12 +2302,12 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if(hIC->lpszProxyBypass) FIXME("Proxy bypass is ignored.\n"); } - if (!lpszUserName || !strlenW(lpszUserName)) { + if ( !lpszUserName) { HKEY key; WCHAR szPassword[MAX_PATH]; DWORD len = sizeof(szPassword); - lpwfs->lpszUserName = heap_strdupW(szDefaultUsername); + lpwfs->lpszUserName = WININET_strdupW(szDefaultUsername); RegOpenKeyW(HKEY_CURRENT_USER, szKey, &key); if (RegQueryValueExW(key, szValue, NULL, NULL, (LPBYTE)szPassword, &len)) { @@ -2424,11 +2320,15 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, RegCloseKey(key); TRACE("Password used for anonymous ftp : (%s)\n", debugstr_w(szPassword)); - lpwfs->lpszPassword = heap_strdupW(szPassword); + lpwfs->lpszPassword = WININET_strdupW(szPassword); } else { - lpwfs->lpszUserName = heap_strdupW(lpszUserName); - lpwfs->lpszPassword = heap_strdupW(lpszPassword ? lpszPassword : szEmpty); + lpwfs->lpszUserName = WININET_strdupW(lpszUserName); + + if (lpszPassword) + lpwfs->lpszPassword = WININET_strdupW(lpszPassword); + else + lpwfs->lpszPassword = WININET_strdupW(szEmpty); } /* Don't send a handle created callback if this handle was created with InternetOpenUrl */ @@ -2436,7 +2336,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, { INTERNET_ASYNC_RESULT iar; - iar.dwResult = (DWORD_PTR)handle; + iar.dwResult = (DWORD)handle; iar.dwError = ERROR_SUCCESS; SendAsyncCallback(&hIC->hdr, dwContext, @@ -2447,9 +2347,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_RESOLVING_NAME, (LPWSTR) lpszServerName, strlenW(lpszServerName)); - sock_namelen = sizeof(socketAddr); - if (!GetAddress(lpszServerName, nServerPort, - (struct sockaddr *)&socketAddr, &sock_namelen)) + if (!GetAddress(lpszServerName, nServerPort, &socketAddr)) { INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); goto lerror; @@ -2458,12 +2356,6 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_NAME_RESOLVED, (LPWSTR) lpszServerName, strlenW(lpszServerName)); - if (socketAddr.sin_family != AF_INET) - { - WARN("unsupported address family %d\n", socketAddr.sin_family); - INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT); - goto lerror; - } nsocket = socket(AF_INET,SOCK_STREAM,0); if (nsocket == -1) { @@ -2472,20 +2364,19 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, } SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTING_TO_SERVER, - &socketAddr, sock_namelen); + &socketAddr, sizeof(struct sockaddr_in)); - if (connect(nsocket, (struct sockaddr *)&socketAddr, sock_namelen) < 0) + if (connect(nsocket, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) < 0) { ERR("Unable to connect (%s)\n", strerror(errno)); INTERNET_SetLastError(ERROR_INTERNET_CANNOT_CONNECT); - closesocket(nsocket); } else { TRACE("Connected to server\n"); lpwfs->sndSocket = nsocket; SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_CONNECTED_TO_SERVER, - &socketAddr, sock_namelen); + &socketAddr, sizeof(struct sockaddr_in)); sock_namelen = sizeof(lpwfs->socketAddress); getsockname(nsocket, (struct sockaddr *) &lpwfs->socketAddress, &sock_namelen); @@ -2506,6 +2397,16 @@ lerror: handle = NULL; } + if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) + { + INTERNET_ASYNC_RESULT iar; + + iar.dwResult = bSuccess ? (DWORD_PTR)lpwfs : 0; + iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError(); + SendAsyncCallback(&hIC->hdr, dwContext, INTERNET_STATUS_REQUEST_COMPLETE, + &iar, sizeof(INTERNET_ASYNC_RESULT)); + } + return handle; } @@ -2520,7 +2421,7 @@ lerror: * NULL on failure * */ -static BOOL FTP_ConnectToHost(ftp_session_t *lpwfs) +static BOOL FTP_ConnectToHost(LPWININETFTPSESSIONW lpwfs) { INT nResCode; BOOL bSuccess = FALSE; @@ -2564,7 +2465,7 @@ lend: * */ static BOOL FTP_SendCommandA(INT nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam, - INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext) + INTERNET_STATUS_CALLBACK lpfnStatusCB, LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext) { DWORD len; CHAR *buf; @@ -2619,10 +2520,10 @@ static BOOL FTP_SendCommandA(INT nSocket, FTP_COMMAND ftpCmd, LPCSTR lpszParam, * */ static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam, - INTERNET_STATUS_CALLBACK lpfnStatusCB, object_header_t *hdr, DWORD_PTR dwContext) + INTERNET_STATUS_CALLBACK lpfnStatusCB, LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext) { BOOL ret; - LPSTR lpszParamA = heap_strdupWtoA(lpszParam); + LPSTR lpszParamA = lpszParam?WININET_strdup_WtoA(lpszParam):NULL; ret = FTP_SendCommandA(nSocket, ftpCmd, lpszParamA, lpfnStatusCB, hdr, dwContext); HeapFree(GetProcessHeap(), 0, lpszParamA); return ret; @@ -2638,7 +2539,7 @@ static BOOL FTP_SendCommand(INT nSocket, FTP_COMMAND ftpCmd, LPCWSTR lpszParam, * 0 on failure * */ -INT FTP_ReceiveResponse(ftp_session_t *lpwfs, DWORD_PTR dwContext) +INT FTP_ReceiveResponse(LPWININETFTPSESSIONW lpwfs, DWORD_PTR dwContext) { LPSTR lpszResponse = INTERNET_GetResponseBuffer(); DWORD nRecv; @@ -2701,7 +2602,7 @@ lerror: * NULL on failure * */ -static BOOL FTP_SendPassword(ftp_session_t *lpwfs) +static BOOL FTP_SendPassword(LPWININETFTPSESSIONW lpwfs) { INT nResCode; BOOL bSuccess = FALSE; @@ -2741,7 +2642,7 @@ lend: * FALSE on failure * */ -static BOOL FTP_SendAccount(ftp_session_t *lpwfs) +static BOOL FTP_SendAccount(LPWININETFTPSESSIONW lpwfs) { INT nResCode; BOOL bSuccess = FALSE; @@ -2771,7 +2672,7 @@ lend: * FALSE on failure * */ -static BOOL FTP_SendStore(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType) +static BOOL FTP_SendStore(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType) { INT nResCode; BOOL bSuccess = FALSE; @@ -2818,10 +2719,10 @@ lend: * FALSE on failure * */ -static BOOL FTP_InitListenSocket(ftp_session_t *lpwfs) +static BOOL FTP_InitListenSocket(LPWININETFTPSESSIONW lpwfs) { BOOL bSuccess = FALSE; - socklen_t namelen = sizeof(lpwfs->lstnSocketAddress); + socklen_t namelen = sizeof(struct sockaddr_in); TRACE("\n"); @@ -2836,9 +2737,9 @@ static BOOL FTP_InitListenSocket(ftp_session_t *lpwfs) lpwfs->lstnSocketAddress = lpwfs->socketAddress; /* and get the system to assign us a port */ - lpwfs->lstnSocketAddress.sin_port = htons(0); + lpwfs->lstnSocketAddress.sin_port = htons((u_short) 0); - if (bind(lpwfs->lstnSocket,(struct sockaddr *) &lpwfs->lstnSocketAddress, sizeof(lpwfs->lstnSocketAddress)) == -1) + if (bind(lpwfs->lstnSocket,(struct sockaddr *) &lpwfs->lstnSocketAddress, sizeof(struct sockaddr_in)) == -1) { TRACE("Unable to bind socket\n"); goto lend; @@ -2877,7 +2778,7 @@ lend: * (i.e. it sends it always), * so we probably don't want to do that either. */ -static BOOL FTP_SendType(ftp_session_t *lpwfs, DWORD dwType) +static BOOL FTP_SendType(LPWININETFTPSESSIONW lpwfs, DWORD dwType) { INT nResCode; WCHAR type[] = { 'I','\0' }; @@ -2915,7 +2816,7 @@ lend: * FALSE on failure * */ -static BOOL FTP_GetFileSize(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD *dwSize) +static BOOL FTP_GetFileSize(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD *dwSize) { INT nResCode; BOOL bSuccess = FALSE; @@ -2959,7 +2860,7 @@ lend: * FALSE on failure * */ -static BOOL FTP_SendPort(ftp_session_t *lpwfs) +static BOOL FTP_SendPort(LPWININETFTPSESSIONW lpwfs) { static const WCHAR szIPFormat[] = {'%','d',',','%','d',',','%','d',',','%','d',',','%','d',',','%','d','\0'}; INT nResCode; @@ -3003,7 +2904,7 @@ lend: * FALSE on failure * */ -static BOOL FTP_DoPassive(ftp_session_t *lpwfs) +static BOOL FTP_DoPassive(LPWININETFTPSESSIONW lpwfs) { INT nResCode; BOOL bSuccess = FALSE; @@ -3075,7 +2976,7 @@ lend: } -static BOOL FTP_SendPortOrPasv(ftp_session_t *lpwfs) +static BOOL FTP_SendPortOrPasv(LPWININETFTPSESSIONW lpwfs) { if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE) { @@ -3104,7 +3005,7 @@ static BOOL FTP_SendPortOrPasv(ftp_session_t *lpwfs) * FALSE on failure * */ -static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket) +static BOOL FTP_GetDataSocket(LPWININETFTPSESSIONW lpwfs, LPINT nDataSocket) { struct sockaddr_in saddr; socklen_t addrlen = sizeof(struct sockaddr); @@ -3113,7 +3014,6 @@ static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket) if (lpwfs->hdr.dwFlags & INTERNET_FLAG_PASSIVE) { *nDataSocket = lpwfs->pasvSocket; - lpwfs->pasvSocket = -1; } else { @@ -3135,7 +3035,7 @@ static BOOL FTP_GetDataSocket(ftp_session_t *lpwfs, LPINT nDataSocket) * FALSE on failure * */ -static BOOL FTP_SendData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile) +static BOOL FTP_SendData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile) { BY_HANDLE_FILE_INFORMATION fi; DWORD nBytesRead = 0; @@ -3216,7 +3116,7 @@ static BOOL FTP_SendData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile) * 0 on failure * */ -static BOOL FTP_SendRetrieve(ftp_session_t *lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType) +static BOOL FTP_SendRetrieve(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, DWORD dwType) { INT nResCode; BOOL ret; @@ -3262,7 +3162,7 @@ lend: * FALSE on failure * */ -static BOOL FTP_RetrieveFileData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile) +static BOOL FTP_RetrieveFileData(LPWININETFTPSESSIONW lpwfs, INT nDataSocket, HANDLE hFile) { DWORD nBytesWritten; INT nRC = 0; @@ -3302,7 +3202,7 @@ recv_end: * * Deallocate session handle */ -static void FTPFINDNEXT_Destroy(object_header_t *hdr) +static void FTPFINDNEXT_Destroy(WININETHANDLEHEADER *hdr) { LPWININETFTPFINDNEXTW lpwfn = (LPWININETFTPFINDNEXTW) hdr; DWORD i; @@ -3320,7 +3220,7 @@ static void FTPFINDNEXT_Destroy(object_header_t *hdr) HeapFree(GetProcessHeap(), 0, lpwfn); } -static DWORD FTPFINDNEXT_FindNextFileProc(WININETFTPFINDNEXTW *find, LPVOID data) +static DWORD WINAPI FTPFINDNEXT_FindNextFileProc(WININETFTPFINDNEXTW *find, LPVOID data) { WIN32_FIND_DATAW *find_data = data; DWORD res = ERROR_SUCCESS; @@ -3360,7 +3260,7 @@ static void FTPFINDNEXT_AsyncFindNextFileProc(WORKREQUEST *workRequest) FTPFINDNEXT_FindNextFileProc((WININETFTPFINDNEXTW*)workRequest->hdr, req->lpFindFileData); } -static DWORD FTPFINDNEXT_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) +static DWORD FTPFINDNEXT_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { switch(option) { case INTERNET_OPTION_HANDLE_TYPE: @@ -3377,7 +3277,7 @@ static DWORD FTPFINDNEXT_QueryOption(object_header_t *hdr, DWORD option, void *b return INET_QueryOption(option, buffer, size, unicode); } -static DWORD FTPFINDNEXT_FindNextFileW(object_header_t *hdr, void *data) +static DWORD FTPFINDNEXT_FindNextFileW(WININETHANDLEHEADER *hdr, void *data) { WININETFTPFINDNEXTW *find = (WININETFTPFINDNEXTW*)hdr; @@ -3399,7 +3299,7 @@ static DWORD FTPFINDNEXT_FindNextFileW(object_header_t *hdr, void *data) return FTPFINDNEXT_FindNextFileProc(find, data); } -static const object_vtbl_t FTPFINDNEXTVtbl = { +static const HANDLEHEADERVtbl FTPFINDNEXTVtbl = { FTPFINDNEXT_Destroy, NULL, FTPFINDNEXT_QueryOption, @@ -3408,7 +3308,6 @@ static const object_vtbl_t FTPFINDNEXTVtbl = { NULL, NULL, NULL, - NULL, FTPFINDNEXT_FindNextFileW }; @@ -3422,7 +3321,7 @@ static const object_vtbl_t FTPFINDNEXTVtbl = { * NULL on failure * */ -static HINTERNET FTP_ReceiveFileList(ftp_session_t *lpwfs, INT nSocket, LPCWSTR lpszSearchFile, +static HINTERNET FTP_ReceiveFileList(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD_PTR dwContext) { DWORD dwSize = 0; @@ -3483,7 +3382,9 @@ static BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFi if (lpafp) { - SystemTimeToFileTime( &lpafp->tmLastModified, &lpFindFileData->ftLastAccessTime ); + /* Convert 'Unix' time to Windows time */ + RtlSecondsSince1970ToTime(mktime(&lpafp->tmLastModified), + (LARGE_INTEGER *) &(lpFindFileData->ftLastAccessTime)); lpFindFileData->ftLastWriteTime = lpFindFileData->ftLastAccessTime; lpFindFileData->ftCreationTime = lpFindFileData->ftLastAccessTime; @@ -3551,12 +3452,12 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT lpfp->nSize = atol(pszToken); } - lpfp->tmLastModified.wSecond = 0; - lpfp->tmLastModified.wMinute = 0; - lpfp->tmLastModified.wHour = 0; - lpfp->tmLastModified.wDay = 0; - lpfp->tmLastModified.wMonth = 0; - lpfp->tmLastModified.wYear = 0; + lpfp->tmLastModified.tm_sec = 0; + lpfp->tmLastModified.tm_min = 0; + lpfp->tmLastModified.tm_hour = 0; + lpfp->tmLastModified.tm_mday = 0; + lpfp->tmLastModified.tm_mon = 0; + lpfp->tmLastModified.tm_year = 0; /* Determine month */ pszToken = strtok(NULL, szSpace); @@ -3564,35 +3465,38 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT if(strlen(pszToken) >= 3) { pszToken[3] = 0; if((pszTmp = StrStrIA(szMonths, pszToken))) - lpfp->tmLastModified.wMonth = ((pszTmp - szMonths) / 3)+1; + lpfp->tmLastModified.tm_mon = ((pszTmp - szMonths) / 3)+1; } /* Determine day */ pszToken = strtok(NULL, szSpace); if(!pszToken) continue; - lpfp->tmLastModified.wDay = atoi(pszToken); + lpfp->tmLastModified.tm_mday = atoi(pszToken); /* Determine time or year */ pszToken = strtok(NULL, szSpace); if(!pszToken) continue; if((pszTmp = strchr(pszToken, ':'))) { - SYSTEMTIME curr_time; + struct tm* apTM; + time_t aTime; *pszTmp = 0; pszTmp++; - lpfp->tmLastModified.wMinute = atoi(pszTmp); - lpfp->tmLastModified.wHour = atoi(pszToken); - GetLocalTime( &curr_time ); - lpfp->tmLastModified.wYear = curr_time.wYear; + lpfp->tmLastModified.tm_min = atoi(pszTmp); + lpfp->tmLastModified.tm_hour = atoi(pszToken); + time(&aTime); + apTM = localtime(&aTime); + lpfp->tmLastModified.tm_year = apTM->tm_year; } else { - lpfp->tmLastModified.wYear = atoi(pszToken); - lpfp->tmLastModified.wHour = 12; + lpfp->tmLastModified.tm_year = atoi(pszToken) - 1900; + lpfp->tmLastModified.tm_hour = 12; } - TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n", - lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond, - lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay); + TRACE("Mod time: %02d:%02d:%02d %02d/%02d/%02d\n", + lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec, + (lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year, + lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday); pszToken = strtok(NULL, szSpace); if(!pszToken) continue; - lpfp->lpszName = heap_strdupAtoW(pszToken); + lpfp->lpszName = WININET_strdup_AtoW(pszToken); TRACE("File: %s\n", debugstr_w(lpfp->lpszName)); } /* NT way of parsing ... : @@ -3601,31 +3505,32 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT 05-09-03 06:02PM 12656686 2003-04-21bgm_cmd_e.rgz */ else if(isdigit(pszToken[0]) && 8 == strlen(pszToken)) { - int mon, mday, year, hour, min; lpfp->permissions = 0xFFFF; /* No idea, put full permission :-) */ - sscanf(pszToken, "%d-%d-%d", &mon, &mday, &year); - lpfp->tmLastModified.wDay = mday; - lpfp->tmLastModified.wMonth = mon; - lpfp->tmLastModified.wYear = year; + sscanf(pszToken, "%d-%d-%d", + &lpfp->tmLastModified.tm_mon, + &lpfp->tmLastModified.tm_mday, + &lpfp->tmLastModified.tm_year); /* Hacky and bad Y2K protection :-) */ - if (lpfp->tmLastModified.wYear < 70) lpfp->tmLastModified.wYear += 2000; - + if (lpfp->tmLastModified.tm_year < 70) + lpfp->tmLastModified.tm_year += 100; + pszToken = strtok(NULL, szSpace); if(!pszToken) continue; - sscanf(pszToken, "%d:%d", &hour, &min); - lpfp->tmLastModified.wHour = hour; - lpfp->tmLastModified.wMinute = min; + sscanf(pszToken, "%d:%d", + &lpfp->tmLastModified.tm_hour, + &lpfp->tmLastModified.tm_min); if((pszToken[5] == 'P') && (pszToken[6] == 'M')) { - lpfp->tmLastModified.wHour += 12; + lpfp->tmLastModified.tm_hour += 12; } - lpfp->tmLastModified.wSecond = 0; - - TRACE("Mod time: %02d:%02d:%02d %04d/%02d/%02d\n", - lpfp->tmLastModified.wHour, lpfp->tmLastModified.wMinute, lpfp->tmLastModified.wSecond, - lpfp->tmLastModified.wYear, lpfp->tmLastModified.wMonth, lpfp->tmLastModified.wDay); + lpfp->tmLastModified.tm_sec = 0; + TRACE("Mod time: %02d:%02d:%02d %02d/%02d/%02d\n", + lpfp->tmLastModified.tm_hour, lpfp->tmLastModified.tm_min, lpfp->tmLastModified.tm_sec, + (lpfp->tmLastModified.tm_year >= 100) ? lpfp->tmLastModified.tm_year - 100 : lpfp->tmLastModified.tm_year, + lpfp->tmLastModified.tm_mon, lpfp->tmLastModified.tm_mday); + pszToken = strtok(NULL, szSpace); if(!pszToken) continue; if(!strcasecmp(pszToken, "")) { @@ -3641,7 +3546,7 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT pszToken = strtok(NULL, szSpace); if(!pszToken) continue; - lpfp->lpszName = heap_strdupAtoW(pszToken); + lpfp->lpszName = WININET_strdup_AtoW(pszToken); TRACE("Name: %s\n", debugstr_w(lpfp->lpszName)); } /* EPLF format - http://cr.yp.to/ftp/list/eplf.html */ @@ -3673,7 +3578,7 @@ static BOOL FTP_ParseNextFile(INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERT * TRUE on success * FALSE on failure */ -static BOOL FTP_ParseDirectory(ftp_session_t *lpwfs, INT nSocket, LPCWSTR lpszSearchFile, +static BOOL FTP_ParseDirectory(LPWININETFTPSESSIONW lpwfs, INT nSocket, LPCWSTR lpszSearchFile, LPFILEPROPERTIESW *lpafp, LPDWORD dwfp) { BOOL bSuccess = TRUE; diff --git a/reactos/dll/win32/wininet/http.c b/reactos/dll/win32/wininet/http.c index 3a14f7ad844..f0ad6beddc1 100644 --- a/reactos/dll/win32/wininet/http.c +++ b/reactos/dll/win32/wininet/http.c @@ -29,10 +29,6 @@ #include "config.h" #include "wine/port.h" -#if defined(__MINGW32__) || defined (_MSC_VER) -#include -#endif - #include #ifdef HAVE_SYS_SOCKET_H # include @@ -48,9 +44,6 @@ #endif #include #include -#ifdef HAVE_ZLIB -# include -#endif #include "windef.h" #include "winbase.h" @@ -66,7 +59,6 @@ #include "internet.h" #include "wine/debug.h" -#include "wine/exception.h" #include "wine/unicode.h" #include "inet_ntop.c" @@ -75,75 +67,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet); static const WCHAR g_szHttp1_0[] = {'H','T','T','P','/','1','.','0',0}; static const WCHAR g_szHttp1_1[] = {'H','T','T','P','/','1','.','1',0}; -static const WCHAR hostW[] = { 'H','o','s','t',0 }; +static const WCHAR g_szReferer[] = {'R','e','f','e','r','e','r',0}; +static const WCHAR g_szAccept[] = {'A','c','c','e','p','t',0}; +static const WCHAR g_szUserAgent[] = {'U','s','e','r','-','A','g','e','n','t',0}; +static const WCHAR szHost[] = { 'H','o','s','t',0 }; static const WCHAR szAuthorization[] = { 'A','u','t','h','o','r','i','z','a','t','i','o','n',0 }; static const WCHAR szProxy_Authorization[] = { 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0 }; static const WCHAR szStatus[] = { 'S','t','a','t','u','s',0 }; static const WCHAR szKeepAlive[] = {'K','e','e','p','-','A','l','i','v','e',0}; static const WCHAR szGET[] = { 'G','E','T', 0 }; -static const WCHAR szHEAD[] = { 'H','E','A','D', 0 }; -static const WCHAR szCrLf[] = {'\r','\n', 0}; - -static const WCHAR szAccept[] = { 'A','c','c','e','p','t',0 }; -static const WCHAR szAccept_Charset[] = { 'A','c','c','e','p','t','-','C','h','a','r','s','e','t', 0 }; -static const WCHAR szAccept_Encoding[] = { 'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',0 }; -static const WCHAR szAccept_Language[] = { 'A','c','c','e','p','t','-','L','a','n','g','u','a','g','e',0 }; -static const WCHAR szAccept_Ranges[] = { 'A','c','c','e','p','t','-','R','a','n','g','e','s',0 }; -static const WCHAR szAge[] = { 'A','g','e',0 }; -static const WCHAR szAllow[] = { 'A','l','l','o','w',0 }; -static const WCHAR szCache_Control[] = { 'C','a','c','h','e','-','C','o','n','t','r','o','l',0 }; -static const WCHAR szConnection[] = { 'C','o','n','n','e','c','t','i','o','n',0 }; -static const WCHAR szContent_Base[] = { 'C','o','n','t','e','n','t','-','B','a','s','e',0 }; -static const WCHAR szContent_Encoding[] = { 'C','o','n','t','e','n','t','-','E','n','c','o','d','i','n','g',0 }; -static const WCHAR szContent_ID[] = { 'C','o','n','t','e','n','t','-','I','D',0 }; -static const WCHAR szContent_Language[] = { 'C','o','n','t','e','n','t','-','L','a','n','g','u','a','g','e',0 }; -static const WCHAR szContent_Length[] = { 'C','o','n','t','e','n','t','-','L','e','n','g','t','h',0 }; -static const WCHAR szContent_Location[] = { 'C','o','n','t','e','n','t','-','L','o','c','a','t','i','o','n',0 }; -static const WCHAR szContent_MD5[] = { 'C','o','n','t','e','n','t','-','M','D','5',0 }; -static const WCHAR szContent_Range[] = { 'C','o','n','t','e','n','t','-','R','a','n','g','e',0 }; -static const WCHAR szContent_Transfer_Encoding[] = { 'C','o','n','t','e','n','t','-','T','r','a','n','s','f','e','r','-','E','n','c','o','d','i','n','g',0 }; -static const WCHAR szContent_Type[] = { 'C','o','n','t','e','n','t','-','T','y','p','e',0 }; -static const WCHAR szCookie[] = { 'C','o','o','k','i','e',0 }; -static const WCHAR szDate[] = { 'D','a','t','e',0 }; -static const WCHAR szFrom[] = { 'F','r','o','m',0 }; -static const WCHAR szETag[] = { 'E','T','a','g',0 }; -static const WCHAR szExpect[] = { 'E','x','p','e','c','t',0 }; -static const WCHAR szExpires[] = { 'E','x','p','i','r','e','s',0 }; -static const WCHAR szIf_Match[] = { 'I','f','-','M','a','t','c','h',0 }; -static const WCHAR szIf_Modified_Since[] = { 'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0 }; -static const WCHAR szIf_None_Match[] = { 'I','f','-','N','o','n','e','-','M','a','t','c','h',0 }; -static const WCHAR szIf_Range[] = { 'I','f','-','R','a','n','g','e',0 }; -static const WCHAR szIf_Unmodified_Since[] = { 'I','f','-','U','n','m','o','d','i','f','i','e','d','-','S','i','n','c','e',0 }; -static const WCHAR szLast_Modified[] = { 'L','a','s','t','-','M','o','d','i','f','i','e','d',0 }; -static const WCHAR szLocation[] = { 'L','o','c','a','t','i','o','n',0 }; -static const WCHAR szMax_Forwards[] = { 'M','a','x','-','F','o','r','w','a','r','d','s',0 }; -static const WCHAR szMime_Version[] = { 'M','i','m','e','-','V','e','r','s','i','o','n',0 }; -static const WCHAR szPragma[] = { 'P','r','a','g','m','a',0 }; -static const WCHAR szProxy_Authenticate[] = { 'P','r','o','x','y','-','A','u','t','h','e','n','t','i','c','a','t','e',0 }; -static const WCHAR szProxy_Connection[] = { 'P','r','o','x','y','-','C','o','n','n','e','c','t','i','o','n',0 }; -static const WCHAR szPublic[] = { 'P','u','b','l','i','c',0 }; -static const WCHAR szRange[] = { 'R','a','n','g','e',0 }; -static const WCHAR szReferer[] = { 'R','e','f','e','r','e','r',0 }; -static const WCHAR szRetry_After[] = { 'R','e','t','r','y','-','A','f','t','e','r',0 }; -static const WCHAR szServer[] = { 'S','e','r','v','e','r',0 }; -static const WCHAR szSet_Cookie[] = { 'S','e','t','-','C','o','o','k','i','e',0 }; -static const WCHAR szTransfer_Encoding[] = { 'T','r','a','n','s','f','e','r','-','E','n','c','o','d','i','n','g',0 }; -static const WCHAR szUnless_Modified_Since[] = { 'U','n','l','e','s','s','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0 }; -static const WCHAR szUpgrade[] = { 'U','p','g','r','a','d','e',0 }; -static const WCHAR szURI[] = { 'U','R','I',0 }; -static const WCHAR szUser_Agent[] = { 'U','s','e','r','-','A','g','e','n','t',0 }; -static const WCHAR szVary[] = { 'V','a','r','y',0 }; -static const WCHAR szVia[] = { 'V','i','a',0 }; -static const WCHAR szWarning[] = { 'W','a','r','n','i','n','g',0 }; -static const WCHAR szWWW_Authenticate[] = { 'W','W','W','-','A','u','t','h','e','n','t','i','c','a','t','e',0 }; #define MAXHOSTNAME 100 #define MAX_FIELD_VALUE_LEN 256 #define MAX_FIELD_LEN 256 -#define HTTP_REFERER szReferer -#define HTTP_ACCEPT szAccept -#define HTTP_USERAGENT szUser_Agent +#define HTTP_REFERER g_szReferer +#define HTTP_ACCEPT g_szAccept +#define HTTP_USERAGENT g_szUserAgent #define HTTP_ADDHDR_FLAG_ADD 0x20000000 #define HTTP_ADDHDR_FLAG_ADD_IF_NEW 0x10000000 @@ -168,55 +108,23 @@ struct HttpAuthInfo BOOL finished; /* finished authenticating */ }; - -struct gzip_stream_t { -#ifdef HAVE_ZLIB - z_stream zstream; -#endif - BYTE buf[8192]; - DWORD buf_size; - DWORD buf_pos; - BOOL end_of_data; -}; - -typedef struct _authorizationData -{ - struct list entry; - - LPWSTR lpszwHost; - LPWSTR lpszwRealm; - LPSTR lpszAuthorization; - UINT AuthorizationLen; -} authorizationData; - -static struct list basicAuthorizationCache = LIST_INIT(basicAuthorizationCache); - -static CRITICAL_SECTION authcache_cs; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &authcache_cs, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": authcache_cs") } -}; -static CRITICAL_SECTION authcache_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; - -static BOOL HTTP_OpenConnection(http_request_t *req); -static BOOL HTTP_GetResponseHeaders(http_request_t *req, BOOL clear); -static BOOL HTTP_ProcessHeader(http_request_t *req, LPCWSTR field, LPCWSTR value, DWORD dwModifier); +static BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr); +static BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr, BOOL clear); +static BOOL HTTP_ProcessHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field, LPCWSTR value, DWORD dwModifier); static LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer); -static BOOL HTTP_InsertCustomHeader(http_request_t *req, LPHTTPHEADERW lpHdr); -static INT HTTP_GetCustomHeaderIndex(http_request_t *req, LPCWSTR lpszField, INT index, BOOL Request); -static BOOL HTTP_DeleteCustomHeader(http_request_t *req, DWORD index); +static BOOL HTTP_InsertCustomHeader(LPWININETHTTPREQW lpwhr, LPHTTPHEADERW lpHdr); +static INT HTTP_GetCustomHeaderIndex(LPWININETHTTPREQW lpwhr, LPCWSTR lpszField, INT index, BOOL Request); +static BOOL HTTP_DeleteCustomHeader(LPWININETHTTPREQW lpwhr, DWORD index); static LPWSTR HTTP_build_req( LPCWSTR *list, int len ); -static BOOL HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWORD); -static LPWSTR HTTP_GetRedirectURL(http_request_t *req, LPCWSTR lpszUrl); -static BOOL HTTP_HandleRedirect(http_request_t *req, LPCWSTR lpszUrl); +static BOOL WINAPI HTTP_HttpQueryInfoW( LPWININETHTTPREQW lpwhr, DWORD + dwInfoLevel, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD + lpdwIndex); +static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl); static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin); -static BOOL HTTP_VerifyValidHeader(http_request_t *req, LPCWSTR field); -static void HTTP_DrainContent(http_request_t *req); -static BOOL HTTP_FinishedReading(http_request_t *req); +static BOOL HTTP_VerifyValidHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field); +static void HTTP_DrainContent(WININETHTTPREQW *req); -static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head) +LPHTTPHEADERW HTTP_GetHeader(LPWININETHTTPREQW req, LPCWSTR head) { int HeaderIndex = 0; HeaderIndex = HTTP_GetCustomHeaderIndex(req, head, 0, TRUE); @@ -226,91 +134,6 @@ static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head) return &req->pCustHeaders[HeaderIndex]; } -#ifdef HAVE_ZLIB - -static voidpf wininet_zalloc(voidpf opaque, uInt items, uInt size) -{ - return HeapAlloc(GetProcessHeap(), 0, items*size); -} - -static void wininet_zfree(voidpf opaque, voidpf address) -{ - HeapFree(GetProcessHeap(), 0, address); -} - -static void init_gzip_stream(http_request_t *req) -{ - gzip_stream_t *gzip_stream; - int index, zres; - - gzip_stream = HeapAlloc(GetProcessHeap(), 0, sizeof(gzip_stream_t)); - gzip_stream->zstream.zalloc = wininet_zalloc; - gzip_stream->zstream.zfree = wininet_zfree; - gzip_stream->zstream.opaque = NULL; - gzip_stream->zstream.next_in = NULL; - gzip_stream->zstream.avail_in = 0; - gzip_stream->zstream.next_out = NULL; - gzip_stream->zstream.avail_out = 0; - gzip_stream->buf_pos = 0; - gzip_stream->buf_size = 0; - gzip_stream->end_of_data = FALSE; - - zres = inflateInit2(&gzip_stream->zstream, 0x1f); - if(zres != Z_OK) { - ERR("inflateInit failed: %d\n", zres); - HeapFree(GetProcessHeap(), 0, gzip_stream); - return; - } - - req->gzip_stream = gzip_stream; - - index = HTTP_GetCustomHeaderIndex(req, szContent_Length, 0, FALSE); - if(index != -1) - HTTP_DeleteCustomHeader(req, index); -} - -#else - -static void init_gzip_stream(http_request_t *req) -{ - ERR("gzip stream not supported, missing zlib.\n"); -} - -#endif - -/* set the request content length based on the headers */ -static DWORD set_content_length( http_request_t *lpwhr ) -{ - static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0}; - WCHAR encoding[20]; - DWORD size; - - size = sizeof(lpwhr->dwContentLength); - if (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, - &lpwhr->dwContentLength, &size, NULL)) - lpwhr->dwContentLength = ~0u; - - size = sizeof(encoding); - if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_TRANSFER_ENCODING, encoding, &size, NULL) && - !strcmpiW(encoding, szChunked)) - { - lpwhr->dwContentLength = ~0u; - lpwhr->read_chunked = TRUE; - } - - if(lpwhr->decoding) { - int encoding_idx; - - static const WCHAR gzipW[] = {'g','z','i','p',0}; - - encoding_idx = HTTP_GetCustomHeaderIndex(lpwhr, szContent_Encoding, 0, FALSE); - if(encoding_idx != -1 && !strcmpiW(lpwhr->pCustHeaders[encoding_idx].lpszValue, gzipW)) - init_gzip_stream(lpwhr); - } - - return lpwhr->dwContentLength; -} - /*********************************************************************** * HTTP_Tokenize (internal) * @@ -323,26 +146,21 @@ static LPWSTR * HTTP_Tokenize(LPCWSTR string, LPCWSTR token_string) int i; LPCWSTR next_token; - if (string) - { - /* empty string has no tokens */ - if (*string) - tokens++; - /* count tokens */ - for (i = 0; string[i]; i++) + /* empty string has no tokens */ + if (*string) + tokens++; + /* count tokens */ + for (i = 0; string[i]; i++) + if (!strncmpW(string+i, token_string, strlenW(token_string))) { - if (!strncmpW(string+i, token_string, strlenW(token_string))) - { - DWORD j; - tokens++; - /* we want to skip over separators, but not the null terminator */ - for (j = 0; j < strlenW(token_string) - 1; j++) - if (!string[i+j]) - break; - i += j; - } + DWORD j; + tokens++; + /* we want to skip over separators, but not the null terminator */ + for (j = 0; j < strlenW(token_string) - 1; j++) + if (!string[i+j]) + break; + i += j; } - } /* add 1 for terminating NULL */ token_array = HeapAlloc(GetProcessHeap(), 0, (tokens+1) * sizeof(*token_array)); @@ -384,7 +202,7 @@ static void HTTP_FreeTokens(LPWSTR * token_array) static void AsyncHttpSendRequestProc(WORKREQUEST *workRequest) { struct WORKREQ_HTTPSENDREQUESTW const *req = &workRequest->u.HttpSendRequestW; - http_request_t *lpwhr = (http_request_t*) workRequest->hdr; + LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) workRequest->hdr; TRACE("%p\n", lpwhr); @@ -395,14 +213,14 @@ static void AsyncHttpSendRequestProc(WORKREQUEST *workRequest) HeapFree(GetProcessHeap(), 0, req->lpszHeader); } -static void HTTP_FixURL(http_request_t *lpwhr) +static void HTTP_FixURL( LPWININETHTTPREQW lpwhr) { static const WCHAR szSlash[] = { '/',0 }; static const WCHAR szHttp[] = { 'h','t','t','p',':','/','/', 0 }; /* If we don't have a path we set it to root */ if (NULL == lpwhr->lpszPath) - lpwhr->lpszPath = heap_strdupW(szSlash); + lpwhr->lpszPath = WININET_strdupW(szSlash); else /* remove \r and \n*/ { int nLen = strlenW(lpwhr->lpszPath); @@ -431,7 +249,7 @@ static void HTTP_FixURL(http_request_t *lpwhr) } } -static LPWSTR HTTP_BuildHeaderRequestString( http_request_t *lpwhr, LPCWSTR verb, LPCWSTR path, LPCWSTR version ) +static LPWSTR HTTP_BuildHeaderRequestString( LPWININETHTTPREQW lpwhr, LPCWSTR verb, LPCWSTR path, LPCWSTR version ) { LPWSTR requestString; DWORD len, n; @@ -440,6 +258,7 @@ static LPWSTR HTTP_BuildHeaderRequestString( http_request_t *lpwhr, LPCWSTR verb LPWSTR p; static const WCHAR szSpace[] = { ' ',0 }; + static const WCHAR szcrlf[] = {'\r','\n', 0}; static const WCHAR szColon[] = { ':',' ',0 }; static const WCHAR sztwocrlf[] = {'\r','\n','\r','\n', 0}; @@ -460,7 +279,7 @@ static LPWSTR HTTP_BuildHeaderRequestString( http_request_t *lpwhr, LPCWSTR verb { if (lpwhr->pCustHeaders[i].wFlags & HDR_ISREQUEST) { - req[n++] = szCrLf; + req[n++] = szcrlf; req[n++] = lpwhr->pCustHeaders[i].lpszField; req[n++] = szColon; req[n++] = lpwhr->pCustHeaders[i].lpszValue; @@ -490,176 +309,103 @@ static LPWSTR HTTP_BuildHeaderRequestString( http_request_t *lpwhr, LPCWSTR verb return requestString; } -static void HTTP_ProcessCookies( http_request_t *lpwhr ) +static void HTTP_ProcessCookies( LPWININETHTTPREQW lpwhr ) { + static const WCHAR szSet_Cookie[] = { 'S','e','t','-','C','o','o','k','i','e',0 }; int HeaderIndex; - int numCookies = 0; LPHTTPHEADERW setCookieHeader; - while((HeaderIndex = HTTP_GetCustomHeaderIndex(lpwhr, szSet_Cookie, numCookies, FALSE)) != -1) - { - setCookieHeader = &lpwhr->pCustHeaders[HeaderIndex]; + HeaderIndex = HTTP_GetCustomHeaderIndex(lpwhr, szSet_Cookie, 0, FALSE); + if (HeaderIndex == -1) + return; + setCookieHeader = &lpwhr->pCustHeaders[HeaderIndex]; - if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES) && setCookieHeader->lpszValue) + if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES) && setCookieHeader->lpszValue) + { + int nPosStart = 0, nPosEnd = 0, len; + static const WCHAR szFmt[] = { 'h','t','t','p',':','/','/','%','s','/',0}; + + while (setCookieHeader->lpszValue[nPosEnd] != '\0') { - int len; - static const WCHAR szFmt[] = { 'h','t','t','p',':','/','/','%','s','%','s',0}; + LPWSTR buf_cookie, cookie_name, cookie_data; LPWSTR buf_url; + LPWSTR domain = NULL; LPHTTPHEADERW Host; - Host = HTTP_GetHeader(lpwhr, hostW); - len = lstrlenW(Host->lpszValue) + 9 + lstrlenW(lpwhr->lpszPath); + int nEqualPos = 0; + while (setCookieHeader->lpszValue[nPosEnd] != ';' && setCookieHeader->lpszValue[nPosEnd] != ',' && + setCookieHeader->lpszValue[nPosEnd] != '\0') + { + nPosEnd++; + } + if (setCookieHeader->lpszValue[nPosEnd] == ';') + { + /* fixme: not case sensitive, strcasestr is gnu only */ + int nDomainPosEnd = 0; + int nDomainPosStart = 0, nDomainLength = 0; + static const WCHAR szDomain[] = {'d','o','m','a','i','n','=',0}; + LPWSTR lpszDomain = strstrW(&setCookieHeader->lpszValue[nPosEnd], szDomain); + if (lpszDomain) + { /* they have specified their own domain, lets use it */ + while (lpszDomain[nDomainPosEnd] != ';' && lpszDomain[nDomainPosEnd] != ',' && + lpszDomain[nDomainPosEnd] != '\0') + { + nDomainPosEnd++; + } + nDomainPosStart = strlenW(szDomain); + nDomainLength = (nDomainPosEnd - nDomainPosStart) + 1; + domain = HeapAlloc(GetProcessHeap(), 0, (nDomainLength + 1)*sizeof(WCHAR)); + lstrcpynW(domain, &lpszDomain[nDomainPosStart], nDomainLength + 1); + } + } + if (setCookieHeader->lpszValue[nPosEnd] == '\0') break; + buf_cookie = HeapAlloc(GetProcessHeap(), 0, ((nPosEnd - nPosStart) + 1)*sizeof(WCHAR)); + lstrcpynW(buf_cookie, &setCookieHeader->lpszValue[nPosStart], (nPosEnd - nPosStart) + 1); + TRACE("%s\n", debugstr_w(buf_cookie)); + while (buf_cookie[nEqualPos] != '=' && buf_cookie[nEqualPos] != '\0') + { + nEqualPos++; + } + if (buf_cookie[nEqualPos] == '\0' || buf_cookie[nEqualPos + 1] == '\0') + { + HeapFree(GetProcessHeap(), 0, buf_cookie); + break; + } + + cookie_name = HeapAlloc(GetProcessHeap(), 0, (nEqualPos + 1)*sizeof(WCHAR)); + lstrcpynW(cookie_name, buf_cookie, nEqualPos + 1); + cookie_data = &buf_cookie[nEqualPos + 1]; + + Host = HTTP_GetHeader(lpwhr,szHost); + len = lstrlenW((domain ? domain : (Host?Host->lpszValue:NULL))) + + strlenW(lpwhr->lpszPath) + 9; buf_url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); - sprintfW(buf_url, szFmt, Host->lpszValue, lpwhr->lpszPath); - InternetSetCookieW(buf_url, NULL, setCookieHeader->lpszValue); + sprintfW(buf_url, szFmt, (domain ? domain : (Host?Host->lpszValue:NULL))); /* FIXME PATH!!! */ + InternetSetCookieW(buf_url, cookie_name, cookie_data); HeapFree(GetProcessHeap(), 0, buf_url); + HeapFree(GetProcessHeap(), 0, buf_cookie); + HeapFree(GetProcessHeap(), 0, cookie_name); + HeapFree(GetProcessHeap(), 0, domain); + nPosStart = nPosEnd; } - numCookies++; } } -static void strip_spaces(LPWSTR start) -{ - LPWSTR str = start; - LPWSTR end; - - while (*str == ' ' && *str != '\0') - str++; - - if (str != start) - memmove(start, str, sizeof(WCHAR) * (strlenW(str) + 1)); - - end = start + strlenW(start) - 1; - while (end >= start && *end == ' ') - { - *end = '\0'; - end--; - } -} - -static inline BOOL is_basic_auth_value( LPCWSTR pszAuthValue, LPWSTR *pszRealm ) +static inline BOOL is_basic_auth_value( LPCWSTR pszAuthValue ) { static const WCHAR szBasic[] = {'B','a','s','i','c'}; /* Note: not nul-terminated */ - static const WCHAR szRealm[] = {'r','e','a','l','m'}; /* Note: not nul-terminated */ - BOOL is_basic; - is_basic = !strncmpiW(pszAuthValue, szBasic, ARRAYSIZE(szBasic)) && + return !strncmpiW(pszAuthValue, szBasic, ARRAYSIZE(szBasic)) && ((pszAuthValue[ARRAYSIZE(szBasic)] == ' ') || !pszAuthValue[ARRAYSIZE(szBasic)]); - if (is_basic && pszRealm) - { - LPCWSTR token; - LPCWSTR ptr = &pszAuthValue[ARRAYSIZE(szBasic)]; - LPCWSTR realm; - ptr++; - *pszRealm=NULL; - token = strchrW(ptr,'='); - if (!token) - return TRUE; - realm = ptr; - while (*realm == ' ' && *realm != '\0') - realm++; - if(!strncmpiW(realm, szRealm, ARRAYSIZE(szRealm)) && - (realm[ARRAYSIZE(szRealm)] == ' ' || realm[ARRAYSIZE(szRealm)] == '=')) - { - token++; - while (*token == ' ' && *token != '\0') - token++; - if (*token == '\0') - return TRUE; - *pszRealm = heap_strdupW(token); - strip_spaces(*pszRealm); - } - } - - return is_basic; } -static void destroy_authinfo( struct HttpAuthInfo *authinfo ) -{ - if (!authinfo) return; - - if (SecIsValidHandle(&authinfo->ctx)) - DeleteSecurityContext(&authinfo->ctx); - if (SecIsValidHandle(&authinfo->cred)) - FreeCredentialsHandle(&authinfo->cred); - - HeapFree(GetProcessHeap(), 0, authinfo->auth_data); - HeapFree(GetProcessHeap(), 0, authinfo->scheme); - HeapFree(GetProcessHeap(), 0, authinfo); -} - -static UINT retrieve_cached_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR *auth_data) -{ - authorizationData *ad; - UINT rc = 0; - - TRACE("Looking for authorization for %s:%s\n",debugstr_w(host),debugstr_w(realm)); - - EnterCriticalSection(&authcache_cs); - LIST_FOR_EACH_ENTRY(ad, &basicAuthorizationCache, authorizationData, entry) - { - if (!strcmpiW(host,ad->lpszwHost) && !strcmpW(realm,ad->lpszwRealm)) - { - TRACE("Authorization found in cache\n"); - *auth_data = HeapAlloc(GetProcessHeap(),0,ad->AuthorizationLen); - memcpy(*auth_data,ad->lpszAuthorization,ad->AuthorizationLen); - rc = ad->AuthorizationLen; - break; - } - } - LeaveCriticalSection(&authcache_cs); - return rc; -} - -static void cache_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR auth_data, UINT auth_data_len) -{ - struct list *cursor; - authorizationData* ad = NULL; - - TRACE("caching authorization for %s:%s = %s\n",debugstr_w(host),debugstr_w(realm),debugstr_an(auth_data,auth_data_len)); - - EnterCriticalSection(&authcache_cs); - LIST_FOR_EACH(cursor, &basicAuthorizationCache) - { - authorizationData *check = LIST_ENTRY(cursor,authorizationData,entry); - if (!strcmpiW(host,check->lpszwHost) && !strcmpW(realm,check->lpszwRealm)) - { - ad = check; - break; - } - } - - if (ad) - { - TRACE("Found match in cache, replacing\n"); - HeapFree(GetProcessHeap(),0,ad->lpszAuthorization); - ad->lpszAuthorization = HeapAlloc(GetProcessHeap(),0,auth_data_len); - memcpy(ad->lpszAuthorization, auth_data, auth_data_len); - ad->AuthorizationLen = auth_data_len; - } - else - { - ad = HeapAlloc(GetProcessHeap(),0,sizeof(authorizationData)); - ad->lpszwHost = heap_strdupW(host); - ad->lpszwRealm = heap_strdupW(realm); - ad->lpszAuthorization = HeapAlloc(GetProcessHeap(),0,auth_data_len); - memcpy(ad->lpszAuthorization, auth_data, auth_data_len); - ad->AuthorizationLen = auth_data_len; - list_add_head(&basicAuthorizationCache,&ad->entry); - TRACE("authorization cached\n"); - } - LeaveCriticalSection(&authcache_cs); -} - -static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue, +static BOOL HTTP_DoAuthorization( LPWININETHTTPREQW lpwhr, LPCWSTR pszAuthValue, struct HttpAuthInfo **ppAuthInfo, - LPWSTR domain_and_username, LPWSTR password, - LPWSTR host ) + LPWSTR domain_and_username, LPWSTR password ) { SECURITY_STATUS sec_status; struct HttpAuthInfo *pAuthInfo = *ppAuthInfo; BOOL first = FALSE; - LPWSTR szRealm = NULL; TRACE("%s\n", debugstr_w(pszAuthValue)); @@ -680,10 +426,10 @@ static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue, pAuthInfo->auth_data_len = 0; pAuthInfo->finished = FALSE; - if (is_basic_auth_value(pszAuthValue,NULL)) + if (is_basic_auth_value(pszAuthValue)) { static const WCHAR szBasic[] = {'B','a','s','i','c',0}; - pAuthInfo->scheme = heap_strdupW(szBasic); + pAuthInfo->scheme = WININET_strdupW(szBasic); if (!pAuthInfo->scheme) { HeapFree(GetProcessHeap(), 0, pAuthInfo); @@ -695,7 +441,7 @@ static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue, PVOID pAuthData; SEC_WINNT_AUTH_IDENTITY_W nt_auth_identity; - pAuthInfo->scheme = heap_strdupW(pszAuthValue); + pAuthInfo->scheme = WININET_strdupW(pszAuthValue); if (!pAuthInfo->scheme) { HeapFree(GetProcessHeap(), 0, pAuthInfo); @@ -767,50 +513,33 @@ static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue, return FALSE; } - if (is_basic_auth_value(pszAuthValue,&szRealm)) + if (is_basic_auth_value(pszAuthValue)) { int userlen; int passlen; - char *auth_data = NULL; - UINT auth_data_len = 0; + char *auth_data; - TRACE("basic authentication realm %s\n",debugstr_w(szRealm)); + TRACE("basic authentication\n"); - if (!domain_and_username) - { - if (host && szRealm) - auth_data_len = retrieve_cached_basic_authorization(host, szRealm,&auth_data); - if (auth_data_len == 0) - { - HeapFree(GetProcessHeap(),0,szRealm); - return FALSE; - } - } - else - { - userlen = WideCharToMultiByte(CP_UTF8, 0, domain_and_username, lstrlenW(domain_and_username), NULL, 0, NULL, NULL); - passlen = WideCharToMultiByte(CP_UTF8, 0, password, lstrlenW(password), NULL, 0, NULL, NULL); + /* we don't cache credentials for basic authentication, so we can't + * retrieve them if the application didn't pass us any credentials */ + if (!domain_and_username) return FALSE; - /* length includes a nul terminator, which will be re-used for the ':' */ - auth_data = HeapAlloc(GetProcessHeap(), 0, userlen + 1 + passlen); - if (!auth_data) - { - HeapFree(GetProcessHeap(),0,szRealm); - return FALSE; - } + userlen = WideCharToMultiByte(CP_UTF8, 0, domain_and_username, lstrlenW(domain_and_username), NULL, 0, NULL, NULL); + passlen = WideCharToMultiByte(CP_UTF8, 0, password, lstrlenW(password), NULL, 0, NULL, NULL); - WideCharToMultiByte(CP_UTF8, 0, domain_and_username, -1, auth_data, userlen, NULL, NULL); - auth_data[userlen] = ':'; - WideCharToMultiByte(CP_UTF8, 0, password, -1, &auth_data[userlen+1], passlen, NULL, NULL); - auth_data_len = userlen + 1 + passlen; - if (host && szRealm) - cache_basic_authorization(host, szRealm, auth_data, auth_data_len); - } + /* length includes a nul terminator, which will be re-used for the ':' */ + auth_data = HeapAlloc(GetProcessHeap(), 0, userlen + 1 + passlen); + if (!auth_data) + return FALSE; + + WideCharToMultiByte(CP_UTF8, 0, domain_and_username, -1, auth_data, userlen, NULL, NULL); + auth_data[userlen] = ':'; + WideCharToMultiByte(CP_UTF8, 0, password, -1, &auth_data[userlen+1], passlen, NULL, NULL); pAuthInfo->auth_data = auth_data; - pAuthInfo->auth_data_len = auth_data_len; + pAuthInfo->auth_data_len = userlen + 1 + passlen; pAuthInfo->finished = TRUE; - HeapFree(GetProcessHeap(),0,szRealm); return TRUE; } @@ -873,9 +602,8 @@ static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue, else { ERR("InitializeSecurityContextW returned error 0x%08x\n", sec_status); + pAuthInfo->finished = TRUE; HeapFree(GetProcessHeap(), 0, out.pvBuffer); - destroy_authinfo(pAuthInfo); - *ppAuthInfo = NULL; return FALSE; } } @@ -886,7 +614,7 @@ static BOOL HTTP_DoAuthorization( http_request_t *lpwhr, LPCWSTR pszAuthValue, /*********************************************************************** * HTTP_HttpAddRequestHeadersW (internal) */ -static BOOL HTTP_HttpAddRequestHeadersW(http_request_t *lpwhr, +static BOOL WINAPI HTTP_HttpAddRequestHeadersW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier) { LPWSTR lpszStart; @@ -914,7 +642,7 @@ static BOOL HTTP_HttpAddRequestHeadersW(http_request_t *lpwhr, while (*lpszEnd != '\0') { - if (*lpszEnd == '\r' || *lpszEnd == '\n') + if (*lpszEnd == '\r' && *(lpszEnd + 1) == '\n') break; lpszEnd++; } @@ -922,19 +650,12 @@ static BOOL HTTP_HttpAddRequestHeadersW(http_request_t *lpwhr, if (*lpszStart == '\0') break; - if (*lpszEnd == '\r' || *lpszEnd == '\n') + if (*lpszEnd == '\r') { *lpszEnd = '\0'; - lpszEnd++; /* Jump over newline */ + lpszEnd += 2; /* Jump over \r\n */ } TRACE("interpreting header %s\n", debugstr_w(lpszStart)); - if (*lpszStart == '\0') - { - /* Skip 0-length headers */ - lpszStart = lpszEnd; - bSuccess = TRUE; - continue; - } pFieldAndValue = HTTP_InterpretHttpHeader(lpszStart); if (pFieldAndValue) { @@ -973,14 +694,14 @@ BOOL WINAPI HttpAddRequestHeadersW(HINTERNET hHttpRequest, LPCWSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier) { BOOL bSuccess = FALSE; - http_request_t *lpwhr; + LPWININETHTTPREQW lpwhr; TRACE("%p, %s, %i, %i\n", hHttpRequest, debugstr_wn(lpszHeader, dwHeaderLength), dwHeaderLength, dwModifier); if (!lpszHeader) return TRUE; - lpwhr = (http_request_t*) WININET_GetObject( hHttpRequest ); + lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hHttpRequest ); if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); @@ -1039,87 +760,57 @@ BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest, BOOL WINAPI HttpEndRequestA(HINTERNET hRequest, LPINTERNET_BUFFERSA lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext) { - TRACE("(%p, %p, %08x, %08lx)\n", hRequest, lpBuffersOut, dwFlags, dwContext); + LPINTERNET_BUFFERSA ptr; + LPINTERNET_BUFFERSW lpBuffersOutW,ptrW; + BOOL rc = FALSE; - if (lpBuffersOut) + TRACE("(%p, %p, %08x, %08lx): stub\n", hRequest, lpBuffersOut, dwFlags, + dwContext); + + ptr = lpBuffersOut; + if (ptr) + lpBuffersOutW = (LPINTERNET_BUFFERSW)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, sizeof(INTERNET_BUFFERSW)); + else + lpBuffersOutW = NULL; + + ptrW = lpBuffersOutW; + while (ptr) { - INTERNET_SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + if (ptr->lpvBuffer && ptr->dwBufferLength) + ptrW->lpvBuffer = HeapAlloc(GetProcessHeap(),0,ptr->dwBufferLength); + ptrW->dwBufferLength = ptr->dwBufferLength; + ptrW->dwBufferTotal= ptr->dwBufferTotal; + + if (ptr->Next) + ptrW->Next = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + sizeof(INTERNET_BUFFERSW)); + + ptr = ptr->Next; + ptrW = ptrW->Next; } - return HttpEndRequestW(hRequest, NULL, dwFlags, dwContext); -} + rc = HttpEndRequestW(hRequest, lpBuffersOutW, dwFlags, dwContext); -static BOOL HTTP_HttpEndRequestW(http_request_t *lpwhr, DWORD dwFlags, DWORD_PTR dwContext) -{ - BOOL rc = FALSE; - INT responseLen; - DWORD dwBufferSize; - INTERNET_ASYNC_RESULT iar; - - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); - - responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE); - if (responseLen) - rc = TRUE; - - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, sizeof(DWORD)); - - /* process cookies here. Is this right? */ - HTTP_ProcessCookies(lpwhr); - - if (!set_content_length( lpwhr )) HTTP_FinishedReading(lpwhr); - - if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT)) + if (lpBuffersOutW) { - DWORD dwCode,dwCodeLength = sizeof(DWORD); - if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, &dwCode, &dwCodeLength, NULL) && - (dwCode == 302 || dwCode == 301 || dwCode == 303)) + ptrW = lpBuffersOutW; + while (ptrW) { - WCHAR *new_url, szNewLocation[INTERNET_MAX_URL_LENGTH]; - dwBufferSize=sizeof(szNewLocation); - if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_LOCATION, szNewLocation, &dwBufferSize, NULL)) - { - if (strcmpW(lpwhr->lpszVerb, szGET) && strcmpW(lpwhr->lpszVerb, szHEAD)) - { - HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb); - lpwhr->lpszVerb = heap_strdupW(szGET); - } - HTTP_DrainContent(lpwhr); - if ((new_url = HTTP_GetRedirectURL( lpwhr, szNewLocation ))) - { - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_REDIRECT, - new_url, (strlenW(new_url) + 1) * sizeof(WCHAR)); - rc = HTTP_HandleRedirect(lpwhr, new_url); - if (rc) - rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE); - HeapFree( GetProcessHeap(), 0, new_url ); - } - } + LPINTERNET_BUFFERSW ptrW2; + + FIXME("Do we need to translate info out of these buffer?\n"); + + HeapFree(GetProcessHeap(),0,ptrW->lpvBuffer); + ptrW2 = ptrW->Next; + HeapFree(GetProcessHeap(),0,ptrW); + ptrW = ptrW2; } } - iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet; - iar.dwError = rc ? 0 : INTERNET_GetLastError(); - - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_REQUEST_COMPLETE, &iar, - sizeof(INTERNET_ASYNC_RESULT)); return rc; } -static void AsyncHttpEndRequestProc(WORKREQUEST *work) -{ - struct WORKREQ_HTTPENDREQUESTW const *req = &work->u.HttpEndRequestW; - http_request_t *lpwhr = (http_request_t*)work->hdr; - - TRACE("%p\n", lpwhr); - - HTTP_HttpEndRequestW(lpwhr, req->dwFlags, req->dwContext); -} - /*********************************************************************** * HttpEndRequestW (WININET.@) * @@ -1134,44 +825,70 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hRequest, LPINTERNET_BUFFERSW lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext) { BOOL rc = FALSE; - http_request_t *lpwhr; + LPWININETHTTPREQW lpwhr; + INT responseLen; + DWORD dwBufferSize; TRACE("-->\n"); - - if (lpBuffersOut) - { - INTERNET_SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - lpwhr = (http_request_t*) WININET_GetObject( hRequest ); + lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest ); if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); if (lpwhr) WININET_Release( &lpwhr->hdr ); - return FALSE; + return FALSE; } + lpwhr->hdr.dwFlags |= dwFlags; + lpwhr->hdr.dwContext = dwContext; - if (lpwhr->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) + /* We appear to do nothing with lpBuffersOut.. is that correct? */ + + SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); + + responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE); + if (responseLen) + rc = TRUE; + + SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, sizeof(DWORD)); + + /* process cookies here. Is this right? */ + HTTP_ProcessCookies(lpwhr); + + dwBufferSize = sizeof(lpwhr->dwContentLength); + if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, + &lpwhr->dwContentLength,&dwBufferSize,NULL)) + lpwhr->dwContentLength = -1; + + if (lpwhr->dwContentLength == 0) + HTTP_FinishedReading(lpwhr); + + if(!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT)) { - WORKREQUEST work; - struct WORKREQ_HTTPENDREQUESTW *request; - - work.asyncproc = AsyncHttpEndRequestProc; - work.hdr = WININET_AddRef( &lpwhr->hdr ); - - request = &work.u.HttpEndRequestW; - request->dwFlags = dwFlags; - request->dwContext = dwContext; - - INTERNET_AsyncCall(&work); - INTERNET_SetLastError(ERROR_IO_PENDING); + DWORD dwCode,dwCodeLength=sizeof(DWORD); + if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,NULL) && + (dwCode==302 || dwCode==301)) + { + WCHAR szNewLocation[INTERNET_MAX_URL_LENGTH]; + dwBufferSize=sizeof(szNewLocation); + if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL)) + { + /* redirects are always GETs */ + HeapFree(GetProcessHeap(),0,lpwhr->lpszVerb); + lpwhr->lpszVerb = WININET_strdupW(szGET); + HTTP_DrainContent(lpwhr); + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_REDIRECT, szNewLocation, + dwBufferSize); + rc = HTTP_HandleRedirect(lpwhr, szNewLocation); + if (rc) + rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE); + } + } } - else - rc = HTTP_HttpEndRequestW(lpwhr, dwFlags, dwContext); WININET_Release( &lpwhr->hdr ); TRACE("%i <--\n",rc); @@ -1193,7 +910,7 @@ HINTERNET WINAPI HttpOpenRequestW(HINTERNET hHttpSession, LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext) { - http_session_t *lpwhs; + LPWININETHTTPSESSIONW lpwhs; HINTERNET handle = NULL; TRACE("(%p, %s, %s, %s, %s, %p, %08x, %08lx)\n", hHttpSession, @@ -1207,7 +924,7 @@ HINTERNET WINAPI HttpOpenRequestW(HINTERNET hHttpSession, TRACE("\taccept type: %s\n",debugstr_w(lpszAcceptTypes[i])); } - lpwhs = (http_session_t*) WININET_GetObject( hHttpSession ); + lpwhs = (LPWININETHTTPSESSIONW) WININET_GetObject( hHttpSession ); if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); @@ -1249,7 +966,7 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession, { LPWSTR szVerb = NULL, szObjectName = NULL; LPWSTR szVersion = NULL, szReferrer = NULL, *szAcceptTypes = NULL; - INT acceptTypesCount; + INT len, acceptTypesCount; HINTERNET rc = FALSE; LPCSTR *types; @@ -1260,30 +977,38 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession, if (lpszVerb) { - szVerb = heap_strdupAtoW(lpszVerb); + len = MultiByteToWideChar(CP_ACP, 0, lpszVerb, -1, NULL, 0 ); + szVerb = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR) ); if ( !szVerb ) goto end; + MultiByteToWideChar(CP_ACP, 0, lpszVerb, -1, szVerb, len); } if (lpszObjectName) { - szObjectName = heap_strdupAtoW(lpszObjectName); + len = MultiByteToWideChar(CP_ACP, 0, lpszObjectName, -1, NULL, 0 ); + szObjectName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR) ); if ( !szObjectName ) goto end; + MultiByteToWideChar(CP_ACP, 0, lpszObjectName, -1, szObjectName, len ); } if (lpszVersion) { - szVersion = heap_strdupAtoW(lpszVersion); + len = MultiByteToWideChar(CP_ACP, 0, lpszVersion, -1, NULL, 0 ); + szVersion = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if ( !szVersion ) goto end; + MultiByteToWideChar(CP_ACP, 0, lpszVersion, -1, szVersion, len ); } if (lpszReferrer) { - szReferrer = heap_strdupAtoW(lpszReferrer); + len = MultiByteToWideChar(CP_ACP, 0, lpszReferrer, -1, NULL, 0 ); + szReferrer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if ( !szReferrer ) goto end; + MultiByteToWideChar(CP_ACP, 0, lpszReferrer, -1, szReferrer, len ); } if (lpszAcceptTypes) @@ -1292,20 +1017,12 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession, types = lpszAcceptTypes; while (*types) { - __TRY + /* find out how many there are */ + if (((ULONG_PTR)*types >> 16) && **types) { - /* find out how many there are */ - if (*types && **types) - { - TRACE("accept type: %s\n", debugstr_a(*types)); - acceptTypesCount++; - } + TRACE("accept type: %s\n", debugstr_a(*types)); + acceptTypesCount++; } - __EXCEPT_PAGE_FAULT - { - WARN("invalid accept type pointer\n"); - } - __ENDTRY; types++; } szAcceptTypes = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *) * (acceptTypesCount+1)); @@ -1315,20 +1032,20 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession, types = lpszAcceptTypes; while (*types) { - __TRY + if (((ULONG_PTR)*types >> 16) && **types) { - if (*types && **types) - szAcceptTypes[acceptTypesCount++] = heap_strdupAtoW(*types); + len = MultiByteToWideChar(CP_ACP, 0, *types, -1, NULL, 0 ); + szAcceptTypes[acceptTypesCount] = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (!szAcceptTypes[acceptTypesCount]) goto end; + + MultiByteToWideChar(CP_ACP, 0, *types, -1, szAcceptTypes[acceptTypesCount], len); + acceptTypesCount++; } - __EXCEPT_PAGE_FAULT - { - /* ignore invalid pointer */ - } - __ENDTRY; types++; } szAcceptTypes[acceptTypesCount] = NULL; } + else szAcceptTypes = 0; rc = HttpOpenRequestW(hHttpSession, szVerb, szObjectName, szVersion, szReferrer, @@ -1490,7 +1207,7 @@ static UINT HTTP_DecodeBase64( LPCWSTR base64, LPSTR bin ) * * Insert or delete the authorization field in the request header. */ -static BOOL HTTP_InsertAuthorization( http_request_t *lpwhr, struct HttpAuthInfo *pAuthInfo, LPCWSTR header ) +static BOOL HTTP_InsertAuthorization( LPWININETHTTPREQW lpwhr, struct HttpAuthInfo *pAuthInfo, LPCWSTR header ) { if (pAuthInfo) { @@ -1533,7 +1250,7 @@ static BOOL HTTP_InsertAuthorization( http_request_t *lpwhr, struct HttpAuthInfo return TRUE; } -static WCHAR *HTTP_BuildProxyRequestUrl(http_request_t *req) +static WCHAR *HTTP_BuildProxyRequestUrl(WININETHTTPREQW *req) { WCHAR new_location[INTERNET_MAX_URL_LENGTH], *url; DWORD size; @@ -1549,7 +1266,7 @@ static WCHAR *HTTP_BuildProxyRequestUrl(http_request_t *req) static const WCHAR slash[] = { '/',0 }; static const WCHAR format[] = { 'h','t','t','p',':','/','/','%','s',':','%','d',0 }; static const WCHAR formatSSL[] = { 'h','t','t','p','s',':','/','/','%','s',':','%','d',0 }; - http_session_t *session = req->lpHttpSession; + WININETHTTPSESSIONW *session = req->lpHttpSession; size = 16; /* "https://" + sizeof(port#) + ":/\0" */ size += strlenW( session->lpszHostName ) + strlenW( req->lpszPath ); @@ -1570,7 +1287,8 @@ static WCHAR *HTTP_BuildProxyRequestUrl(http_request_t *req) /*********************************************************************** * HTTP_DealWithProxy */ -static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *lpwhs, http_request_t *lpwhr) +static BOOL HTTP_DealWithProxy( LPWININETAPPINFOW hIC, + LPWININETHTTPSESSIONW lpwhs, LPWININETHTTPREQW lpwhr) { WCHAR buf[MAXHOSTNAME]; WCHAR proxy[MAXHOSTNAME + 15]; /* 15 == "http://" + sizeof(port#) + ":/\0" */ @@ -1601,50 +1319,32 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *lpwhs, http_reque UrlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT; HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName); - lpwhs->lpszServerName = heap_strdupW(UrlComponents.lpszHostName); + lpwhs->lpszServerName = WININET_strdupW(UrlComponents.lpszHostName); lpwhs->nServerPort = UrlComponents.nPort; TRACE("proxy server=%s port=%d\n", debugstr_w(lpwhs->lpszServerName), lpwhs->nServerPort); return TRUE; } -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN 46 -#endif - -static BOOL HTTP_ResolveName(http_request_t *lpwhr) +static BOOL HTTP_ResolveName(LPWININETHTTPREQW lpwhr) { - char szaddr[INET6_ADDRSTRLEN]; - http_session_t *lpwhs = lpwhr->lpHttpSession; - const void *addr; + char szaddr[32]; + LPWININETHTTPSESSIONW lpwhs = lpwhr->lpHttpSession; INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_RESOLVING_NAME, lpwhs->lpszServerName, strlenW(lpwhs->lpszServerName)+1); - lpwhs->sa_len = sizeof(lpwhs->socketAddress); if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort, - (struct sockaddr *)&lpwhs->socketAddress, &lpwhs->sa_len)) + &lpwhs->socketAddress)) { INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); return FALSE; } - switch (lpwhs->socketAddress.ss_family) - { - case AF_INET: - addr = &((struct sockaddr_in *)&lpwhs->socketAddress)->sin_addr; - break; - case AF_INET6: - addr = &((struct sockaddr_in6 *)&lpwhs->socketAddress)->sin6_addr; - break; - default: - WARN("unsupported family %d\n", lpwhs->socketAddress.ss_family); - INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); - return FALSE; - } - inet_ntop(lpwhs->socketAddress.ss_family, addr, szaddr, sizeof(szaddr)); + inet_ntop(lpwhs->socketAddress.sin_family, &lpwhs->socketAddress.sin_addr, + szaddr, sizeof(szaddr)); INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_NAME_RESOLVED, szaddr, strlen(szaddr)+1); @@ -1660,9 +1360,9 @@ static BOOL HTTP_ResolveName(http_request_t *lpwhr) * Deallocate request handle * */ -static void HTTPREQ_Destroy(object_header_t *hdr) +static void HTTPREQ_Destroy(WININETHANDLEHEADER *hdr) { - http_request_t *lpwhr = (http_request_t*) hdr; + LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) hdr; DWORD i; TRACE("\n"); @@ -1670,14 +1370,13 @@ static void HTTPREQ_Destroy(object_header_t *hdr) if(lpwhr->hCacheFile) CloseHandle(lpwhr->hCacheFile); - HeapFree(GetProcessHeap(), 0, lpwhr->lpszCacheFile); + if(lpwhr->lpszCacheFile) { + DeleteFileW(lpwhr->lpszCacheFile); /* FIXME */ + HeapFree(GetProcessHeap(), 0, lpwhr->lpszCacheFile); + } - DeleteCriticalSection( &lpwhr->read_section ); WININET_Release(&lpwhr->lpHttpSession->hdr); - destroy_authinfo(lpwhr->pAuthInfo); - destroy_authinfo(lpwhr->pProxyAuthInfo); - HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath); HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb); HeapFree(GetProcessHeap(), 0, lpwhr->lpszRawHeaders); @@ -1690,27 +1389,44 @@ static void HTTPREQ_Destroy(object_header_t *hdr) HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders[i].lpszValue); } -#ifdef HAVE_ZLIB - if(lpwhr->gzip_stream) { - if(!lpwhr->gzip_stream->end_of_data) - inflateEnd(&lpwhr->gzip_stream->zstream); - HeapFree(GetProcessHeap(), 0, lpwhr->gzip_stream); - } -#endif - HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders); HeapFree(GetProcessHeap(), 0, lpwhr); } -static void HTTPREQ_CloseConnection(object_header_t *hdr) +static void HTTPREQ_CloseConnection(WININETHANDLEHEADER *hdr) { - http_request_t *lpwhr = (http_request_t*) hdr; + LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) hdr; TRACE("%p\n",lpwhr); if (!NETCON_connected(&lpwhr->netConnection)) return; + if (lpwhr->pAuthInfo) + { + if (SecIsValidHandle(&lpwhr->pAuthInfo->ctx)) + DeleteSecurityContext(&lpwhr->pAuthInfo->ctx); + if (SecIsValidHandle(&lpwhr->pAuthInfo->cred)) + FreeCredentialsHandle(&lpwhr->pAuthInfo->cred); + + HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo->auth_data); + HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo->scheme); + HeapFree(GetProcessHeap(), 0, lpwhr->pAuthInfo); + lpwhr->pAuthInfo = NULL; + } + if (lpwhr->pProxyAuthInfo) + { + if (SecIsValidHandle(&lpwhr->pProxyAuthInfo->ctx)) + DeleteSecurityContext(&lpwhr->pProxyAuthInfo->ctx); + if (SecIsValidHandle(&lpwhr->pProxyAuthInfo->cred)) + FreeCredentialsHandle(&lpwhr->pProxyAuthInfo->cred); + + HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo->auth_data); + HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo->scheme); + HeapFree(GetProcessHeap(), 0, lpwhr->pProxyAuthInfo); + lpwhr->pProxyAuthInfo = NULL; + } + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_CLOSING_CONNECTION, 0, 0); @@ -1720,96 +1436,11 @@ static void HTTPREQ_CloseConnection(object_header_t *hdr) INTERNET_STATUS_CONNECTION_CLOSED, 0, 0); } -static BOOL HTTP_GetRequestURL(http_request_t *req, LPWSTR buf) +static DWORD HTTPREQ_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { - LPHTTPHEADERW host_header; - - static const WCHAR formatW[] = {'h','t','t','p',':','/','/','%','s','%','s',0}; - - host_header = HTTP_GetHeader(req, hostW); - if(!host_header) - return FALSE; - - sprintfW(buf, formatW, host_header->lpszValue, req->lpszPath); /* FIXME */ - return TRUE; -} - -static BOOL HTTP_KeepAlive(http_request_t *lpwhr) -{ - WCHAR szVersion[10]; - WCHAR szConnectionResponse[20]; - DWORD dwBufferSize = sizeof(szVersion); - BOOL keepalive = FALSE; - - /* as per RFC 2068, S8.1.2.1, if the client is HTTP/1.1 then assume that - * the connection is keep-alive by default */ - if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_VERSION, szVersion, - &dwBufferSize, NULL) && - !strcmpiW(szVersion, g_szHttp1_1)) - { - keepalive = TRUE; - } - - dwBufferSize = sizeof(szConnectionResponse); - if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_PROXY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) || - HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL)) - { - keepalive = !strcmpiW(szConnectionResponse, szKeepAlive); - } - - return keepalive; -} - -static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) -{ - http_request_t *req = (http_request_t*)hdr; + WININETHTTPREQW *req = (WININETHTTPREQW*)hdr; switch(option) { - case INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO: - { - http_session_t *lpwhs = req->lpHttpSession; - INTERNET_DIAGNOSTIC_SOCKET_INFO *info = buffer; - - FIXME("INTERNET_DIAGNOSTIC_SOCKET_INFO stub\n"); - - if (*size < sizeof(INTERNET_DIAGNOSTIC_SOCKET_INFO)) - return ERROR_INSUFFICIENT_BUFFER; - *size = sizeof(INTERNET_DIAGNOSTIC_SOCKET_INFO); - /* FIXME: can't get a SOCKET from our connection since we don't use - * winsock - */ - info->Socket = 0; - /* FIXME: get source port from req->netConnection */ - info->SourcePort = 0; - info->DestPort = lpwhs->nHostPort; - info->Flags = 0; - if (HTTP_KeepAlive(req)) - info->Flags |= IDSI_FLAG_KEEP_ALIVE; - if (lpwhs->lpAppInfo->lpszProxy && lpwhs->lpAppInfo->lpszProxy[0] != 0) - info->Flags |= IDSI_FLAG_PROXY; - if (req->netConnection.useSSL) - info->Flags |= IDSI_FLAG_SECURE; - - return ERROR_SUCCESS; - } - - case INTERNET_OPTION_SECURITY_FLAGS: - { - http_session_t *lpwhs; - lpwhs = req->lpHttpSession; - - if (*size < sizeof(ULONG)) - return ERROR_INSUFFICIENT_BUFFER; - - *size = sizeof(DWORD); - if (lpwhs->hdr.dwFlags & INTERNET_FLAG_SECURE) - *(DWORD*)buffer = SECURITY_FLAG_SECURE; - else - *(DWORD*)buffer = 0; - FIXME("Semi-STUB INTERNET_OPTION_SECURITY_FLAGS: %x\n",*(DWORD*)buffer); - return ERROR_SUCCESS; - } - case INTERNET_OPTION_HANDLE_TYPE: TRACE("INTERNET_OPTION_HANDLE_TYPE\n"); @@ -1827,6 +1458,7 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe WCHAR *pch; static const WCHAR httpW[] = {'h','t','t','p',':','/','/',0}; + static const WCHAR hostW[] = {'H','o','s','t',0}; TRACE("INTERNET_OPTION_URL\n"); @@ -1857,41 +1489,6 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe } } - case INTERNET_OPTION_CACHE_TIMESTAMPS: { - INTERNET_CACHE_ENTRY_INFOW *info; - INTERNET_CACHE_TIMESTAMPS *ts = buffer; - WCHAR url[INTERNET_MAX_URL_LENGTH]; - DWORD nbytes, error; - BOOL ret; - - TRACE("INTERNET_OPTION_CACHE_TIMESTAMPS\n"); - - if (*size < sizeof(*ts)) - { - *size = sizeof(*ts); - return ERROR_INSUFFICIENT_BUFFER; - } - nbytes = 0; - HTTP_GetRequestURL(req, url); - ret = GetUrlCacheEntryInfoW(url, NULL, &nbytes); - error = GetLastError(); - if (!ret && error == ERROR_INSUFFICIENT_BUFFER) - { - if (!(info = HeapAlloc(GetProcessHeap(), 0, nbytes))) - return ERROR_OUTOFMEMORY; - - GetUrlCacheEntryInfoW(url, info, &nbytes); - - ts->ftExpires = info->ExpireTime; - ts->ftLastModified = info->LastModifiedTime; - - HeapFree(GetProcessHeap(), 0, info); - *size = sizeof(*ts); - return ERROR_SUCCESS; - } - return error; - } - case INTERNET_OPTION_DATAFILE_NAME: { DWORD req_size; @@ -1987,9 +1584,9 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe return INET_QueryOption(option, buffer, size, unicode); } -static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer, DWORD size) +static DWORD HTTPREQ_SetOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD size) { - http_request_t *req = (http_request_t*)hdr; + WININETHTTPREQW *req = (WININETHTTPREQW*)hdr; switch(option) { case INTERNET_OPTION_SEND_TIMEOUT: @@ -2001,330 +1598,30 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer, return NETCON_set_timeout(&req->netConnection, option == INTERNET_OPTION_SEND_TIMEOUT, *(DWORD*)buffer); - - case INTERNET_OPTION_USERNAME: - HeapFree(GetProcessHeap(), 0, req->lpHttpSession->lpszUserName); - if (!(req->lpHttpSession->lpszUserName = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; - return ERROR_SUCCESS; - - case INTERNET_OPTION_PASSWORD: - HeapFree(GetProcessHeap(), 0, req->lpHttpSession->lpszPassword); - if (!(req->lpHttpSession->lpszPassword = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; - return ERROR_SUCCESS; - case INTERNET_OPTION_HTTP_DECODING: - if(size != sizeof(BOOL)) - return ERROR_INVALID_PARAMETER; - req->decoding = *(BOOL*)buffer; - return ERROR_SUCCESS; } return ERROR_INTERNET_INVALID_OPTION; } -/* read some more data into the read buffer (the read section must be held) */ -static BOOL read_more_data( http_request_t *req, int maxlen ) +static DWORD HTTP_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync) { - int len; + int bytes_read; - if (req->read_pos) - { - /* move existing data to the start of the buffer */ - if(req->read_size) - memmove( req->read_buf, req->read_buf + req->read_pos, req->read_size ); - req->read_pos = 0; + if(!NETCON_recv(&req->netConnection, buffer, min(size, req->dwContentLength - req->dwContentRead), + sync ? MSG_WAITALL : 0, &bytes_read)) { + if(req->dwContentLength != -1 && req->dwContentRead != req->dwContentLength) + ERR("not all data received %d/%d\n", req->dwContentRead, req->dwContentLength); + + /* always return success, even if the network layer returns an error */ + *read = 0; + HTTP_FinishedReading(req); + return ERROR_SUCCESS; } - if (maxlen == -1) maxlen = sizeof(req->read_buf); - - if(!NETCON_recv( &req->netConnection, req->read_buf + req->read_size, - maxlen - req->read_size, 0, &len )) - return FALSE; - - req->read_size += len; - return TRUE; -} - -/* remove some amount of data from the read buffer (the read section must be held) */ -static void remove_data( http_request_t *req, int count ) -{ - if (!(req->read_size -= count)) req->read_pos = 0; - else req->read_pos += count; -} - -static BOOL read_line( http_request_t *req, LPSTR buffer, DWORD *len ) -{ - int count, bytes_read, pos = 0; - - EnterCriticalSection( &req->read_section ); - for (;;) - { - BYTE *eol = memchr( req->read_buf + req->read_pos, '\n', req->read_size ); - - if (eol) - { - count = eol - (req->read_buf + req->read_pos); - bytes_read = count + 1; - } - else count = bytes_read = req->read_size; - - count = min( count, *len - pos ); - memcpy( buffer + pos, req->read_buf + req->read_pos, count ); - pos += count; - remove_data( req, bytes_read ); - if (eol) break; - - if (!read_more_data( req, -1 ) || !req->read_size) - { - *len = 0; - TRACE( "returning empty string\n" ); - LeaveCriticalSection( &req->read_section ); - return FALSE; - } - } - LeaveCriticalSection( &req->read_section ); - - if (pos < *len) - { - if (pos && buffer[pos - 1] == '\r') pos--; - *len = pos + 1; - } - buffer[*len - 1] = 0; - TRACE( "returning %s\n", debugstr_a(buffer)); - return TRUE; -} - -/* discard data contents until we reach end of line (the read section must be held) */ -static BOOL discard_eol( http_request_t *req ) -{ - do - { - BYTE *eol = memchr( req->read_buf + req->read_pos, '\n', req->read_size ); - if (eol) - { - remove_data( req, (eol + 1) - (req->read_buf + req->read_pos) ); - break; - } - req->read_pos = req->read_size = 0; /* discard everything */ - if (!read_more_data( req, -1 )) return FALSE; - } while (req->read_size); - return TRUE; -} - -/* read the size of the next chunk (the read section must be held) */ -static BOOL start_next_chunk( http_request_t *req ) -{ - DWORD chunk_size = 0; - - if (!req->dwContentLength) return TRUE; - if (req->dwContentLength == req->dwContentRead) - { - /* read terminator for the previous chunk */ - if (!discard_eol( req )) return FALSE; - req->dwContentLength = ~0u; - req->dwContentRead = 0; - } - for (;;) - { - while (req->read_size) - { - char ch = req->read_buf[req->read_pos]; - if (ch >= '0' && ch <= '9') chunk_size = chunk_size * 16 + ch - '0'; - else if (ch >= 'a' && ch <= 'f') chunk_size = chunk_size * 16 + ch - 'a' + 10; - else if (ch >= 'A' && ch <= 'F') chunk_size = chunk_size * 16 + ch - 'A' + 10; - else if (ch == ';' || ch == '\r' || ch == '\n') - { - TRACE( "reading %u byte chunk\n", chunk_size ); - req->dwContentLength = chunk_size; - req->dwContentRead = 0; - if (!discard_eol( req )) return FALSE; - return TRUE; - } - remove_data( req, 1 ); - } - if (!read_more_data( req, -1 )) return FALSE; - if (!req->read_size) - { - req->dwContentLength = req->dwContentRead = 0; - return TRUE; - } - } -} - -/* check if we have reached the end of the data to read (the read section must be held) */ -static BOOL end_of_read_data( http_request_t *req ) -{ - if (req->gzip_stream) return req->gzip_stream->end_of_data && !req->gzip_stream->buf_size; - if (req->read_chunked) return (req->dwContentLength == 0); - if (req->dwContentLength == ~0u) return FALSE; - return (req->dwContentLength == req->dwContentRead); -} - -/* fetch some more data into the read buffer (the read section must be held) */ -static BOOL refill_buffer( http_request_t *req ) -{ - int len = sizeof(req->read_buf); - - if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead)) - { - if (!start_next_chunk( req )) return FALSE; - } - - if (req->dwContentLength != ~0u) len = min( len, req->dwContentLength - req->dwContentRead ); - if (len <= req->read_size) return TRUE; - - if (!read_more_data( req, len )) return FALSE; - if (!req->read_size) req->dwContentLength = req->dwContentRead = 0; - return TRUE; -} - -static DWORD read_gzip_data(http_request_t *req, BYTE *buf, int size, BOOL sync, int *read_ret) -{ - DWORD ret = ERROR_SUCCESS; - int read = 0; - -#ifdef HAVE_ZLIB - z_stream *zstream = &req->gzip_stream->zstream; - int zres; - - while(read < size && !req->gzip_stream->end_of_data) { - if(!req->read_size) { - if(!sync || !refill_buffer(req)) - break; - } - - zstream->next_in = req->read_buf+req->read_pos; - zstream->avail_in = req->read_size; - zstream->next_out = buf+read; - zstream->avail_out = size-read; - zres = inflate(zstream, Z_FULL_FLUSH); - read = size - zstream->avail_out; - remove_data(req, req->read_size-zstream->avail_in); - if(zres == Z_STREAM_END) { - TRACE("end of data\n"); - req->gzip_stream->end_of_data = TRUE; - inflateEnd(&req->gzip_stream->zstream); - }else if(zres != Z_OK) { - WARN("inflate failed %d\n", zres); - if(!read) - ret = ERROR_INTERNET_DECODING_FAILED; - break; - } - } -#endif - - *read_ret = read; - return ret; -} - -static void refill_gzip_buffer(http_request_t *req) -{ - DWORD res; - int len; - - if(!req->gzip_stream || !req->read_size || req->gzip_stream->buf_size == sizeof(req->gzip_stream->buf)) - return; - - if(req->gzip_stream->buf_pos) { - if(req->gzip_stream->buf_size) - memmove(req->gzip_stream->buf, req->gzip_stream->buf + req->gzip_stream->buf_pos, req->gzip_stream->buf_size); - req->gzip_stream->buf_pos = 0; - } - - res = read_gzip_data(req, req->gzip_stream->buf + req->gzip_stream->buf_size, - sizeof(req->gzip_stream->buf) - req->gzip_stream->buf_size, FALSE, &len); - if(res == ERROR_SUCCESS) - req->gzip_stream->buf_size += len; -} - -/* return the size of data available to be read immediately (the read section must be held) */ -static DWORD get_avail_data( http_request_t *req ) -{ - if (req->gzip_stream) { - refill_gzip_buffer(req); - return req->gzip_stream->buf_size; - } - if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead)) - return 0; - return min( req->read_size, req->dwContentLength - req->dwContentRead ); -} - -static void HTTP_ReceiveRequestData(http_request_t *req, BOOL first_notif) -{ - INTERNET_ASYNC_RESULT iar; - - TRACE("%p\n", req); - - EnterCriticalSection( &req->read_section ); - if (refill_buffer( req )) { - iar.dwResult = (DWORD_PTR)req->hdr.hInternet; - iar.dwError = first_notif ? 0 : get_avail_data(req); - }else { - iar.dwResult = 0; - iar.dwError = INTERNET_GetLastError(); - } - LeaveCriticalSection( &req->read_section ); - - INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar, - sizeof(INTERNET_ASYNC_RESULT)); -} - -/* read data from the http connection (the read section must be held) */ -static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *read, BOOL sync) -{ - BOOL finished_reading = FALSE; - int len, bytes_read = 0; - DWORD ret = ERROR_SUCCESS; - - EnterCriticalSection( &req->read_section ); - - if (req->read_chunked && (req->dwContentLength == ~0u || req->dwContentLength == req->dwContentRead)) - { - if (!start_next_chunk( req )) goto done; - } - - if(req->gzip_stream) { - if(req->gzip_stream->buf_size) { - bytes_read = min(req->gzip_stream->buf_size, size); - memcpy(buffer, req->gzip_stream->buf + req->gzip_stream->buf_pos, bytes_read); - req->gzip_stream->buf_pos += bytes_read; - req->gzip_stream->buf_size -= bytes_read; - }else if(!req->read_size && !req->gzip_stream->end_of_data) { - refill_buffer(req); - } - - if(size > bytes_read) { - ret = read_gzip_data(req, (BYTE*)buffer+bytes_read, size-bytes_read, sync, &len); - if(ret == ERROR_SUCCESS) - bytes_read += len; - } - - finished_reading = req->gzip_stream->end_of_data && !req->gzip_stream->buf_size; - }else { - if (req->dwContentLength != ~0u) size = min( size, req->dwContentLength - req->dwContentRead ); - - if (req->read_size) { - bytes_read = min( req->read_size, size ); - memcpy( buffer, req->read_buf + req->read_pos, bytes_read ); - remove_data( req, bytes_read ); - } - - if (size > bytes_read && (!bytes_read || sync)) { - if (NETCON_recv( &req->netConnection, (char *)buffer + bytes_read, size - bytes_read, - sync ? MSG_WAITALL : 0, &len)) - bytes_read += len; - /* always return success, even if the network layer returns an error */ - } - - finished_reading = !bytes_read && req->dwContentRead == req->dwContentLength; - } -done: req->dwContentRead += bytes_read; *read = bytes_read; - TRACE( "retrieved %u bytes (%u/%u)\n", bytes_read, req->dwContentRead, req->dwContentLength ); - LeaveCriticalSection( &req->read_section ); - - if(ret == ERROR_SUCCESS && req->lpszCacheFile) { + if(req->lpszCacheFile) { BOOL res; DWORD dwBytesWritten; @@ -2333,23 +1630,119 @@ done: WARN("WriteFile failed: %u\n", GetLastError()); } - if(finished_reading) + if(!bytes_read && (req->dwContentRead == req->dwContentLength)) HTTP_FinishedReading(req); - return ret; + return ERROR_SUCCESS; } - -static DWORD HTTPREQ_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DWORD *read) +static DWORD get_chunk_size(const char *buffer) { - http_request_t *req = (http_request_t*)hdr; + const char *p; + DWORD size = 0; + + for (p = buffer; *p; p++) + { + if (*p >= '0' && *p <= '9') size = size * 16 + *p - '0'; + else if (*p >= 'a' && *p <= 'f') size = size * 16 + *p - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') size = size * 16 + *p - 'A' + 10; + else if (*p == ';') break; + } + return size; +} + +static DWORD HTTP_ReadChunked(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync) +{ + char reply[MAX_REPLY_LEN], *p = buffer; + DWORD buflen, to_read, to_write = size; + int bytes_read; + + *read = 0; + for (;;) + { + if (*read == size) break; + + if (req->dwContentLength == ~0UL) /* new chunk */ + { + buflen = sizeof(reply); + if (!NETCON_getNextLine(&req->netConnection, reply, &buflen)) break; + + if (!(req->dwContentLength = get_chunk_size(reply))) + { + /* zero sized chunk marks end of transfer; read any trailing headers and return */ + HTTP_GetResponseHeaders(req, FALSE); + break; + } + } + to_read = min(to_write, req->dwContentLength - req->dwContentRead); + + if (!NETCON_recv(&req->netConnection, p, to_read, sync ? MSG_WAITALL : 0, &bytes_read)) + { + if (bytes_read != to_read) + ERR("Not all data received %d/%d\n", bytes_read, to_read); + + /* always return success, even if the network layer returns an error */ + *read = 0; + break; + } + if (!bytes_read) break; + + req->dwContentRead += bytes_read; + to_write -= bytes_read; + *read += bytes_read; + + if (req->lpszCacheFile) + { + DWORD dwBytesWritten; + + if (!WriteFile(req->hCacheFile, p, bytes_read, &dwBytesWritten, NULL)) + WARN("WriteFile failed: %u\n", GetLastError()); + } + p += bytes_read; + + if (req->dwContentRead == req->dwContentLength) /* chunk complete */ + { + req->dwContentRead = 0; + req->dwContentLength = ~0UL; + + buflen = sizeof(reply); + if (!NETCON_getNextLine(&req->netConnection, reply, &buflen)) + { + ERR("Malformed chunk\n"); + *read = 0; + break; + } + } + } + if (!*read) HTTP_FinishedReading(req); + return ERROR_SUCCESS; +} + +static DWORD HTTPREQ_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD *read, BOOL sync) +{ + WCHAR encoding[20]; + DWORD buflen = sizeof(encoding); + static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0}; + + if (HTTP_HttpQueryInfoW(req, HTTP_QUERY_TRANSFER_ENCODING, encoding, &buflen, NULL) && + !strcmpiW(encoding, szChunked)) + { + return HTTP_ReadChunked(req, buffer, size, read, sync); + } + else + return HTTP_Read(req, buffer, size, read, sync); +} + +static DWORD HTTPREQ_ReadFile(WININETHANDLEHEADER *hdr, void *buffer, DWORD size, DWORD *read) +{ + WININETHTTPREQW *req = (WININETHTTPREQW*)hdr; return HTTPREQ_Read(req, buffer, size, read, TRUE); } -static void HTTPREQ_AsyncReadFileExAProc(WORKREQUEST *workRequest) +static void HTTPREQ_AsyncReadFileExProc(WORKREQUEST *workRequest) { struct WORKREQ_INTERNETREADFILEEXA const *data = &workRequest->u.InternetReadFileExA; - http_request_t *req = (http_request_t*)workRequest->hdr; + WININETHTTPREQW *req = (WININETHTTPREQW*)workRequest->hdr; INTERNET_ASYNC_RESULT iar; DWORD res; @@ -2366,10 +1759,11 @@ static void HTTPREQ_AsyncReadFileExAProc(WORKREQUEST *workRequest) sizeof(INTERNET_ASYNC_RESULT)); } -static DWORD HTTPREQ_ReadFileExA(object_header_t *hdr, INTERNET_BUFFERSA *buffers, +static DWORD HTTPREQ_ReadFileExA(WININETHANDLEHEADER *hdr, INTERNET_BUFFERSA *buffers, DWORD flags, DWORD_PTR context) { - http_request_t *req = (http_request_t*)hdr; + + WININETHTTPREQW *req = (WININETHTTPREQW*)hdr; DWORD res; if (flags & ~(IRF_ASYNC|IRF_NO_WAIT)) @@ -2380,35 +1774,27 @@ static DWORD HTTPREQ_ReadFileExA(object_header_t *hdr, INTERNET_BUFFERSA *buffer INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); - if ((hdr->dwFlags & INTERNET_FLAG_ASYNC) && !get_avail_data(req)) - { - WORKREQUEST workRequest; + if (hdr->dwFlags & INTERNET_FLAG_ASYNC) { + DWORD available = 0; - if (TryEnterCriticalSection( &req->read_section )) + NETCON_query_data_available(&req->netConnection, &available); + if (!available) { - if (get_avail_data(req)) - { - res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength, - &buffers->dwBufferLength, FALSE); - LeaveCriticalSection( &req->read_section ); - goto done; - } - LeaveCriticalSection( &req->read_section ); + WORKREQUEST workRequest; + + workRequest.asyncproc = HTTPREQ_AsyncReadFileExProc; + workRequest.hdr = WININET_AddRef(&req->hdr); + workRequest.u.InternetReadFileExA.lpBuffersOut = buffers; + + INTERNET_AsyncCall(&workRequest); + + return ERROR_IO_PENDING; } - - workRequest.asyncproc = HTTPREQ_AsyncReadFileExAProc; - workRequest.hdr = WININET_AddRef(&req->hdr); - workRequest.u.InternetReadFileExA.lpBuffersOut = buffers; - - INTERNET_AsyncCall(&workRequest); - - return ERROR_IO_PENDING; } res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength, !(flags & IRF_NO_WAIT)); -done: if (res == ERROR_SUCCESS) { DWORD size = buffers->dwBufferLength; INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED, @@ -2418,119 +1804,52 @@ done: return res; } -static void HTTPREQ_AsyncReadFileExWProc(WORKREQUEST *workRequest) +static BOOL HTTPREQ_WriteFile(WININETHANDLEHEADER *hdr, const void *buffer, DWORD size, DWORD *written) { - struct WORKREQ_INTERNETREADFILEEXW const *data = &workRequest->u.InternetReadFileExW; - http_request_t *req = (http_request_t*)workRequest->hdr; - INTERNET_ASYNC_RESULT iar; - DWORD res; + LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW)hdr; - TRACE("INTERNETREADFILEEXW %p\n", workRequest->hdr); - - res = HTTPREQ_Read(req, data->lpBuffersOut->lpvBuffer, - data->lpBuffersOut->dwBufferLength, &data->lpBuffersOut->dwBufferLength, TRUE); - - iar.dwResult = res == ERROR_SUCCESS; - iar.dwError = res; - - INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, - INTERNET_STATUS_REQUEST_COMPLETE, &iar, - sizeof(INTERNET_ASYNC_RESULT)); -} - -static DWORD HTTPREQ_ReadFileExW(object_header_t *hdr, INTERNET_BUFFERSW *buffers, - DWORD flags, DWORD_PTR context) -{ - - http_request_t *req = (http_request_t*)hdr; - DWORD res; - - if (flags & ~(IRF_ASYNC|IRF_NO_WAIT)) - FIXME("these dwFlags aren't implemented: 0x%x\n", flags & ~(IRF_ASYNC|IRF_NO_WAIT)); - - if (buffers->dwStructSize != sizeof(*buffers)) - return ERROR_INVALID_PARAMETER; - - INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); - - if (hdr->dwFlags & INTERNET_FLAG_ASYNC) - { - WORKREQUEST workRequest; - - if (TryEnterCriticalSection( &req->read_section )) - { - if (get_avail_data(req)) - { - res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength, - &buffers->dwBufferLength, FALSE); - LeaveCriticalSection( &req->read_section ); - goto done; - } - LeaveCriticalSection( &req->read_section ); - } - - workRequest.asyncproc = HTTPREQ_AsyncReadFileExWProc; - workRequest.hdr = WININET_AddRef(&req->hdr); - workRequest.u.InternetReadFileExW.lpBuffersOut = buffers; - - INTERNET_AsyncCall(&workRequest); - - return ERROR_IO_PENDING; - } - - res = HTTPREQ_Read(req, buffers->lpvBuffer, buffers->dwBufferLength, &buffers->dwBufferLength, - !(flags & IRF_NO_WAIT)); - -done: - if (res == ERROR_SUCCESS) { - DWORD size = buffers->dwBufferLength; - INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED, - &size, sizeof(size)); - } - - return res; -} - -static BOOL HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD size, DWORD *written) -{ - BOOL ret; - http_request_t *lpwhr = (http_request_t*)hdr; - - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_SENDING_REQUEST, NULL, 0); - - *written = 0; - if ((ret = NETCON_send(&lpwhr->netConnection, buffer, size, 0, (LPINT)written))) - lpwhr->dwBytesWritten += *written; - - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_REQUEST_SENT, written, sizeof(DWORD)); - return ret; + return NETCON_send(&lpwhr->netConnection, buffer, size, 0, (LPINT)written); } static void HTTPREQ_AsyncQueryDataAvailableProc(WORKREQUEST *workRequest) { - http_request_t *req = (http_request_t*)workRequest->hdr; + WININETHTTPREQW *req = (WININETHTTPREQW*)workRequest->hdr; + INTERNET_ASYNC_RESULT iar; + char buffer[4048]; - HTTP_ReceiveRequestData(req, FALSE); + TRACE("%p\n", workRequest->hdr); + + iar.dwResult = NETCON_recv(&req->netConnection, buffer, + min(sizeof(buffer), req->dwContentLength - req->dwContentRead), + MSG_PEEK, (int *)&iar.dwError); + + INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_REQUEST_COMPLETE, &iar, + sizeof(INTERNET_ASYNC_RESULT)); } -static DWORD HTTPREQ_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx) +static DWORD HTTPREQ_QueryDataAvailable(WININETHANDLEHEADER *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx) { - http_request_t *req = (http_request_t*)hdr; + WININETHTTPREQW *req = (WININETHTTPREQW*)hdr; + BYTE buffer[4048]; + BOOL async; TRACE("(%p %p %x %lx)\n", req, available, flags, ctx); - if (req->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) + if(!NETCON_query_data_available(&req->netConnection, available) || *available) + return ERROR_SUCCESS; + + /* Even if we are in async mode, we need to determine whether + * there is actually more data available. We do this by trying + * to peek only a single byte in async mode. */ + async = (req->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) != 0; + + if (NETCON_recv(&req->netConnection, buffer, + min(async ? 1 : sizeof(buffer), req->dwContentLength - req->dwContentRead), + MSG_PEEK, (int *)available) && async && *available) { WORKREQUEST workRequest; - /* never wait, if we can't enter the section we queue an async request right away */ - if (TryEnterCriticalSection( &req->read_section )) - { - if ((*available = get_avail_data( req ))) goto done; - if (end_of_read_data( req )) goto done; - LeaveCriticalSection( &req->read_section ); - } - + *available = 0; workRequest.asyncproc = HTTPREQ_AsyncQueryDataAvailableProc; workRequest.hdr = WININET_AddRef( &req->hdr ); @@ -2539,35 +1858,16 @@ static DWORD HTTPREQ_QueryDataAvailable(object_header_t *hdr, DWORD *available, return ERROR_IO_PENDING; } - EnterCriticalSection( &req->read_section ); - - if (!(*available = get_avail_data( req )) && !end_of_read_data( req )) - { - refill_buffer( req ); - *available = get_avail_data( req ); - } - -done: - if (*available == sizeof(req->read_buf) && !req->gzip_stream) /* check if we have even more pending in the socket */ - { - DWORD extra; - if (NETCON_query_data_available(&req->netConnection, &extra)) - *available = min( *available + extra, req->dwContentLength - req->dwContentRead ); - } - LeaveCriticalSection( &req->read_section ); - - TRACE( "returning %u\n", *available ); return ERROR_SUCCESS; } -static const object_vtbl_t HTTPREQVtbl = { +static const HANDLEHEADERVtbl HTTPREQVtbl = { HTTPREQ_Destroy, HTTPREQ_CloseConnection, HTTPREQ_QueryOption, HTTPREQ_SetOption, HTTPREQ_ReadFile, HTTPREQ_ReadFileExA, - HTTPREQ_ReadFileExW, HTTPREQ_WriteFile, HTTPREQ_QueryDataAvailable, NULL @@ -2583,13 +1883,13 @@ static const object_vtbl_t HTTPREQVtbl = { * NULL on failure * */ -HINTERNET WINAPI HTTP_HttpOpenRequestW(http_session_t *lpwhs, +HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs, LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext) { - appinfo_t *hIC = NULL; - http_request_t *lpwhr; + LPWININETAPPINFOW hIC = NULL; + LPWININETHTTPREQW lpwhr; LPWSTR lpszHostName = NULL; HINTERNET handle = NULL; static const WCHAR szHostForm[] = {'%','s',':','%','u',0}; @@ -2600,7 +1900,7 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(http_session_t *lpwhs, assert( lpwhs->hdr.htype == WH_HHTTPSESSION ); hIC = lpwhs->lpAppInfo; - lpwhr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(http_request_t)); + lpwhr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETHTTPREQW)); if (NULL == lpwhr) { INTERNET_SetLastError(ERROR_OUTOFMEMORY); @@ -2613,8 +1913,6 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(http_session_t *lpwhs, lpwhr->hdr.refs = 1; lpwhr->hdr.lpfnStatusCB = lpwhs->hdr.lpfnStatusCB; lpwhr->hdr.dwInternalFlags = lpwhs->hdr.dwInternalFlags & INET_CALLBACKW; - lpwhr->dwContentLength = ~0u; - InitializeCriticalSection( &lpwhr->read_section ); WININET_AddRef( &lpwhs->hdr ); lpwhr->lpHttpSession = lpwhs; @@ -2652,15 +1950,11 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(http_session_t *lpwhs, lpwhr->lpszPath = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); rc = UrlEscapeW(lpszObjectName, lpwhr->lpszPath, &len, URL_ESCAPE_SPACES_ONLY); - if (rc != S_OK) + if (rc) { ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(lpszObjectName),rc); strcpyW(lpwhr->lpszPath,lpszObjectName); } - }else { - static const WCHAR slashW[] = {'/',0}; - - lpwhr->lpszPath = heap_strdupW(slashW); } if (lpszReferrer && *lpszReferrer) @@ -2679,19 +1973,23 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(http_session_t *lpwhs, } } - lpwhr->lpszVerb = heap_strdupW(lpszVerb && *lpszVerb ? lpszVerb : szGET); - lpwhr->lpszVersion = heap_strdupW(lpszVersion ? lpszVersion : g_szHttp1_1); + lpwhr->lpszVerb = WININET_strdupW(lpszVerb && *lpszVerb ? lpszVerb : szGET); + + if (lpszVersion) + lpwhr->lpszVersion = WININET_strdupW(lpszVersion); + else + lpwhr->lpszVersion = WININET_strdupW(g_szHttp1_1); if (lpwhs->nHostPort != INTERNET_INVALID_PORT_NUMBER && lpwhs->nHostPort != INTERNET_DEFAULT_HTTP_PORT && lpwhs->nHostPort != INTERNET_DEFAULT_HTTPS_PORT) { sprintfW(lpszHostName, szHostForm, lpwhs->lpszHostName, lpwhs->nHostPort); - HTTP_ProcessHeader(lpwhr, hostW, lpszHostName, + HTTP_ProcessHeader(lpwhr, szHost, lpszHostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDHDR_FLAG_REQ); } else - HTTP_ProcessHeader(lpwhr, hostW, lpwhs->lpszHostName, + HTTP_ProcessHeader(lpwhr, szHost, lpwhs->lpszHostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDHDR_FLAG_REQ); if (lpwhs->nServerPort == INTERNET_INVALID_PORT_NUMBER) @@ -2722,27 +2020,76 @@ lend: /* read any content returned by the server so that the connection can be * reused */ -static void HTTP_DrainContent(http_request_t *req) +static void HTTP_DrainContent(WININETHTTPREQW *req) { DWORD bytes_read; if (!NETCON_connected(&req->netConnection)) return; if (req->dwContentLength == -1) - { NETCON_close(&req->netConnection); - return; - } - if (!strcmpW(req->lpszVerb, szHEAD)) return; do { char buffer[2048]; - if (HTTPREQ_Read(req, buffer, sizeof(buffer), &bytes_read, TRUE) != ERROR_SUCCESS) + if (HTTP_Read(req, buffer, sizeof(buffer), &bytes_read, TRUE) != ERROR_SUCCESS) return; } while (bytes_read); } +static const WCHAR szAccept[] = { 'A','c','c','e','p','t',0 }; +static const WCHAR szAccept_Charset[] = { 'A','c','c','e','p','t','-','C','h','a','r','s','e','t', 0 }; +static const WCHAR szAccept_Encoding[] = { 'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',0 }; +static const WCHAR szAccept_Language[] = { 'A','c','c','e','p','t','-','L','a','n','g','u','a','g','e',0 }; +static const WCHAR szAccept_Ranges[] = { 'A','c','c','e','p','t','-','R','a','n','g','e','s',0 }; +static const WCHAR szAge[] = { 'A','g','e',0 }; +static const WCHAR szAllow[] = { 'A','l','l','o','w',0 }; +static const WCHAR szCache_Control[] = { 'C','a','c','h','e','-','C','o','n','t','r','o','l',0 }; +static const WCHAR szConnection[] = { 'C','o','n','n','e','c','t','i','o','n',0 }; +static const WCHAR szContent_Base[] = { 'C','o','n','t','e','n','t','-','B','a','s','e',0 }; +static const WCHAR szContent_Encoding[] = { 'C','o','n','t','e','n','t','-','E','n','c','o','d','i','n','g',0 }; +static const WCHAR szContent_ID[] = { 'C','o','n','t','e','n','t','-','I','D',0 }; +static const WCHAR szContent_Language[] = { 'C','o','n','t','e','n','t','-','L','a','n','g','u','a','g','e',0 }; +static const WCHAR szContent_Length[] = { 'C','o','n','t','e','n','t','-','L','e','n','g','t','h',0 }; +static const WCHAR szContent_Location[] = { 'C','o','n','t','e','n','t','-','L','o','c','a','t','i','o','n',0 }; +static const WCHAR szContent_MD5[] = { 'C','o','n','t','e','n','t','-','M','D','5',0 }; +static const WCHAR szContent_Range[] = { 'C','o','n','t','e','n','t','-','R','a','n','g','e',0 }; +static const WCHAR szContent_Transfer_Encoding[] = { 'C','o','n','t','e','n','t','-','T','r','a','n','s','f','e','r','-','E','n','c','o','d','i','n','g',0 }; +static const WCHAR szContent_Type[] = { 'C','o','n','t','e','n','t','-','T','y','p','e',0 }; +static const WCHAR szCookie[] = { 'C','o','o','k','i','e',0 }; +static const WCHAR szDate[] = { 'D','a','t','e',0 }; +static const WCHAR szFrom[] = { 'F','r','o','m',0 }; +static const WCHAR szETag[] = { 'E','T','a','g',0 }; +static const WCHAR szExpect[] = { 'E','x','p','e','c','t',0 }; +static const WCHAR szExpires[] = { 'E','x','p','i','r','e','s',0 }; +static const WCHAR szIf_Match[] = { 'I','f','-','M','a','t','c','h',0 }; +static const WCHAR szIf_Modified_Since[] = { 'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0 }; +static const WCHAR szIf_None_Match[] = { 'I','f','-','N','o','n','e','-','M','a','t','c','h',0 }; +static const WCHAR szIf_Range[] = { 'I','f','-','R','a','n','g','e',0 }; +static const WCHAR szIf_Unmodified_Since[] = { 'I','f','-','U','n','m','o','d','i','f','i','e','d','-','S','i','n','c','e',0 }; +static const WCHAR szLast_Modified[] = { 'L','a','s','t','-','M','o','d','i','f','i','e','d',0 }; +static const WCHAR szLocation[] = { 'L','o','c','a','t','i','o','n',0 }; +static const WCHAR szMax_Forwards[] = { 'M','a','x','-','F','o','r','w','a','r','d','s',0 }; +static const WCHAR szMime_Version[] = { 'M','i','m','e','-','V','e','r','s','i','o','n',0 }; +static const WCHAR szPragma[] = { 'P','r','a','g','m','a',0 }; +static const WCHAR szProxy_Authenticate[] = { 'P','r','o','x','y','-','A','u','t','h','e','n','t','i','c','a','t','e',0 }; +static const WCHAR szProxy_Connection[] = { 'P','r','o','x','y','-','C','o','n','n','e','c','t','i','o','n',0 }; +static const WCHAR szPublic[] = { 'P','u','b','l','i','c',0 }; +static const WCHAR szRange[] = { 'R','a','n','g','e',0 }; +static const WCHAR szReferer[] = { 'R','e','f','e','r','e','r',0 }; +static const WCHAR szRetry_After[] = { 'R','e','t','r','y','-','A','f','t','e','r',0 }; +static const WCHAR szServer[] = { 'S','e','r','v','e','r',0 }; +static const WCHAR szSet_Cookie[] = { 'S','e','t','-','C','o','o','k','i','e',0 }; +static const WCHAR szTransfer_Encoding[] = { 'T','r','a','n','s','f','e','r','-','E','n','c','o','d','i','n','g',0 }; +static const WCHAR szUnless_Modified_Since[] = { 'U','n','l','e','s','s','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0 }; +static const WCHAR szUpgrade[] = { 'U','p','g','r','a','d','e',0 }; +static const WCHAR szURI[] = { 'U','R','I',0 }; +static const WCHAR szUser_Agent[] = { 'U','s','e','r','-','A','g','e','n','t',0 }; +static const WCHAR szVary[] = { 'V','a','r','y',0 }; +static const WCHAR szVia[] = { 'V','i','a',0 }; +static const WCHAR szWarning[] = { 'W','a','r','n','i','n','g',0 }; +static const WCHAR szWWW_Authenticate[] = { 'W','W','W','-','A','u','t','h','e','n','t','i','c','a','t','e',0 }; + static const LPCWSTR header_lookup[] = { szMime_Version, /* HTTP_QUERY_MIME_VERSION = 0 */ szContent_Type, /* HTTP_QUERY_CONTENT_TYPE = 1 */ @@ -2799,7 +2146,7 @@ static const LPCWSTR header_lookup[] = { szContent_MD5, /* HTTP_QUERY_CONTENT_MD5 = 52 */ szContent_Range, /* HTTP_QUERY_CONTENT_RANGE = 53 */ szETag, /* HTTP_QUERY_ETAG = 54 */ - hostW, /* HTTP_QUERY_HOST = 55 */ + szHost, /* HTTP_QUERY_HOST = 55 */ szIf_Match, /* HTTP_QUERY_IF_MATCH = 56 */ szIf_None_Match, /* HTTP_QUERY_IF_NONE_MATCH = 57 */ szIf_Range, /* HTTP_QUERY_IF_RANGE = 58 */ @@ -2822,27 +2169,27 @@ static const LPCWSTR header_lookup[] = { /*********************************************************************** * HTTP_HttpQueryInfoW (internal) */ -static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, +static BOOL WINAPI HTTP_HttpQueryInfoW( LPWININETHTTPREQW lpwhr, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex) { LPHTTPHEADERW lphttpHdr = NULL; BOOL bSuccess = FALSE; BOOL request_only = dwInfoLevel & HTTP_QUERY_FLAG_REQUEST_HEADERS; INT requested_index = lpdwIndex ? *lpdwIndex : 0; - DWORD level = (dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK); + INT level = (dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK); INT index = -1; /* Find requested header structure */ switch (level) { case HTTP_QUERY_CUSTOM: - if (!lpBuffer) return FALSE; index = HTTP_GetCustomHeaderIndex(lpwhr, lpBuffer, requested_index, request_only); break; + case HTTP_QUERY_RAW_HEADERS_CRLF: { LPWSTR headers; - DWORD len = 0; + DWORD len; BOOL ret = FALSE; if (request_only) @@ -2850,24 +2197,15 @@ static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, else headers = lpwhr->lpszRawHeaders; - if (headers) - len = strlenW(headers) * sizeof(WCHAR); - - if (len + sizeof(WCHAR) > *lpdwBufferLength) + len = (strlenW(headers) + 1) * sizeof(WCHAR); + if (len > *lpdwBufferLength) { - len += sizeof(WCHAR); INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); ret = FALSE; } else if (lpBuffer) { - if (headers) - memcpy(lpBuffer, headers, len + sizeof(WCHAR)); - else - { - len = strlenW(szCrLf) * sizeof(WCHAR); - memcpy(lpBuffer, szCrLf, sizeof(szCrLf)); - } + memcpy(lpBuffer, headers, len); TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len / sizeof(WCHAR))); ret = TRUE; } @@ -2879,9 +2217,10 @@ static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, } case HTTP_QUERY_RAW_HEADERS: { + static const WCHAR szCrLf[] = {'\r','\n',0}; LPWSTR * ppszRawHeaderLines = HTTP_Tokenize(lpwhr->lpszRawHeaders, szCrLf); DWORD i, size = 0; - LPWSTR pszString = lpBuffer; + LPWSTR pszString = (WCHAR*)lpBuffer; for (i = 0; ppszRawHeaderLines[i]; i++) size += strlenW(ppszRawHeaderLines[i]) + 1; @@ -2893,17 +2232,17 @@ static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } - if (pszString) + + for (i = 0; ppszRawHeaderLines[i]; i++) { - for (i = 0; ppszRawHeaderLines[i]; i++) - { - DWORD len = strlenW(ppszRawHeaderLines[i]); - memcpy(pszString, ppszRawHeaderLines[i], (len+1)*sizeof(WCHAR)); - pszString += len+1; - } - *pszString = '\0'; - TRACE("returning data: %s\n", debugstr_wn(lpBuffer, size)); + DWORD len = strlenW(ppszRawHeaderLines[i]); + memcpy(pszString, ppszRawHeaderLines[i], (len+1)*sizeof(WCHAR)); + pszString += len+1; } + *pszString = '\0'; + + TRACE("returning data: %s\n", debugstr_wn((WCHAR*)lpBuffer, size)); + *lpdwBufferLength = size * sizeof(WCHAR); HTTP_FreeTokens(ppszRawHeaderLines); @@ -2919,12 +2258,11 @@ static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } - if (lpBuffer) - { - memcpy(lpBuffer, lpwhr->lpszStatusText, (len + 1) * sizeof(WCHAR)); - TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len)); - } + memcpy(lpBuffer, lpwhr->lpszStatusText, (len+1)*sizeof(WCHAR)); *lpdwBufferLength = len * sizeof(WCHAR); + + TRACE("returning data: %s\n", debugstr_wn((WCHAR*)lpBuffer, len)); + return TRUE; } break; @@ -2938,23 +2276,18 @@ static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } - if (lpBuffer) - { - memcpy(lpBuffer, lpwhr->lpszVersion, (len + 1) * sizeof(WCHAR)); - TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len)); - } + memcpy(lpBuffer, lpwhr->lpszVersion, (len+1)*sizeof(WCHAR)); *lpdwBufferLength = len * sizeof(WCHAR); + + TRACE("returning data: %s\n", debugstr_wn((WCHAR*)lpBuffer, len)); + return TRUE; } break; - case HTTP_QUERY_CONTENT_ENCODING: - index = HTTP_GetCustomHeaderIndex(lpwhr, header_lookup[lpwhr->gzip_stream ? HTTP_QUERY_CONTENT_TYPE : level], - requested_index,request_only); - break; default: assert (LAST_TABLE_HEADER == (HTTP_QUERY_UNLESS_MODIFIED_SINCE + 1)); - if (level < LAST_TABLE_HEADER && header_lookup[level]) + if (level >= 0 && level < LAST_TABLE_HEADER && header_lookup[level]) index = HTTP_GetCustomHeaderIndex(lpwhr, header_lookup[level], requested_index,request_only); } @@ -2971,16 +2304,18 @@ static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, return bSuccess; } - if (lpdwIndex && level != HTTP_QUERY_STATUS_CODE) (*lpdwIndex)++; + if (lpdwIndex) + (*lpdwIndex)++; /* coalesce value to requested type */ - if (dwInfoLevel & HTTP_QUERY_FLAG_NUMBER && lpBuffer) + if (dwInfoLevel & HTTP_QUERY_FLAG_NUMBER) { - *(int *)lpBuffer = atoiW(lphttpHdr->lpszValue); - TRACE(" returning number: %d\n", *(int *)lpBuffer); - bSuccess = TRUE; + *(int *)lpBuffer = atoiW(lphttpHdr->lpszValue); + bSuccess = TRUE; + + TRACE(" returning number : %d\n", *(int *)lpBuffer); } - else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME && lpBuffer) + else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME) { time_t tmpTime; struct tm tmpTM; @@ -2989,20 +2324,24 @@ static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, tmpTime = ConvertTimeString(lphttpHdr->lpszValue); tmpTM = *gmtime(&tmpTime); - STHook = (SYSTEMTIME *)lpBuffer; - STHook->wDay = tmpTM.tm_mday; - STHook->wHour = tmpTM.tm_hour; - STHook->wMilliseconds = 0; - STHook->wMinute = tmpTM.tm_min; - STHook->wDayOfWeek = tmpTM.tm_wday; - STHook->wMonth = tmpTM.tm_mon + 1; - STHook->wSecond = tmpTM.tm_sec; - STHook->wYear = tmpTM.tm_year; - bSuccess = TRUE; + STHook = (SYSTEMTIME *) lpBuffer; + if(STHook==NULL) + return bSuccess; + + STHook->wDay = tmpTM.tm_mday; + STHook->wHour = tmpTM.tm_hour; + STHook->wMilliseconds = 0; + STHook->wMinute = tmpTM.tm_min; + STHook->wDayOfWeek = tmpTM.tm_wday; + STHook->wMonth = tmpTM.tm_mon + 1; + STHook->wSecond = tmpTM.tm_sec; + STHook->wYear = tmpTM.tm_year; - TRACE(" returning time: %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n", - STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek, - STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds); + bSuccess = TRUE; + + TRACE(" returning time : %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n", + STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek, + STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds); } else if (lphttpHdr->lpszValue) { @@ -3014,13 +2353,12 @@ static BOOL HTTP_HttpQueryInfoW(http_request_t *lpwhr, DWORD dwInfoLevel, INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); return bSuccess; } - if (lpBuffer) - { - memcpy(lpBuffer, lphttpHdr->lpszValue, len); - TRACE(" returning string: %s\n", debugstr_w(lpBuffer)); - } + + memcpy(lpBuffer, lphttpHdr->lpszValue, len); *lpdwBufferLength = len - sizeof(WCHAR); bSuccess = TRUE; + + TRACE(" returning string : %s\n", debugstr_w(lpBuffer)); } return bSuccess; } @@ -3039,7 +2377,7 @@ BOOL WINAPI HttpQueryInfoW(HINTERNET hHttpRequest, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex) { BOOL bSuccess = FALSE; - http_request_t *lpwhr; + LPWININETHTTPREQW lpwhr; if (TRACE_ON(wininet)) { #define FE(x) { x, #x } @@ -3151,7 +2489,7 @@ BOOL WINAPI HttpQueryInfoW(HINTERNET hHttpRequest, DWORD dwInfoLevel, TRACE("\n"); } - lpwhr = (http_request_t*) WININET_GetObject( hHttpRequest ); + lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hHttpRequest ); if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); @@ -3310,14 +2648,14 @@ BOOL WINAPI HttpSendRequestExW(HINTERNET hRequest, DWORD dwFlags, DWORD_PTR dwContext) { BOOL ret = FALSE; - http_request_t *lpwhr; - http_session_t *lpwhs; - appinfo_t *hIC; + LPWININETHTTPREQW lpwhr; + LPWININETHTTPSESSIONW lpwhs; + LPWININETAPPINFOW hIC; TRACE("(%p, %p, %p, %08x, %08lx)\n", hRequest, lpBuffersIn, lpBuffersOut, dwFlags, dwContext); - lpwhr = (http_request_t*) WININET_GetObject( hRequest ); + lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest ); if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) { @@ -3340,16 +2678,11 @@ BOOL WINAPI HttpSendRequestExW(HINTERNET hRequest, req = &workRequest.u.HttpSendRequestW; if (lpBuffersIn) { - DWORD size; - - if (lpBuffersIn->dwHeadersLength == ~0u) - size = (strlenW( lpBuffersIn->lpcszHeader ) + 1) * sizeof(WCHAR); + if (lpBuffersIn->lpcszHeader) + /* FIXME: this should use dwHeadersLength or may not be necessary at all */ + req->lpszHeader = WININET_strdupW(lpBuffersIn->lpcszHeader); else - size = lpBuffersIn->dwHeadersLength * sizeof(WCHAR); - - req->lpszHeader = HeapAlloc( GetProcessHeap(), 0, size ); - memcpy( req->lpszHeader, lpBuffersIn->lpcszHeader, size ); - + req->lpszHeader = NULL; req->dwHeaderLength = lpBuffersIn->dwHeadersLength; req->lpOptional = lpBuffersIn->lpvBuffer; req->dwOptionalLength = lpBuffersIn->dwBufferLength; @@ -3403,15 +2736,15 @@ lend: BOOL WINAPI HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders, DWORD dwHeaderLength, LPVOID lpOptional ,DWORD dwOptionalLength) { - http_request_t *lpwhr; - http_session_t *lpwhs = NULL; - appinfo_t *hIC = NULL; + LPWININETHTTPREQW lpwhr; + LPWININETHTTPSESSIONW lpwhs = NULL; + LPWININETAPPINFOW hIC = NULL; BOOL r; TRACE("%p, %s, %i, %p, %i)\n", hHttpRequest, debugstr_wn(lpszHeaders, dwHeaderLength), dwHeaderLength, lpOptional, dwOptionalLength); - lpwhr = (http_request_t*) WININET_GetObject( hHttpRequest ); + lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hHttpRequest ); if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); @@ -3445,13 +2778,8 @@ BOOL WINAPI HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders, req = &workRequest.u.HttpSendRequestW; if (lpszHeaders) { - DWORD size; - - if (dwHeaderLength == ~0u) size = (strlenW(lpszHeaders) + 1) * sizeof(WCHAR); - else size = dwHeaderLength * sizeof(WCHAR); - - req->lpszHeader = HeapAlloc(GetProcessHeap(), 0, size); - memcpy(req->lpszHeader, lpszHeaders, size); + req->lpszHeader = HeapAlloc(GetProcessHeap(), 0, dwHeaderLength * sizeof(WCHAR)); + memcpy(req->lpszHeader, lpszHeaders, dwHeaderLength * sizeof(WCHAR)); } else req->lpszHeader = 0; @@ -3507,75 +2835,29 @@ BOOL WINAPI HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders, return result; } -/*********************************************************************** - * HTTP_GetRedirectURL (internal) - */ -static LPWSTR HTTP_GetRedirectURL(http_request_t *lpwhr, LPCWSTR lpszUrl) +static BOOL HTTP_GetRequestURL(WININETHTTPREQW *req, LPWSTR buf) { - static WCHAR szHttp[] = {'h','t','t','p',0}; - static WCHAR szHttps[] = {'h','t','t','p','s',0}; - http_session_t *lpwhs = lpwhr->lpHttpSession; - URL_COMPONENTSW urlComponents; - DWORD url_length = 0; - LPWSTR orig_url; - LPWSTR combined_url; + LPHTTPHEADERW host_header; - urlComponents.dwStructSize = sizeof(URL_COMPONENTSW); - urlComponents.lpszScheme = (lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp; - urlComponents.dwSchemeLength = 0; - urlComponents.lpszHostName = lpwhs->lpszHostName; - urlComponents.dwHostNameLength = 0; - urlComponents.nPort = lpwhs->nHostPort; - urlComponents.lpszUserName = lpwhs->lpszUserName; - urlComponents.dwUserNameLength = 0; - urlComponents.lpszPassword = NULL; - urlComponents.dwPasswordLength = 0; - urlComponents.lpszUrlPath = lpwhr->lpszPath; - urlComponents.dwUrlPathLength = 0; - urlComponents.lpszExtraInfo = NULL; - urlComponents.dwExtraInfoLength = 0; + static const WCHAR formatW[] = {'h','t','t','p',':','/','/','%','s','%','s',0}; - if (!InternetCreateUrlW(&urlComponents, 0, NULL, &url_length) && - (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) - return NULL; + host_header = HTTP_GetHeader(req, szHost); + if(!host_header) + return FALSE; - orig_url = HeapAlloc(GetProcessHeap(), 0, url_length); - - /* convert from bytes to characters */ - url_length = url_length / sizeof(WCHAR) - 1; - if (!InternetCreateUrlW(&urlComponents, 0, orig_url, &url_length)) - { - HeapFree(GetProcessHeap(), 0, orig_url); - return NULL; - } - - url_length = 0; - if (!InternetCombineUrlW(orig_url, lpszUrl, NULL, &url_length, ICU_ENCODE_SPACES_ONLY) && - (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) - { - HeapFree(GetProcessHeap(), 0, orig_url); - return NULL; - } - combined_url = HeapAlloc(GetProcessHeap(), 0, url_length * sizeof(WCHAR)); - - if (!InternetCombineUrlW(orig_url, lpszUrl, combined_url, &url_length, ICU_ENCODE_SPACES_ONLY)) - { - HeapFree(GetProcessHeap(), 0, orig_url); - HeapFree(GetProcessHeap(), 0, combined_url); - return NULL; - } - HeapFree(GetProcessHeap(), 0, orig_url); - return combined_url; + sprintfW(buf, formatW, host_header->lpszValue, req->lpszPath); /* FIXME */ + return TRUE; } - /*********************************************************************** * HTTP_HandleRedirect (internal) */ -static BOOL HTTP_HandleRedirect(http_request_t *lpwhr, LPCWSTR lpszUrl) +static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl) { - http_session_t *lpwhs = lpwhr->lpHttpSession; - appinfo_t *hIC = lpwhs->lpAppInfo; + static const WCHAR szContentType[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0}; + static const WCHAR szContentLength[] = {'C','o','n','t','e','n','t','-','L','e','n','g','t','h',0}; + LPWININETHTTPSESSIONW lpwhs = lpwhr->lpHttpSession; + LPWININETAPPINFOW hIC = lpwhs->lpAppInfo; BOOL using_proxy = hIC->lpszProxy && hIC->lpszProxy[0]; WCHAR path[INTERNET_MAX_URL_LENGTH]; int index; @@ -3591,6 +2873,55 @@ static BOOL HTTP_HandleRedirect(http_request_t *lpwhr, LPCWSTR lpszUrl) WCHAR protocol[32], hostName[MAXHOSTNAME], userName[1024]; static WCHAR szHttp[] = {'h','t','t','p',0}; static WCHAR szHttps[] = {'h','t','t','p','s',0}; + DWORD url_length = 0; + LPWSTR orig_url; + LPWSTR combined_url; + + urlComponents.dwStructSize = sizeof(URL_COMPONENTSW); + urlComponents.lpszScheme = (lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp; + urlComponents.dwSchemeLength = 0; + urlComponents.lpszHostName = lpwhs->lpszHostName; + urlComponents.dwHostNameLength = 0; + urlComponents.nPort = lpwhs->nHostPort; + urlComponents.lpszUserName = lpwhs->lpszUserName; + urlComponents.dwUserNameLength = 0; + urlComponents.lpszPassword = NULL; + urlComponents.dwPasswordLength = 0; + urlComponents.lpszUrlPath = lpwhr->lpszPath; + urlComponents.dwUrlPathLength = 0; + urlComponents.lpszExtraInfo = NULL; + urlComponents.dwExtraInfoLength = 0; + + if (!InternetCreateUrlW(&urlComponents, 0, NULL, &url_length) && + (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) + return FALSE; + + orig_url = HeapAlloc(GetProcessHeap(), 0, url_length); + + /* convert from bytes to characters */ + url_length = url_length / sizeof(WCHAR) - 1; + if (!InternetCreateUrlW(&urlComponents, 0, orig_url, &url_length)) + { + HeapFree(GetProcessHeap(), 0, orig_url); + return FALSE; + } + + url_length = 0; + if (!InternetCombineUrlW(orig_url, lpszUrl, NULL, &url_length, ICU_ENCODE_SPACES_ONLY) && + (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) + { + HeapFree(GetProcessHeap(), 0, orig_url); + return FALSE; + } + combined_url = HeapAlloc(GetProcessHeap(), 0, url_length * sizeof(WCHAR)); + + if (!InternetCombineUrlW(orig_url, lpszUrl, combined_url, &url_length, ICU_ENCODE_SPACES_ONLY)) + { + HeapFree(GetProcessHeap(), 0, orig_url); + HeapFree(GetProcessHeap(), 0, combined_url); + return FALSE; + } + HeapFree(GetProcessHeap(), 0, orig_url); userName[0] = 0; hostName[0] = 0; @@ -3609,8 +2940,13 @@ static BOOL HTTP_HandleRedirect(http_request_t *lpwhr, LPCWSTR lpszUrl) urlComponents.dwUrlPathLength = 2048; urlComponents.lpszExtraInfo = NULL; urlComponents.dwExtraInfoLength = 0; - if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents)) + if(!InternetCrackUrlW(combined_url, strlenW(combined_url), 0, &urlComponents)) + { + HeapFree(GetProcessHeap(), 0, combined_url); return FALSE; + } + + HeapFree(GetProcessHeap(), 0, combined_url); if (!strncmpW(szHttp, urlComponents.lpszScheme, strlenW(szHttp)) && (lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE)) @@ -3664,28 +3000,26 @@ static BOOL HTTP_HandleRedirect(http_request_t *lpwhr, LPCWSTR lpszUrl) sprintfW(lpwhs->lpszHostName, fmt, hostName, urlComponents.nPort); } else - lpwhs->lpszHostName = heap_strdupW(hostName); + lpwhs->lpszHostName = WININET_strdupW(hostName); - HTTP_ProcessHeader(lpwhr, hostW, lpwhs->lpszHostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ); + HTTP_ProcessHeader(lpwhr, szHost, lpwhs->lpszHostName, HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDHDR_FLAG_REQ); HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName); lpwhs->lpszUserName = NULL; if (userName[0]) - lpwhs->lpszUserName = heap_strdupW(userName); + lpwhs->lpszUserName = WININET_strdupW(userName); if (!using_proxy) { if (strcmpiW(lpwhs->lpszServerName, hostName) || lpwhs->nServerPort != urlComponents.nPort) { HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName); - lpwhs->lpszServerName = heap_strdupW(hostName); + lpwhs->lpszServerName = WININET_strdupW(hostName); lpwhs->nServerPort = urlComponents.nPort; NETCON_close(&lpwhr->netConnection); if (!HTTP_ResolveName(lpwhr)) return FALSE; if (!NETCON_init(&lpwhr->netConnection, lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE)) return FALSE; - lpwhr->read_pos = lpwhr->read_size = 0; - lpwhr->read_chunked = FALSE; } } else @@ -3705,7 +3039,7 @@ static BOOL HTTP_HandleRedirect(http_request_t *lpwhr, LPCWSTR lpszUrl) lpwhr->lpszPath = HeapAlloc(GetProcessHeap(), 0, needed*sizeof(WCHAR)); rc = UrlEscapeW(path, lpwhr->lpszPath, &needed, URL_ESCAPE_SPACES_ONLY); - if (rc != S_OK) + if (rc) { ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc); strcpyW(lpwhr->lpszPath,path); @@ -3713,10 +3047,10 @@ static BOOL HTTP_HandleRedirect(http_request_t *lpwhr, LPCWSTR lpszUrl) } /* Remove custom content-type/length headers on redirects. */ - index = HTTP_GetCustomHeaderIndex(lpwhr, szContent_Type, 0, TRUE); + index = HTTP_GetCustomHeaderIndex(lpwhr, szContentType, 0, TRUE); if (0 <= index) HTTP_DeleteCustomHeader(lpwhr, index); - index = HTTP_GetCustomHeaderIndex(lpwhr, szContent_Length, 0, TRUE); + index = HTTP_GetCustomHeaderIndex(lpwhr, szContentLength, 0, TRUE); if (0 <= index) HTTP_DeleteCustomHeader(lpwhr, index); @@ -3746,7 +3080,7 @@ static LPWSTR HTTP_build_req( LPCWSTR *list, int len ) return str; } -static BOOL HTTP_SecureProxyConnect(http_request_t *lpwhr) +static BOOL HTTP_SecureProxyConnect(LPWININETHTTPREQW lpwhr) { LPWSTR lpszPath; LPWSTR requestString; @@ -3757,7 +3091,7 @@ static BOOL HTTP_SecureProxyConnect(http_request_t *lpwhr) BOOL ret; static const WCHAR szConnect[] = {'C','O','N','N','E','C','T',0}; static const WCHAR szFormat[] = {'%','s',':','%','d',0}; - http_session_t *lpwhs = lpwhr->lpHttpSession; + LPWININETHTTPSESSIONW lpwhs = lpwhr->lpHttpSession; TRACE("\n"); @@ -3788,30 +3122,31 @@ static BOOL HTTP_SecureProxyConnect(http_request_t *lpwhr) return TRUE; } -static void HTTP_InsertCookies(http_request_t *lpwhr) +static void HTTP_InsertCookies(LPWININETHTTPREQW lpwhr) { - static const WCHAR szUrlForm[] = {'h','t','t','p',':','/','/','%','s','%','s',0}; + static const WCHAR szUrlForm[] = {'h','t','t','p',':','/','/','%','s',0}; LPWSTR lpszCookies, lpszUrl = NULL; DWORD nCookieSize, size; - LPHTTPHEADERW Host = HTTP_GetHeader(lpwhr, hostW); + LPHTTPHEADERW Host = HTTP_GetHeader(lpwhr,szHost); - size = (strlenW(Host->lpszValue) + strlenW(szUrlForm) + strlenW(lpwhr->lpszPath)) * sizeof(WCHAR); + size = (strlenW(Host->lpszValue) + strlenW(szUrlForm)) * sizeof(WCHAR); if (!(lpszUrl = HeapAlloc(GetProcessHeap(), 0, size))) return; - sprintfW( lpszUrl, szUrlForm, Host->lpszValue, lpwhr->lpszPath); + sprintfW( lpszUrl, szUrlForm, Host->lpszValue ); if (InternetGetCookieW(lpszUrl, NULL, NULL, &nCookieSize)) { int cnt = 0; static const WCHAR szCookie[] = {'C','o','o','k','i','e',':',' ',0}; + static const WCHAR szcrlf[] = {'\r','\n',0}; - size = sizeof(szCookie) + nCookieSize * sizeof(WCHAR) + sizeof(szCrLf); + size = sizeof(szCookie) + nCookieSize * sizeof(WCHAR) + sizeof(szcrlf); if ((lpszCookies = HeapAlloc(GetProcessHeap(), 0, size))) { cnt += sprintfW(lpszCookies, szCookie); InternetGetCookieW(lpszUrl, NULL, lpszCookies + cnt, &nCookieSize); - strcatW(lpszCookies, szCrLf); + strcatW(lpszCookies, szcrlf); - HTTP_HttpAddRequestHeadersW(lpwhr, lpszCookies, strlenW(lpszCookies), HTTP_ADDREQ_FLAG_REPLACE); + HTTP_HttpAddRequestHeadersW(lpwhr, lpszCookies, strlenW(lpszCookies), HTTP_ADDREQ_FLAG_ADD); HeapFree(GetProcessHeap(), 0, lpszCookies); } } @@ -3828,12 +3163,12 @@ static void HTTP_InsertCookies(http_request_t *lpwhr) * FALSE on failure * */ -BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, +BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders, DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength, DWORD dwContentLength, BOOL bEndRequest) { INT cnt; - BOOL bSuccess = FALSE, redirected = FALSE; + BOOL bSuccess = FALSE; LPWSTR requestString = NULL; INT responseLen; BOOL loop_next; @@ -3849,13 +3184,12 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, /* if the verb is NULL default to GET */ if (!lpwhr->lpszVerb) - lpwhr->lpszVerb = heap_strdupW(szGET); + lpwhr->lpszVerb = WININET_strdupW(szGET); - if (dwContentLength || strcmpW(lpwhr->lpszVerb, szGET)) + if (dwContentLength || !strcmpW(lpwhr->lpszVerb, szPost)) { sprintfW(contentLengthStr, szContentLength, dwContentLength); - HTTP_HttpAddRequestHeadersW(lpwhr, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_REPLACE); - lpwhr->dwBytesToWrite = dwContentLength; + HTTP_HttpAddRequestHeadersW(lpwhr, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_ADD_IF_NEW); } if (lpwhr->lpHttpSession->lpAppInfo->lpszAgent) { @@ -3896,7 +3230,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, if (TRACE_ON(wininet)) { - LPHTTPHEADERW Host = HTTP_GetHeader(lpwhr, hostW); + LPHTTPHEADERW Host = HTTP_GetHeader(lpwhr,szHost); TRACE("Going to url %s %s\n", debugstr_w(Host->lpszValue), debugstr_w(lpwhr->lpszPath)); } @@ -3935,7 +3269,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, goto lend; /* send the request as ASCII, tack on the optional data */ - if (!lpOptional || redirected) + if( !lpOptional ) dwOptionalLength = 0; len = WideCharToMultiByte( CP_ACP, 0, requestString, -1, NULL, 0, NULL, NULL ); @@ -3954,8 +3288,6 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, NETCON_send(&lpwhr->netConnection, ascii_req, len, 0, &cnt); HeapFree( GetProcessHeap(), 0, ascii_req ); - lpwhr->dwBytesWritten = dwOptionalLength; - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_REQUEST_SENT, &len, sizeof(DWORD)); @@ -3964,6 +3296,8 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, { DWORD dwBufferSize; DWORD dwStatusCode; + WCHAR encoding[20]; + static const WCHAR szChunked[] = {'c','h','u','n','k','e','d',0}; INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); @@ -3981,7 +3315,22 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, HTTP_ProcessCookies(lpwhr); - if (!set_content_length( lpwhr )) HTTP_FinishedReading(lpwhr); + dwBufferSize = sizeof(lpwhr->dwContentLength); + if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, + &lpwhr->dwContentLength,&dwBufferSize,NULL)) + lpwhr->dwContentLength = -1; + + if (lpwhr->dwContentLength == 0) + HTTP_FinishedReading(lpwhr); + + /* Correct the case where both a Content-Length and Transfer-encoding = chunked are set */ + + dwBufferSize = sizeof(encoding); + if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_TRANSFER_ENCODING, encoding, &dwBufferSize, NULL) && + !strcmpiW(encoding, szChunked)) + { + lpwhr->dwContentLength = -1; + } dwBufferSize = sizeof(dwStatusCode); if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE, @@ -3990,30 +3339,21 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT) && bSuccess) { - WCHAR *new_url, szNewLocation[INTERNET_MAX_URL_LENGTH]; + WCHAR szNewLocation[INTERNET_MAX_URL_LENGTH]; dwBufferSize=sizeof(szNewLocation); if ((dwStatusCode==HTTP_STATUS_REDIRECT || dwStatusCode==HTTP_STATUS_MOVED) && HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL)) { - if (strcmpW(lpwhr->lpszVerb, szGET) && strcmpW(lpwhr->lpszVerb, szHEAD)) - { - HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb); - lpwhr->lpszVerb = heap_strdupW(szGET); - } HTTP_DrainContent(lpwhr); - if ((new_url = HTTP_GetRedirectURL( lpwhr, szNewLocation ))) + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_REDIRECT, szNewLocation, + dwBufferSize); + bSuccess = HTTP_HandleRedirect(lpwhr, szNewLocation); + if (bSuccess) { - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_REDIRECT, - new_url, (strlenW(new_url) + 1) * sizeof(WCHAR)); - bSuccess = HTTP_HandleRedirect(lpwhr, new_url); - if (bSuccess) - { - HeapFree(GetProcessHeap(), 0, requestString); - loop_next = TRUE; - } - HeapFree( GetProcessHeap(), 0, new_url ); + HeapFree(GetProcessHeap(), 0, requestString); + loop_next = TRUE; } - redirected = TRUE; } } if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTH) && bSuccess) @@ -4022,15 +3362,13 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, dwBufferSize=2048; if (dwStatusCode == HTTP_STATUS_DENIED) { - LPHTTPHEADERW Host = HTTP_GetHeader(lpwhr, hostW); DWORD dwIndex = 0; while (HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_WWW_AUTHENTICATE,szAuthValue,&dwBufferSize,&dwIndex)) { if (HTTP_DoAuthorization(lpwhr, szAuthValue, &lpwhr->pAuthInfo, lpwhr->lpHttpSession->lpszUserName, - lpwhr->lpHttpSession->lpszPassword, - Host->lpszValue)) + lpwhr->lpHttpSession->lpszPassword)) { loop_next = TRUE; break; @@ -4045,8 +3383,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, if (HTTP_DoAuthorization(lpwhr, szAuthValue, &lpwhr->pProxyAuthInfo, lpwhr->lpHttpSession->lpAppInfo->lpszProxyUsername, - lpwhr->lpHttpSession->lpAppInfo->lpszProxyPassword, - NULL)) + lpwhr->lpHttpSession->lpAppInfo->lpszProxyPassword)) { loop_next = TRUE; break; @@ -4060,7 +3397,8 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, } while (loop_next); - if(bSuccess) { + /* FIXME: Better check, when we have to create the cache file */ + if(bSuccess && (lpwhr->hdr.dwFlags & INTERNET_FLAG_NEED_FILE)) { WCHAR url[INTERNET_MAX_URL_LENGTH]; WCHAR cacheFileName[MAX_PATH+1]; BOOL b; @@ -4073,7 +3411,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, b = CreateUrlCacheEntryW(url, lpwhr->dwContentLength > 0 ? lpwhr->dwContentLength : 0, NULL, cacheFileName, 0); if(b) { - lpwhr->lpszCacheFile = heap_strdupW(cacheFileName); + lpwhr->lpszCacheFile = WININET_strdupW(cacheFileName); lpwhr->hCacheFile = CreateFileW(lpwhr->lpszCacheFile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(lpwhr->hCacheFile == INVALID_HANDLE_VALUE) { @@ -4091,31 +3429,12 @@ lend: /* TODO: send notification for P3P header */ - if (lpwhr->lpHttpSession->lpAppInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) - { - if (bSuccess) - { - if (lpwhr->dwBytesWritten == lpwhr->dwBytesToWrite) HTTP_ReceiveRequestData(lpwhr, TRUE); - else - { - iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet; - iar.dwError = 0; + iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet; + iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError(); - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_REQUEST_COMPLETE, &iar, - sizeof(INTERNET_ASYNC_RESULT)); - } - } - else - { - iar.dwResult = (DWORD_PTR)lpwhr->hdr.hInternet; - iar.dwError = INTERNET_GetLastError(); - - INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, - INTERNET_STATUS_REQUEST_COMPLETE, &iar, - sizeof(INTERNET_ASYNC_RESULT)); - } - } + INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, + INTERNET_STATUS_REQUEST_COMPLETE, &iar, + sizeof(INTERNET_ASYNC_RESULT)); TRACE("<--\n"); if (bSuccess) INTERNET_SetLastError(ERROR_SUCCESS); @@ -4128,9 +3447,9 @@ lend: * Deallocate session handle * */ -static void HTTPSESSION_Destroy(object_header_t *hdr) +static void HTTPSESSION_Destroy(WININETHANDLEHEADER *hdr) { - http_session_t *lpwhs = (http_session_t*) hdr; + LPWININETHTTPSESSIONW lpwhs = (LPWININETHTTPSESSIONW) hdr; TRACE("%p\n", lpwhs); @@ -4143,7 +3462,7 @@ static void HTTPSESSION_Destroy(object_header_t *hdr) HeapFree(GetProcessHeap(), 0, lpwhs); } -static DWORD HTTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) +static DWORD HTTPSESSION_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { switch(option) { case INTERNET_OPTION_HANDLE_TYPE: @@ -4160,34 +3479,11 @@ static DWORD HTTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *b return INET_QueryOption(option, buffer, size, unicode); } -static DWORD HTTPSESSION_SetOption(object_header_t *hdr, DWORD option, void *buffer, DWORD size) -{ - http_session_t *ses = (http_session_t*)hdr; - - switch(option) { - case INTERNET_OPTION_USERNAME: - { - HeapFree(GetProcessHeap(), 0, ses->lpszUserName); - if (!(ses->lpszUserName = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; - return ERROR_SUCCESS; - } - case INTERNET_OPTION_PASSWORD: - { - HeapFree(GetProcessHeap(), 0, ses->lpszPassword); - if (!(ses->lpszPassword = heap_strdupW(buffer))) return ERROR_OUTOFMEMORY; - return ERROR_SUCCESS; - } - default: break; - } - - return ERROR_INTERNET_INVALID_OPTION; -} - -static const object_vtbl_t HTTPSESSIONVtbl = { +static const HANDLEHEADERVtbl HTTPSESSIONVtbl = { HTTPSESSION_Destroy, NULL, HTTPSESSION_QueryOption, - HTTPSESSION_SetOption, + NULL, NULL, NULL, NULL, @@ -4206,12 +3502,12 @@ static const object_vtbl_t HTTPSESSIONVtbl = { * NULL on failure * */ -HINTERNET HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, +HINTERNET HTTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext, DWORD dwInternalFlags) { - http_session_t *lpwhs = NULL; + LPWININETHTTPSESSIONW lpwhs = NULL; HINTERNET handle = NULL; TRACE("-->\n"); @@ -4224,7 +3520,7 @@ HINTERNET HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, assert( hIC->hdr.htype == WH_HINIT ); - lpwhs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(http_session_t)); + lpwhs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETHTTPSESSIONW)); if (NULL == lpwhs) { INTERNET_SetLastError(ERROR_OUTOFMEMORY); @@ -4263,13 +3559,13 @@ HINTERNET HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, } if (lpszServerName && lpszServerName[0]) { - lpwhs->lpszServerName = heap_strdupW(lpszServerName); - lpwhs->lpszHostName = heap_strdupW(lpszServerName); + lpwhs->lpszServerName = WININET_strdupW(lpszServerName); + lpwhs->lpszHostName = WININET_strdupW(lpszServerName); } if (lpszUserName && lpszUserName[0]) - lpwhs->lpszUserName = heap_strdupW(lpszUserName); + lpwhs->lpszUserName = WININET_strdupW(lpszUserName); if (lpszPassword && lpszPassword[0]) - lpwhs->lpszPassword = heap_strdupW(lpszPassword); + lpwhs->lpszPassword = WININET_strdupW(lpszPassword); lpwhs->nServerPort = nServerPort; lpwhs->nHostPort = nServerPort; @@ -4305,18 +3601,17 @@ lerror: * TRUE on success * FALSE on failure */ -static BOOL HTTP_OpenConnection(http_request_t *lpwhr) +static BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr) { BOOL bSuccess = FALSE; - http_session_t *lpwhs; - appinfo_t *hIC = NULL; - char szaddr[INET6_ADDRSTRLEN]; - const void *addr; + LPWININETHTTPSESSIONW lpwhs; + LPWININETAPPINFOW hIC = NULL; + char szaddr[32]; TRACE("-->\n"); - if (lpwhr->hdr.htype != WH_HHTTPREQ) + if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) { INTERNET_SetLastError(ERROR_INVALID_PARAMETER); goto lend; @@ -4332,26 +3627,14 @@ static BOOL HTTP_OpenConnection(http_request_t *lpwhr) lpwhs = lpwhr->lpHttpSession; hIC = lpwhs->lpAppInfo; - switch (lpwhs->socketAddress.ss_family) - { - case AF_INET: - addr = &((struct sockaddr_in *)&lpwhs->socketAddress)->sin_addr; - break; - case AF_INET6: - addr = &((struct sockaddr_in6 *)&lpwhs->socketAddress)->sin6_addr; - break; - default: - WARN("unsupported family %d\n", lpwhs->socketAddress.ss_family); - INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); - return FALSE; - } - inet_ntop(lpwhs->socketAddress.ss_family, addr, szaddr, sizeof(szaddr)); + inet_ntop(lpwhs->socketAddress.sin_family, &lpwhs->socketAddress.sin_addr, + szaddr, sizeof(szaddr)); INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_CONNECTING_TO_SERVER, szaddr, strlen(szaddr)+1); - if (!NETCON_create(&lpwhr->netConnection, lpwhs->socketAddress.ss_family, + if (!NETCON_create(&lpwhr->netConnection, lpwhs->socketAddress.sin_family, SOCK_STREAM, 0)) { WARN("Socket creation failed: %u\n", INTERNET_GetLastError()); @@ -4359,7 +3642,7 @@ static BOOL HTTP_OpenConnection(http_request_t *lpwhr) } if (!NETCON_connect(&lpwhr->netConnection, (struct sockaddr *)&lpwhs->socketAddress, - lpwhs->sa_len)) + sizeof(lpwhs->socketAddress))) goto lend; if (lpwhr->hdr.dwFlags & INTERNET_FLAG_SECURE) @@ -4387,9 +3670,6 @@ static BOOL HTTP_OpenConnection(http_request_t *lpwhr) bSuccess = TRUE; lend: - lpwhr->read_pos = lpwhr->read_size = 0; - lpwhr->read_chunked = FALSE; - TRACE("%d <--\n", bSuccess); return bSuccess; } @@ -4400,7 +3680,7 @@ lend: * * clear out any old response headers */ -static void HTTP_clear_response_headers( http_request_t *lpwhr ) +static void HTTP_clear_response_headers( LPWININETHTTPREQW lpwhr ) { DWORD i; @@ -4427,20 +3707,20 @@ static void HTTP_clear_response_headers( http_request_t *lpwhr ) * TRUE on success * FALSE on error */ -static INT HTTP_GetResponseHeaders(http_request_t *lpwhr, BOOL clear) +static INT HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr, BOOL clear) { INT cbreaks = 0; WCHAR buffer[MAX_REPLY_LEN]; DWORD buflen = MAX_REPLY_LEN; BOOL bSuccess = FALSE; INT rc = 0; + static const WCHAR szCrLf[] = {'\r','\n',0}; + static const WCHAR szHundred[] = {'1','0','0',0}; char bufferA[MAX_REPLY_LEN]; - LPWSTR status_code = NULL, status_text = NULL; + LPWSTR status_code, status_text; DWORD cchMaxRawHeaders = 1024; LPWSTR lpszRawHeaders = HeapAlloc(GetProcessHeap(), 0, (cchMaxRawHeaders+1)*sizeof(WCHAR)); - LPWSTR temp; DWORD cchRawHeaders = 0; - BOOL codeHundred = FALSE; TRACE("-->\n"); @@ -4451,41 +3731,36 @@ static INT HTTP_GetResponseHeaders(http_request_t *lpwhr, BOOL clear) goto lend; do { - static const WCHAR szHundred[] = {'1','0','0',0}; + /* + * HACK peek at the buffer + */ + buflen = MAX_REPLY_LEN; + NETCON_recv(&lpwhr->netConnection, buffer, buflen, MSG_PEEK, &rc); + /* * We should first receive 'HTTP/1.x nnn OK' where nnn is the status code. */ - buflen = MAX_REPLY_LEN; - if (!read_line(lpwhr, bufferA, &buflen)) + memset(buffer, 0, MAX_REPLY_LEN); + if (!NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen)) goto lend; - rc += buflen; MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN ); - /* check is this a status code line? */ - if (!strncmpW(buffer, g_szHttp1_0, 4)) - { - /* split the version from the status code */ - status_code = strchrW( buffer, ' ' ); - if( !status_code ) - goto lend; - *status_code++=0; - /* split the status code from the status text */ - status_text = strchrW( status_code, ' ' ); - if( !status_text ) - goto lend; - *status_text++=0; - - TRACE("version [%s] status code [%s] status text [%s]\n", - debugstr_w(buffer), debugstr_w(status_code), debugstr_w(status_text) ); - - codeHundred = (!strcmpW(status_code, szHundred)); - } - else if (!codeHundred) - { - FIXME("Non status line at head of response (%s)\n",debugstr_w(buffer)); + /* split the version from the status code */ + status_code = strchrW( buffer, ' ' ); + if( !status_code ) goto lend; - } - } while (codeHundred); + *status_code++=0; + + /* split the status code from the status text */ + status_text = strchrW( status_code, ' ' ); + if( !status_text ) + goto lend; + *status_text++=0; + + TRACE("version [%s] status code [%s] status text [%s]\n", + debugstr_w(buffer), debugstr_w(status_code), debugstr_w(status_text) ); + + } while (!strcmpW(status_code, szHundred)); /* ignore "100 Continue" responses */ /* Add status code */ HTTP_ProcessHeader(lpwhr, szStatus, status_code, @@ -4494,8 +3769,8 @@ static INT HTTP_GetResponseHeaders(http_request_t *lpwhr, BOOL clear) HeapFree(GetProcessHeap(),0,lpwhr->lpszVersion); HeapFree(GetProcessHeap(),0,lpwhr->lpszStatusText); - lpwhr->lpszVersion = heap_strdupW(buffer); - lpwhr->lpszStatusText = heap_strdupW(status_text); + lpwhr->lpszVersion= WININET_strdupW(buffer); + lpwhr->lpszStatusText = WININET_strdupW(status_text); /* Restore the spaces */ *(status_code-1) = ' '; @@ -4503,10 +3778,10 @@ static INT HTTP_GetResponseHeaders(http_request_t *lpwhr, BOOL clear) /* regenerate raw headers */ while (cchRawHeaders + buflen + strlenW(szCrLf) > cchMaxRawHeaders) + { cchMaxRawHeaders *= 2; - temp = HeapReAlloc(GetProcessHeap(), 0, lpszRawHeaders, (cchMaxRawHeaders+1)*sizeof(WCHAR)); - if (temp == NULL) goto lend; - lpszRawHeaders = temp; + lpszRawHeaders = HeapReAlloc(GetProcessHeap(), 0, lpszRawHeaders, (cchMaxRawHeaders+1)*sizeof(WCHAR)); + } memcpy(lpszRawHeaders+cchRawHeaders, buffer, (buflen-1)*sizeof(WCHAR)); cchRawHeaders += (buflen-1); memcpy(lpszRawHeaders+cchRawHeaders, szCrLf, sizeof(szCrLf)); @@ -4517,35 +3792,33 @@ static INT HTTP_GetResponseHeaders(http_request_t *lpwhr, BOOL clear) do { buflen = MAX_REPLY_LEN; - if (read_line(lpwhr, bufferA, &buflen)) + if (NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen)) { LPWSTR * pFieldAndValue; TRACE("got line %s, now interpreting\n", debugstr_a(bufferA)); - - if (!bufferA[0]) break; MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN ); - pFieldAndValue = HTTP_InterpretHttpHeader(buffer); - if (pFieldAndValue) + while (cchRawHeaders + buflen + strlenW(szCrLf) > cchMaxRawHeaders) { - while (cchRawHeaders + buflen + strlenW(szCrLf) > cchMaxRawHeaders) - cchMaxRawHeaders *= 2; - temp = HeapReAlloc(GetProcessHeap(), 0, lpszRawHeaders, (cchMaxRawHeaders+1)*sizeof(WCHAR)); - if (temp == NULL) goto lend; - lpszRawHeaders = temp; - memcpy(lpszRawHeaders+cchRawHeaders, buffer, (buflen-1)*sizeof(WCHAR)); - cchRawHeaders += (buflen-1); - memcpy(lpszRawHeaders+cchRawHeaders, szCrLf, sizeof(szCrLf)); - cchRawHeaders += sizeof(szCrLf)/sizeof(szCrLf[0])-1; - lpszRawHeaders[cchRawHeaders] = '\0'; - - HTTP_ProcessHeader(lpwhr, pFieldAndValue[0], pFieldAndValue[1], - HTTP_ADDREQ_FLAG_ADD ); - - HTTP_FreeTokens(pFieldAndValue); + cchMaxRawHeaders *= 2; + lpszRawHeaders = HeapReAlloc(GetProcessHeap(), 0, lpszRawHeaders, (cchMaxRawHeaders+1)*sizeof(WCHAR)); } - } + memcpy(lpszRawHeaders+cchRawHeaders, buffer, (buflen-1)*sizeof(WCHAR)); + cchRawHeaders += (buflen-1); + memcpy(lpszRawHeaders+cchRawHeaders, szCrLf, sizeof(szCrLf)); + cchRawHeaders += sizeof(szCrLf)/sizeof(szCrLf[0])-1; + lpszRawHeaders[cchRawHeaders] = '\0'; + + pFieldAndValue = HTTP_InterpretHttpHeader(buffer); + if (!pFieldAndValue) + break; + + HTTP_ProcessHeader(lpwhr, pFieldAndValue[0], pFieldAndValue[1], + HTTP_ADDREQ_FLAG_ADD ); + + HTTP_FreeTokens(pFieldAndValue); + } else { cbreaks++; @@ -4554,19 +3827,6 @@ static INT HTTP_GetResponseHeaders(http_request_t *lpwhr, BOOL clear) } }while(1); - /* make sure the response header is terminated with an empty line. Some apps really - truly care about that empty line being there for some reason. Just add it to the - header. */ - if (cchRawHeaders + strlenW(szCrLf) > cchMaxRawHeaders) - { - cchMaxRawHeaders = cchRawHeaders + strlenW(szCrLf); - temp = HeapReAlloc(GetProcessHeap(), 0, lpszRawHeaders, (cchMaxRawHeaders + 1) * sizeof(WCHAR)); - if (temp == NULL) goto lend; - lpszRawHeaders = temp; - } - - memcpy(&lpszRawHeaders[cchRawHeaders], szCrLf, sizeof(szCrLf)); - HeapFree(GetProcessHeap(), 0, lpwhr->lpszRawHeaders); lpwhr->lpszRawHeaders = lpszRawHeaders; TRACE("raw headers: %s\n", debugstr_w(lpszRawHeaders)); @@ -4584,6 +3844,27 @@ lend: } } + +static void strip_spaces(LPWSTR start) +{ + LPWSTR str = start; + LPWSTR end; + + while (*str == ' ' && *str != '\0') + str++; + + if (str != start) + memmove(start, str, sizeof(WCHAR) * (strlenW(str) + 1)); + + end = start + strlenW(start) - 1; + while (end >= start && *end == ' ') + { + *end = '\0'; + end--; + } +} + + /*********************************************************************** * HTTP_InterpretHttpHeader (internal) * @@ -4648,7 +3929,7 @@ static LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer) #define COALESCEFLAGS (HTTP_ADDHDR_FLAG_COALESCE|HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA|HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON) -static BOOL HTTP_ProcessHeader(http_request_t *lpwhr, LPCWSTR field, LPCWSTR value, DWORD dwModifier) +static BOOL HTTP_ProcessHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field, LPCWSTR value, DWORD dwModifier) { LPHTTPHEADERW lphttpHdr = NULL; BOOL bSuccess = FALSE; @@ -4770,12 +4051,30 @@ static BOOL HTTP_ProcessHeader(http_request_t *lpwhr, LPCWSTR field, LPCWSTR val * Called when all content from server has been read by client. * */ -static BOOL HTTP_FinishedReading(http_request_t *lpwhr) +BOOL HTTP_FinishedReading(LPWININETHTTPREQW lpwhr) { - BOOL keepalive = HTTP_KeepAlive(lpwhr); + WCHAR szVersion[10]; + WCHAR szConnectionResponse[20]; + DWORD dwBufferSize = sizeof(szVersion); + BOOL keepalive = FALSE; TRACE("\n"); + /* as per RFC 2068, S8.1.2.1, if the client is HTTP/1.1 then assume that + * the connection is keep-alive by default */ + if (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_VERSION, szVersion, + &dwBufferSize, NULL) || + strcmpiW(szVersion, g_szHttp1_1)) + { + keepalive = TRUE; + } + + dwBufferSize = sizeof(szConnectionResponse); + if (HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_PROXY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) || + HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL)) + { + keepalive = !strcmpiW(szConnectionResponse, szKeepAlive); + } if (!keepalive) { @@ -4794,7 +4093,7 @@ static BOOL HTTP_FinishedReading(http_request_t *lpwhr) * Return index of custom header from header array * */ -static INT HTTP_GetCustomHeaderIndex(http_request_t *lpwhr, LPCWSTR lpszField, +static INT HTTP_GetCustomHeaderIndex(LPWININETHTTPREQW lpwhr, LPCWSTR lpszField, int requested_index, BOOL request_only) { DWORD index; @@ -4831,7 +4130,7 @@ static INT HTTP_GetCustomHeaderIndex(http_request_t *lpwhr, LPCWSTR lpszField, * Insert header into array * */ -static BOOL HTTP_InsertCustomHeader(http_request_t *lpwhr, LPHTTPHEADERW lpHdr) +static BOOL HTTP_InsertCustomHeader(LPWININETHTTPREQW lpwhr, LPHTTPHEADERW lpHdr) { INT count; LPHTTPHEADERW lph = NULL; @@ -4847,8 +4146,8 @@ static BOOL HTTP_InsertCustomHeader(http_request_t *lpwhr, LPHTTPHEADERW lpHdr) if (NULL != lph) { lpwhr->pCustHeaders = lph; - lpwhr->pCustHeaders[count-1].lpszField = heap_strdupW(lpHdr->lpszField); - lpwhr->pCustHeaders[count-1].lpszValue = heap_strdupW(lpHdr->lpszValue); + lpwhr->pCustHeaders[count-1].lpszField = WININET_strdupW(lpHdr->lpszField); + lpwhr->pCustHeaders[count-1].lpszValue = WININET_strdupW(lpHdr->lpszValue); lpwhr->pCustHeaders[count-1].wFlags = lpHdr->wFlags; lpwhr->pCustHeaders[count-1].wCount= lpHdr->wCount; lpwhr->nCustHeaders++; @@ -4869,7 +4168,7 @@ static BOOL HTTP_InsertCustomHeader(http_request_t *lpwhr, LPHTTPHEADERW lpHdr) * Delete header from array * If this function is called, the indexs may change. */ -static BOOL HTTP_DeleteCustomHeader(http_request_t *lpwhr, DWORD index) +static BOOL HTTP_DeleteCustomHeader(LPWININETHTTPREQW lpwhr, DWORD index) { if( lpwhr->nCustHeaders <= 0 ) return FALSE; @@ -4894,7 +4193,7 @@ static BOOL HTTP_DeleteCustomHeader(http_request_t *lpwhr, DWORD index) * Verify the given header is not invalid for the given http request * */ -static BOOL HTTP_VerifyValidHeader(http_request_t *lpwhr, LPCWSTR field) +static BOOL HTTP_VerifyValidHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field) { /* Accept-Encoding is stripped from HTTP/1.0 requests. It is invalid */ if (!strcmpW(lpwhr->lpszVersion, g_szHttp1_0) && !strcmpiW(field, szAccept_Encoding)) diff --git a/reactos/dll/win32/wininet/internet.c b/reactos/dll/win32/wininet/internet.c index f61074c438f..bad795ddbd4 100644 --- a/reactos/dll/win32/wininet/internet.c +++ b/reactos/dll/win32/wininet/internet.c @@ -31,10 +31,6 @@ #define MAXHOSTNAME 100 /* from http.c */ -#if defined(__MINGW32__) || defined (_MSC_VER) -#include -#endif - #include #include #include @@ -101,13 +97,13 @@ static CRITICAL_SECTION_DEBUG WININET_cs_debug = }; static CRITICAL_SECTION WININET_cs = { &WININET_cs_debug, -1, 0, 0, 0, 0 }; -static object_header_t **WININET_Handles; +static LPWININETHANDLEHEADER *WININET_Handles; static UINT WININET_dwNextHandle; static UINT WININET_dwMaxHandles; -HINTERNET WININET_AllocHandle( object_header_t *info ) +HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info ) { - object_header_t **p; + LPWININETHANDLEHEADER *p; UINT handle = 0, num; list_init( &info->children ); @@ -117,7 +113,7 @@ HINTERNET WININET_AllocHandle( object_header_t *info ) { num = HANDLE_CHUNK_SIZE; p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof (*WININET_Handles)* num); + sizeof (UINT)* num); if( !p ) goto end; WININET_Handles = p; @@ -127,7 +123,7 @@ HINTERNET WININET_AllocHandle( object_header_t *info ) { num = WININET_dwMaxHandles + HANDLE_CHUNK_SIZE; p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, - WININET_Handles, sizeof (*WININET_Handles)* num); + WININET_Handles, sizeof (UINT)* num); if( !p ) goto end; WININET_Handles = p; @@ -149,16 +145,16 @@ end: return info->hInternet = (HINTERNET) (handle+1); } -object_header_t *WININET_AddRef( object_header_t *info ) +LPWININETHANDLEHEADER WININET_AddRef( LPWININETHANDLEHEADER info ) { ULONG refs = InterlockedIncrement(&info->refs); TRACE("%p -> refcount = %d\n", info, refs ); return info; } -object_header_t *WININET_GetObject( HINTERNET hinternet ) +LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet ) { - object_header_t *info = NULL; + LPWININETHANDLEHEADER info = NULL; UINT handle = (UINT) hinternet; EnterCriticalSection( &WININET_cs ); @@ -174,7 +170,7 @@ object_header_t *WININET_GetObject( HINTERNET hinternet ) return info; } -BOOL WININET_Release( object_header_t *info ) +BOOL WININET_Release( LPWININETHANDLEHEADER info ) { ULONG refs = InterlockedDecrement(&info->refs); TRACE( "object %p refcount = %d\n", info, refs ); @@ -186,8 +182,7 @@ BOOL WININET_Release( object_header_t *info ) info->vtbl->CloseConnection( info ); } /* Don't send a callback if this is a session handle created with InternetOpenUrl */ - if ((info->htype != WH_HHTTPSESSION && info->htype != WH_HFTPSESSION) - || !(info->dwInternalFlags & INET_OPENURL)) + if (info->htype != WH_HHTTPSESSION || !(info->dwInternalFlags & INET_OPENURL)) { INTERNET_SendCallback(info, info->dwContext, INTERNET_STATUS_HANDLE_CLOSING, &info->hInternet, @@ -205,7 +200,7 @@ BOOL WININET_FreeHandle( HINTERNET hinternet ) { BOOL ret = FALSE; UINT handle = (UINT) hinternet; - object_header_t *info = NULL, *child, *next; + LPWININETHANDLEHEADER info = NULL, child, next; EnterCriticalSection( &WININET_cs ); @@ -229,7 +224,7 @@ BOOL WININET_FreeHandle( HINTERNET hinternet ) if( info ) { /* Free all children as native does */ - LIST_FOR_EACH_ENTRY_SAFE( child, next, &info->children, object_header_t, entry ) + LIST_FOR_EACH_ENTRY_SAFE( child, next, &info->children, WININETHANDLEHEADER, entry ) { TRACE( "freeing child handle %d for parent handle %d\n", (UINT)child->hInternet, handle+1); @@ -290,8 +285,6 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) case DLL_PROCESS_DETACH: - NETCON_unload(); - URLCacheContainers_DeleteAll(); if (g_dwTlsErrIndex != TLS_OUT_OF_INDEXES) @@ -350,7 +343,7 @@ BOOL WINAPI DetectAutoProxyUrl(LPSTR lpszAutoProxyUrl, * The proxy may be specified in the form 'http=proxy.my.org' * Presumably that means there can be ftp=ftpproxy.my.org too. */ -static BOOL INTERNET_ConfigureProxy( appinfo_t *lpwai ) +static BOOL INTERNET_ConfigureProxy( LPWININETAPPINFOW lpwai ) { HKEY key; DWORD type, len, enabled = 0; @@ -417,11 +410,8 @@ static BOOL INTERNET_ConfigureProxy( appinfo_t *lpwai ) TRACE("http proxy (from environment) = %s\n", debugstr_w(lpwai->lpszProxy)); enabled = 1; } - if (!enabled) - { - TRACE("Proxy is not enabled.\n"); - lpwai->dwAccessType = INTERNET_OPEN_TYPE_DIRECT; - } + if (!enabled) TRACE("Proxy is not enabled.\n"); + RegCloseKey( key ); return (enabled > 0); } @@ -469,8 +459,8 @@ static void dump_INTERNET_FLAGS(DWORD dwFlags) FE(INTERNET_FLAG_TRANSFER_BINARY) }; #undef FE - unsigned int i; - + int i; + for (i = 0; i < (sizeof(flag) / sizeof(flag[0])); i++) { if (flag[i].val & dwFlags) { TRACE(" %s", flag[i].name); @@ -489,9 +479,9 @@ static void dump_INTERNET_FLAGS(DWORD dwFlags) * Close internet handle * */ -static VOID APPINFO_Destroy(object_header_t *hdr) +static VOID APPINFO_Destroy(WININETHANDLEHEADER *hdr) { - appinfo_t *lpwai = (appinfo_t*)hdr; + LPWININETAPPINFOW lpwai = (LPWININETAPPINFOW) hdr; TRACE("%p\n",lpwai); @@ -503,9 +493,9 @@ static VOID APPINFO_Destroy(object_header_t *hdr) HeapFree(GetProcessHeap(), 0, lpwai); } -static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) +static DWORD APPINFO_QueryOption(WININETHANDLEHEADER *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode) { - appinfo_t *ai = (appinfo_t*)hdr; + LPWININETAPPINFOW ai = (LPWININETAPPINFOW)hdr; switch(option) { case INTERNET_OPTION_HANDLE_TYPE: @@ -526,36 +516,17 @@ static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffe bufsize = *size; if (unicode) { - DWORD len = ai->lpszAgent ? strlenW(ai->lpszAgent) : 0; - - *size = (len + 1) * sizeof(WCHAR); + *size = (strlenW(ai->lpszAgent) + 1) * sizeof(WCHAR); if(!buffer || bufsize < *size) return ERROR_INSUFFICIENT_BUFFER; - if (ai->lpszAgent) - strcpyW(buffer, ai->lpszAgent); - else - *(WCHAR *)buffer = 0; - /* If the buffer is copied, the returned length doesn't include - * the NULL terminator. - */ - *size = len * sizeof(WCHAR); + strcpyW(buffer, ai->lpszAgent); }else { - if (ai->lpszAgent) - *size = WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, NULL, 0, NULL, NULL); - else - *size = 1; + *size = WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, NULL, 0, NULL, NULL); if(!buffer || bufsize < *size) return ERROR_INSUFFICIENT_BUFFER; - if (ai->lpszAgent) - WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, buffer, *size, NULL, NULL); - else - *(char *)buffer = 0; - /* If the buffer is copied, the returned length doesn't include - * the NULL terminator. - */ - *size -= 1; + WideCharToMultiByte(CP_ACP, 0, ai->lpszAgent, -1, buffer, *size, NULL, NULL); } return ERROR_SUCCESS; @@ -572,10 +543,8 @@ static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffe if (ai->lpszProxyBypass) proxyBypassBytesRequired = (lstrlenW(ai->lpszProxyBypass) + 1) * sizeof(WCHAR); if (*size < sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired) - { - *size = sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired + proxyBypassBytesRequired; - return ERROR_INSUFFICIENT_BUFFER; - } + return ERROR_INSUFFICIENT_BUFFER; + proxy = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW)); proxy_bypass = (LPWSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOW) + proxyBytesRequired); @@ -605,10 +574,8 @@ static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffe proxyBypassBytesRequired = WideCharToMultiByte(CP_ACP, 0, ai->lpszProxyBypass, -1, NULL, 0, NULL, NULL); if (*size < sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired) - { - *size = sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired + proxyBypassBytesRequired; return ERROR_INSUFFICIENT_BUFFER; - } + proxy = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA)); proxy_bypass = (LPSTR)((LPBYTE)buffer + sizeof(INTERNET_PROXY_INFOA) + proxyBytesRequired); @@ -634,7 +601,7 @@ static DWORD APPINFO_QueryOption(object_header_t *hdr, DWORD option, void *buffe return INET_QueryOption(option, buffer, size, unicode); } -static const object_vtbl_t APPINFOVtbl = { +static const HANDLEHEADERVtbl APPINFOVtbl = { APPINFO_Destroy, NULL, APPINFO_QueryOption, @@ -660,7 +627,7 @@ static const object_vtbl_t APPINFOVtbl = { HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags) { - appinfo_t *lpwai = NULL; + LPWININETAPPINFOW lpwai = NULL; HINTERNET handle = NULL; if (TRACE_ON(wininet)) { @@ -691,7 +658,7 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, /* Clear any error information */ INTERNET_SetLastError(0); - lpwai = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(appinfo_t)); + lpwai = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETAPPINFOW)); if (NULL == lpwai) { INTERNET_SetLastError(ERROR_OUTOFMEMORY); @@ -714,12 +681,30 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, goto lend; } - lpwai->lpszAgent = heap_strdupW(lpszAgent); + if (NULL != lpszAgent) + { + lpwai->lpszAgent = HeapAlloc( GetProcessHeap(),0, + (strlenW(lpszAgent)+1)*sizeof(WCHAR)); + if (lpwai->lpszAgent) + lstrcpyW( lpwai->lpszAgent, lpszAgent ); + } if(dwAccessType == INTERNET_OPEN_TYPE_PRECONFIG) INTERNET_ConfigureProxy( lpwai ); - else - lpwai->lpszProxy = heap_strdupW(lpszProxy); - lpwai->lpszProxyBypass = heap_strdupW(lpszProxyBypass); + else if (NULL != lpszProxy) + { + lpwai->lpszProxy = HeapAlloc( GetProcessHeap(), 0, + (strlenW(lpszProxy)+1)*sizeof(WCHAR)); + if (lpwai->lpszProxy) + lstrcpyW( lpwai->lpszProxy, lpszProxy ); + } + + if (NULL != lpszProxyBypass) + { + lpwai->lpszProxyBypass = HeapAlloc( GetProcessHeap(), 0, + (strlenW(lpszProxyBypass)+1)*sizeof(WCHAR)); + if (lpwai->lpszProxyBypass) + lstrcpyW( lpwai->lpszProxyBypass, lpszProxyBypass ); + } lend: if( lpwai ) @@ -744,15 +729,33 @@ lend: HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType, LPCSTR lpszProxy, LPCSTR lpszProxyBypass, DWORD dwFlags) { - WCHAR *szAgent, *szProxy, *szBypass; - HINTERNET rc; + HINTERNET rc = NULL; + INT len; + WCHAR *szAgent = NULL, *szProxy = NULL, *szBypass = NULL; TRACE("(%s, 0x%08x, %s, %s, 0x%08x)\n", debugstr_a(lpszAgent), dwAccessType, debugstr_a(lpszProxy), debugstr_a(lpszProxyBypass), dwFlags); - szAgent = heap_strdupAtoW(lpszAgent); - szProxy = heap_strdupAtoW(lpszProxy); - szBypass = heap_strdupAtoW(lpszProxyBypass); + if( lpszAgent ) + { + len = MultiByteToWideChar(CP_ACP, 0, lpszAgent, -1, NULL, 0); + szAgent = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpszAgent, -1, szAgent, len); + } + + if( lpszProxy ) + { + len = MultiByteToWideChar(CP_ACP, 0, lpszProxy, -1, NULL, 0); + szProxy = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpszProxy, -1, szProxy, len); + } + + if( lpszProxyBypass ) + { + len = MultiByteToWideChar(CP_ACP, 0, lpszProxyBypass, -1, NULL, 0); + szBypass = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpszProxyBypass, -1, szBypass, len); + } rc = InternetOpenW(szAgent, dwAccessType, szProxy, szBypass, dwFlags); @@ -776,7 +779,7 @@ HINTERNET WINAPI InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType, BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError, LPSTR lpszBuffer, LPDWORD lpdwBufferLength) { - LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex); + LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); TRACE("\n"); @@ -813,7 +816,7 @@ BOOL WINAPI InternetGetLastResponseInfoA(LPDWORD lpdwError, BOOL WINAPI InternetGetLastResponseInfoW(LPDWORD lpdwError, LPWSTR lpszBuffer, LPDWORD lpdwBufferLength) { - LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex); + LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); TRACE("\n"); @@ -853,7 +856,7 @@ BOOL WINAPI InternetGetConnectedState(LPDWORD lpdwStatus, DWORD dwReserved) TRACE("(%p, 0x%08x)\n", lpdwStatus, dwReserved); if (lpdwStatus) { - WARN("always returning LAN connection.\n"); + FIXME("always returning LAN connection.\n"); *lpdwStatus = INTERNET_CONNECTION_LAN; } return TRUE; @@ -897,7 +900,7 @@ BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnecti return FALSE; if (lpdwStatus) { - WARN("always returning LAN connection.\n"); + FIXME("always returning LAN connection.\n"); *lpdwStatus = INTERNET_CONNECTION_LAN; } return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen); @@ -947,7 +950,7 @@ HINTERNET WINAPI InternetConnectW(HINTERNET hInternet, LPCWSTR lpszUserName, LPCWSTR lpszPassword, DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext) { - appinfo_t *hIC; + LPWININETAPPINFOW hIC; HINTERNET rc = NULL; TRACE("(%p, %s, %i, %s, %s, %i, %i, %lx)\n", hInternet, debugstr_w(lpszServerName), @@ -962,7 +965,7 @@ HINTERNET WINAPI InternetConnectW(HINTERNET hInternet, /* Clear any error information */ INTERNET_SetLastError(0); - hIC = (appinfo_t*)WININET_GetObject( hInternet ); + hIC = (LPWININETAPPINFOW) WININET_GetObject( hInternet ); if ( (hIC == NULL) || (hIC->hdr.htype != WH_HINIT) ) { INTERNET_SetLastError(ERROR_INVALID_HANDLE); @@ -1010,13 +1013,30 @@ HINTERNET WINAPI InternetConnectA(HINTERNET hInternet, DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext) { HINTERNET rc = NULL; - LPWSTR szServerName; - LPWSTR szUserName; - LPWSTR szPassword; + INT len = 0; + LPWSTR szServerName = NULL; + LPWSTR szUserName = NULL; + LPWSTR szPassword = NULL; + + if (lpszServerName) + { + len = MultiByteToWideChar(CP_ACP, 0, lpszServerName, -1, NULL, 0); + szServerName = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpszServerName, -1, szServerName, len); + } + if (lpszUserName) + { + len = MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, NULL, 0); + szUserName = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, szUserName, len); + } + if (lpszPassword) + { + len = MultiByteToWideChar(CP_ACP, 0, lpszPassword, -1, NULL, 0); + szPassword = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpszPassword, -1, szPassword, len); + } - szServerName = heap_strdupAtoW(lpszServerName); - szUserName = heap_strdupAtoW(lpszUserName); - szPassword = heap_strdupAtoW(lpszPassword); rc = InternetConnectW(hInternet, szServerName, nServerPort, szUserName, szPassword, dwService, dwFlags, dwContext); @@ -1061,7 +1081,7 @@ BOOL WINAPI InternetFindNextFileA(HINTERNET hFind, LPVOID lpvFindData) */ BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData) { - object_header_t *hdr; + WININETHANDLEHEADER *hdr; DWORD res; TRACE("\n"); @@ -1099,7 +1119,7 @@ BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData) */ BOOL WINAPI InternetCloseHandle(HINTERNET hInternet) { - object_header_t *lpwh; + LPWININETHANDLEHEADER lpwh; TRACE("%p\n",hInternet); @@ -1133,14 +1153,11 @@ static void ConvertUrlComponentValue(LPSTR* lppszComponent, LPDWORD dwComponentL DWORD nASCIILength=WideCharToMultiByte(CP_ACP,0,lpwszComponent,dwwComponentLen,NULL,0,NULL,NULL); if (*lppszComponent == NULL) { + int nASCIIOffset=WideCharToMultiByte(CP_ACP,0,lpwszStart,lpwszComponent-lpwszStart,NULL,0,NULL,NULL); if (lpwszComponent) - { - int offset = WideCharToMultiByte(CP_ACP, 0, lpwszStart, lpwszComponent-lpwszStart, NULL, 0, NULL, NULL); - *lppszComponent = (LPSTR)lpszStart + offset; - } + *lppszComponent = (LPSTR)lpszStart+nASCIIOffset; else *lppszComponent = NULL; - *dwComponentLen = nASCIILength; } else @@ -1187,7 +1204,7 @@ BOOL WINAPI InternetCrackUrlA(LPCSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, InternetCrackUrlW should not include it */ if (dwUrlLength == -1) nLength--; - lpwszUrl = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR)); + lpwszUrl=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR)*nLength); MultiByteToWideChar(CP_ACP,0,lpszUrl,dwUrlLength,lpwszUrl,nLength); memset(&UCW,0,sizeof(UCW)); @@ -1426,7 +1443,7 @@ BOOL WINAPI InternetCrackUrlW(LPCWSTR lpszUrl_orig, DWORD dwUrlLength_orig, DWOR /* Determine if the URI is absolute. */ while (lpszap - lpszUrl < dwUrlLength) { - if (isalnumW(*lpszap) || *lpszap == '+' || *lpszap == '.' || *lpszap == '-') + if (isalnumW(*lpszap)) { lpszap++; continue; @@ -1448,11 +1465,8 @@ BOOL WINAPI InternetCrackUrlW(LPCWSTR lpszUrl_orig, DWORD dwUrlLength_orig, DWOR lpUC->nPort = INTERNET_INVALID_PORT_NUMBER; /* Parse */ - lpszParam = memchrW(lpszap, ';', dwUrlLength - (lpszap - lpszUrl)); - if(!lpszParam) + if (!(lpszParam = memchrW(lpszap, ';', dwUrlLength - (lpszap - lpszUrl)))) lpszParam = memchrW(lpszap, '?', dwUrlLength - (lpszap - lpszUrl)); - if(!lpszParam) - lpszParam = memchrW(lpszap, '#', dwUrlLength - (lpszap - lpszUrl)); SetUrlComponentValueW(&lpUC->lpszExtraInfo, &lpUC->dwExtraInfoLength, lpszParam, lpszParam ? dwUrlLength-(lpszParam-lpszUrl) : 0); @@ -1769,7 +1783,7 @@ BOOL WINAPI InternetCanonicalizeUrlW(LPCWSTR lpszUrl, LPWSTR lpszBuffer, /* #################################################### */ static INTERNET_STATUS_CALLBACK set_status_callback( - object_header_t *lpwh, INTERNET_STATUS_CALLBACK callback, BOOL unicode) + LPWININETHANDLEHEADER lpwh, INTERNET_STATUS_CALLBACK callback, BOOL unicode) { INTERNET_STATUS_CALLBACK ret; @@ -1797,10 +1811,10 @@ INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA( HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB) { INTERNET_STATUS_CALLBACK retVal; - object_header_t *lpwh; - - TRACE("%p\n", hInternet); + LPWININETHANDLEHEADER lpwh; + TRACE("0x%08x\n", (ULONG)hInternet); + if (!(lpwh = WININET_GetObject(hInternet))) return INTERNET_INVALID_STATUS_CALLBACK; @@ -1825,9 +1839,9 @@ INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW( HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB) { INTERNET_STATUS_CALLBACK retVal; - object_header_t *lpwh; + LPWININETHANDLEHEADER lpwh; - TRACE("%p\n", hInternet); + TRACE("0x%08x\n", (ULONG)hInternet); if (!(lpwh = WININET_GetObject(hInternet))) return INTERNET_INVALID_STATUS_CALLBACK; @@ -1861,7 +1875,7 @@ DWORD WINAPI InternetSetFilePointer(HINTERNET hFile, LONG lDistanceToMove, BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer, DWORD dwNumOfBytesToWrite, LPDWORD lpdwNumOfBytesWritten) { - object_header_t *lpwh; + LPWININETHANDLEHEADER lpwh; BOOL retval = FALSE; TRACE("(%p %p %d %p)\n", hFile, lpBuffer, dwNumOfBytesToWrite, lpdwNumOfBytesWritten); @@ -1900,7 +1914,7 @@ BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer, BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer, DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead) { - object_header_t *hdr; + LPWININETHANDLEHEADER hdr; DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE; TRACE("%p %p %d %p\n", hFile, lpBuffer, dwNumOfBytesToRead, pdwNumOfBytesRead); @@ -1954,7 +1968,7 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer, BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext) { - object_header_t *hdr; + LPWININETHANDLEHEADER hdr; DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE; TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffersOut, dwFlags, dwContext); @@ -1980,40 +1994,33 @@ BOOL WINAPI InternetReadFileExA(HINTERNET hFile, LPINTERNET_BUFFERSA lpBuffersOu /*********************************************************************** * InternetReadFileExW (WININET.@) - * SEE - * InternetReadFileExA() + * + * Read data from an open internet file. + * + * PARAMS + * hFile [I] Handle returned by InternetOpenUrl() or HttpOpenRequest(). + * lpBuffersOut [I/O] Buffer. + * dwFlags [I] Flags. + * dwContext [I] Context for callbacks. + * + * RETURNS + * FALSE, last error is set to ERROR_CALL_NOT_IMPLEMENTED + * + * NOTES + * Not implemented in Wine or native either (as of IE6 SP2). + * */ BOOL WINAPI InternetReadFileExW(HINTERNET hFile, LPINTERNET_BUFFERSW lpBuffer, DWORD dwFlags, DWORD_PTR dwContext) { - object_header_t *hdr; - DWORD res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE; + ERR("(%p, %p, 0x%x, 0x%lx): not implemented in native\n", hFile, lpBuffer, dwFlags, dwContext); - TRACE("(%p %p 0x%x 0x%lx)\n", hFile, lpBuffer, dwFlags, dwContext); - - hdr = WININET_GetObject(hFile); - if (!hdr) { - INTERNET_SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - - if(hdr->vtbl->ReadFileExW) - res = hdr->vtbl->ReadFileExW(hdr, lpBuffer, dwFlags, dwContext); - - WININET_Release(hdr); - - TRACE("-- %s (%u, bytes read: %d)\n", res == ERROR_SUCCESS ? "TRUE": "FALSE", - res, lpBuffer->dwBufferLength); - - if(res != ERROR_SUCCESS) - SetLastError(res); - return res == ERROR_SUCCESS; + INTERNET_SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; } DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) { - static BOOL warn = TRUE; - switch(option) { case INTERNET_OPTION_REQUEST_FLAGS: TRACE("INTERNET_OPTION_REQUEST_FLAGS\n"); @@ -2040,10 +2047,8 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) return ERROR_SUCCESS; case INTERNET_OPTION_CONNECTED_STATE: - if (warn) { - FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n"); - warn = FALSE; - } + FIXME("INTERNET_OPTION_CONNECTED_STATE: semi-stub\n"); + if (*size < sizeof(ULONG)) return ERROR_INSUFFICIENT_BUFFER; @@ -2053,16 +2058,13 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) return ERROR_SUCCESS; case INTERNET_OPTION_PROXY: { - appinfo_t ai; - BOOL ret; + WININETAPPINFOW ai; TRACE("Getting global proxy info\n"); - memset(&ai, 0, sizeof(appinfo_t)); + memset(&ai, 0, sizeof(WININETAPPINFOW)); INTERNET_ConfigureProxy(&ai); - ret = APPINFO_QueryOption(&ai.hdr, INTERNET_OPTION_PROXY, buffer, size, unicode); /* FIXME */ - APPINFO_Destroy(&ai.hdr); - return ret; + return APPINFO_QueryOption(&ai.hdr, INTERNET_OPTION_PROXY, buffer, size, unicode); /* FIXME */ } case INTERNET_OPTION_MAX_CONNS_PER_SERVER: @@ -2107,44 +2109,23 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) case INTERNET_OPTION_PER_CONNECTION_OPTION: { INTERNET_PER_CONN_OPTION_LISTW *con = buffer; - INTERNET_PER_CONN_OPTION_LISTA *conA = buffer; DWORD res = ERROR_SUCCESS, i; - appinfo_t ai; - - TRACE("Getting global proxy info\n"); - memset(&ai, 0, sizeof(appinfo_t)); - INTERNET_ConfigureProxy(&ai); FIXME("INTERNET_OPTION_PER_CONNECTION_OPTION stub\n"); - if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) { - APPINFO_Destroy(&ai.hdr); + if (*size < sizeof(INTERNET_PER_CONN_OPTION_LISTW)) return ERROR_INSUFFICIENT_BUFFER; - } for (i = 0; i < con->dwOptionCount; i++) { INTERNET_PER_CONN_OPTIONW *option = con->pOptions + i; - INTERNET_PER_CONN_OPTIONA *optionA = conA->pOptions + i; switch (option->dwOption) { case INTERNET_PER_CONN_FLAGS: - option->Value.dwValue = ai.dwAccessType; + option->Value.dwValue = PROXY_TYPE_DIRECT; break; case INTERNET_PER_CONN_PROXY_SERVER: - if (unicode) - option->Value.pszValue = heap_strdupW(ai.lpszProxy); - else - optionA->Value.pszValue = heap_strdupWtoA(ai.lpszProxy); - break; - case INTERNET_PER_CONN_PROXY_BYPASS: - if (unicode) - option->Value.pszValue = heap_strdupW(ai.lpszProxyBypass); - else - optionA->Value.pszValue = heap_strdupWtoA(ai.lpszProxyBypass); - break; - case INTERNET_PER_CONN_AUTOCONFIG_URL: case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS: case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL: @@ -2152,7 +2133,8 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME: case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: FIXME("Unhandled dwOption %d\n", option->dwOption); - memset(&option->Value, 0, sizeof(option->Value)); + option->Value.dwValue = 0; + res = ERROR_INVALID_PARAMETER; break; default: @@ -2161,12 +2143,9 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) break; } } - APPINFO_Destroy(&ai.hdr); return res; } - case INTERNET_OPTION_USER_AGENT: - return ERROR_INTERNET_INCORRECT_HANDLE_TYPE; } FIXME("Stub for %d\n", option); @@ -2186,7 +2165,7 @@ DWORD INET_QueryOption(DWORD option, void *buffer, DWORD *size, BOOL unicode) BOOL WINAPI InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength) { - object_header_t *hdr; + LPWININETHANDLEHEADER hdr; DWORD res = ERROR_INVALID_HANDLE; TRACE("%p %d %p %p\n", hInternet, dwOption, lpBuffer, lpdwBufferLength); @@ -2219,7 +2198,7 @@ BOOL WINAPI InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption, BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength) { - object_header_t *hdr; + LPWININETHANDLEHEADER hdr; DWORD res = ERROR_INVALID_HANDLE; TRACE("%p %d %p %p\n", hInternet, dwOption, lpBuffer, lpdwBufferLength); @@ -2253,12 +2232,12 @@ BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD dwOption, BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, DWORD dwBufferLength) { - object_header_t *lpwhh; + LPWININETHANDLEHEADER lpwhh; BOOL ret = TRUE; TRACE("(%p %d %p %d)\n", hInternet, dwOption, lpBuffer, dwBufferLength); - lpwhh = (object_header_t*) WININET_GetObject( hInternet ); + lpwhh = (LPWININETHANDLEHEADER) WININET_GetObject( hInternet ); if(lpwhh && lpwhh->vtbl->SetOption) { DWORD res; @@ -2277,14 +2256,9 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, { case INTERNET_OPTION_CALLBACK: { - if (!lpwhh) - { - INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); - return FALSE; - } - WININET_Release(lpwhh); - INTERNET_SetLastError(ERROR_INTERNET_OPTION_NOT_SETTABLE); - return FALSE; + INTERNET_STATUS_CALLBACK callback = *(INTERNET_STATUS_CALLBACK *)lpBuffer; + ret = (set_status_callback(lpwhh, callback, TRUE) != INTERNET_INVALID_STATUS_CALLBACK); + break; } case INTERNET_OPTION_HTTP_VERSION: { @@ -2368,35 +2342,8 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, case INTERNET_OPTION_DISABLE_AUTODIAL: FIXME("Option INTERNET_OPTION_DISABLE_AUTODIAL; STUB\n"); break; - case INTERNET_OPTION_HTTP_DECODING: - FIXME("INTERNET_OPTION_HTTP_DECODING; STUB\n"); - INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION); - ret = FALSE; - break; - case INTERNET_OPTION_COOKIES_3RD_PARTY: - FIXME("INTERNET_OPTION_COOKIES_3RD_PARTY; STUB\n"); - INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION); - ret = FALSE; - break; - case INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY: - FIXME("INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY; STUB\n"); - INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION); - ret = FALSE; - break; - case INTERNET_OPTION_CODEPAGE_PATH: - FIXME("INTERNET_OPTION_CODEPAGE_PATH; STUB\n"); - INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION); - ret = FALSE; - break; - case INTERNET_OPTION_CODEPAGE_EXTRA: - FIXME("INTERNET_OPTION_CODEPAGE_EXTRA; STUB\n"); - INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION); - ret = FALSE; - break; - case INTERNET_OPTION_IDN: - FIXME("INTERNET_OPTION_IDN; STUB\n"); - INTERNET_SetLastError(ERROR_INTERNET_INVALID_OPTION); - ret = FALSE; + case 86: + FIXME("86\n"); break; default: FIXME("Option %d STUB\n",dwOption); @@ -2433,16 +2380,13 @@ BOOL WINAPI InternetSetOptionA(HINTERNET hInternet, DWORD dwOption, { case INTERNET_OPTION_CALLBACK: { - object_header_t *lpwh; + LPWININETHANDLEHEADER lpwh; + INTERNET_STATUS_CALLBACK callback = *(INTERNET_STATUS_CALLBACK *)lpBuffer; - if (!(lpwh = WININET_GetObject(hInternet))) - { - INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); - return FALSE; - } + if (!(lpwh = WININET_GetObject(hInternet))) return FALSE; + r = (set_status_callback(lpwh, callback, FALSE) != INTERNET_INVALID_STATUS_CALLBACK); WININET_Release(lpwh); - INTERNET_SetLastError(ERROR_INTERNET_OPTION_NOT_SETTABLE); - return FALSE; + return r; } case INTERNET_OPTION_PROXY: { @@ -2531,18 +2475,6 @@ BOOL WINAPI InternetTimeFromSystemTimeA( const SYSTEMTIME* time, DWORD format, L TRACE( "%p 0x%08x %p 0x%08x\n", time, format, string, size ); - if (!time || !string || format != INTERNET_RFC1123_FORMAT) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if (size < INTERNET_RFC1123_BUFSIZE * sizeof(*string)) - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - return FALSE; - } - ret = InternetTimeFromSystemTimeW( time, format, stringW, sizeof(stringW) ); if (ret) WideCharToMultiByte( CP_ACP, 0, stringW, -1, string, size, NULL, NULL ); @@ -2560,17 +2492,10 @@ BOOL WINAPI InternetTimeFromSystemTimeW( const SYSTEMTIME* time, DWORD format, L TRACE( "%p 0x%08x %p 0x%08x\n", time, format, string, size ); - if (!time || !string || format != INTERNET_RFC1123_FORMAT) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + if (!time || !string) return FALSE; - if (size < INTERNET_RFC1123_BUFSIZE * sizeof(*string)) - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); + if (format != INTERNET_RFC1123_FORMAT || size < INTERNET_RFC1123_BUFSIZE * sizeof(WCHAR)) return FALSE; - } sprintfW( string, date, WININET_wkday[time->wDayOfWeek], @@ -2591,12 +2516,16 @@ BOOL WINAPI InternetTimeToSystemTimeA( LPCSTR string, SYSTEMTIME* time, DWORD re { BOOL ret = FALSE; WCHAR *stringW; + int len; TRACE( "%s %p 0x%08x\n", debugstr_a(string), time, reserved ); - stringW = heap_strdupAtoW(string); + len = MultiByteToWideChar( CP_ACP, 0, string, -1, NULL, 0 ); + stringW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + if (stringW) { + MultiByteToWideChar( CP_ACP, 0, string, -1, stringW, len ); ret = InternetTimeToSystemTimeW( stringW, time, reserved ); HeapFree( GetProcessHeap(), 0, stringW ); } @@ -2745,16 +2674,15 @@ BOOL WINAPI InternetCheckConnectionW( LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwRe if (dwFlags & FLAG_ICC_FORCE_CONNECTION) { - struct sockaddr_storage saddr; - socklen_t sa_len = sizeof(saddr); + struct sockaddr_in sin; int fd; - if (!GetAddress(hostW, port, (struct sockaddr *)&saddr, &sa_len)) + if (!GetAddress(hostW, port, &sin)) goto End; - fd = socket(saddr.ss_family, SOCK_STREAM, 0); + fd = socket(sin.sin_family, SOCK_STREAM, 0); if (fd != -1) { - if (connect(fd, (struct sockaddr *)&saddr, sa_len) == 0) + if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == 0) rc = TRUE; close(fd); } @@ -2803,18 +2731,17 @@ End: */ BOOL WINAPI InternetCheckConnectionA(LPCSTR lpszUrl, DWORD dwFlags, DWORD dwReserved) { - WCHAR *url = NULL; + WCHAR *szUrl; + INT len; BOOL rc; - if(lpszUrl) { - url = heap_strdupAtoW(lpszUrl); - if(!url) - return FALSE; - } - - rc = InternetCheckConnectionW(url, dwFlags, dwReserved); - - HeapFree(GetProcessHeap(), 0, url); + len = MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, NULL, 0); + if (!(szUrl = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)))) + return FALSE; + MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, szUrl, len); + rc = InternetCheckConnectionW(szUrl, dwFlags, dwReserved); + HeapFree(GetProcessHeap(), 0, szUrl); + return rc; } @@ -2827,7 +2754,7 @@ BOOL WINAPI InternetCheckConnectionA(LPCSTR lpszUrl, DWORD dwFlags, DWORD dwRese * RETURNS * handle of connection or NULL on failure */ -static HINTERNET INTERNET_InternetOpenUrlW(appinfo_t *hIC, LPCWSTR lpszUrl, +static HINTERNET INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl, LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext) { URL_COMPONENTSW urlComponents; @@ -2878,8 +2805,6 @@ static HINTERNET INTERNET_InternetOpenUrlW(appinfo_t *hIC, LPCWSTR lpszUrl, else urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT; } - if (urlComponents.nScheme == INTERNET_SCHEME_HTTPS) dwFlags |= INTERNET_FLAG_SECURE; - /* FIXME: should use pointers, not handles, as handles are not thread-safe */ client = HTTP_Connect(hIC, hostName, urlComponents.nPort, userName, password, dwFlags, dwContext, INET_OPENURL); @@ -2939,7 +2864,7 @@ static HINTERNET INTERNET_InternetOpenUrlW(appinfo_t *hIC, LPCWSTR lpszUrl, static void AsyncInternetOpenUrlProc(WORKREQUEST *workRequest) { struct WORKREQ_INTERNETOPENURLW const *req = &workRequest->u.InternetOpenUrlW; - appinfo_t *hIC = (appinfo_t*) workRequest->hdr; + LPWININETAPPINFOW hIC = (LPWININETAPPINFOW) workRequest->hdr; TRACE("%p\n", hIC); @@ -2953,7 +2878,7 @@ HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl, LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext) { HINTERNET ret = NULL; - appinfo_t *hIC = NULL; + LPWININETAPPINFOW hIC = NULL; if (TRACE_ON(wininet)) { TRACE("(%p, %s, %s, %08x, %08x, %08lx)\n", hInternet, debugstr_w(lpszUrl), debugstr_w(lpszHeaders), @@ -2968,7 +2893,7 @@ HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl, goto lend; } - hIC = (appinfo_t*)WININET_GetObject( hInternet ); + hIC = (LPWININETAPPINFOW) WININET_GetObject( hInternet ); if (NULL == hIC || hIC->hdr.htype != WH_HINIT) { INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); goto lend; @@ -2980,9 +2905,12 @@ HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl, workRequest.asyncproc = AsyncInternetOpenUrlProc; workRequest.hdr = WININET_AddRef( &hIC->hdr ); - req = &workRequest.u.InternetOpenUrlW; - req->lpszUrl = heap_strdupW(lpszUrl); - req->lpszHeaders = heap_strdupW(lpszHeaders); + req = &workRequest.u.InternetOpenUrlW; + req->lpszUrl = WININET_strdupW(lpszUrl); + if (lpszHeaders) + req->lpszHeaders = WININET_strdupW(lpszHeaders); + else + req->lpszHeaders = 0; req->dwHeadersLength = dwHeadersLength; req->dwFlags = dwFlags; req->dwContext = dwContext; @@ -3016,16 +2944,20 @@ HINTERNET WINAPI InternetOpenUrlA(HINTERNET hInternet, LPCSTR lpszUrl, LPCSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext) { HINTERNET rc = NULL; - DWORD lenHeaders = 0; + + INT lenUrl; + INT lenHeaders = 0; LPWSTR szUrl = NULL; LPWSTR szHeaders = NULL; TRACE("\n"); if(lpszUrl) { - szUrl = heap_strdupAtoW(lpszUrl); + lenUrl = MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, NULL, 0 ); + szUrl = HeapAlloc(GetProcessHeap(), 0, lenUrl*sizeof(WCHAR)); if(!szUrl) return NULL; + MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, szUrl, lenUrl); } if(lpszHeaders) { @@ -3078,7 +3010,7 @@ static LPWITHREADERROR INTERNET_AllocThreadError(void) */ void INTERNET_SetLastError(DWORD dwError) { - LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex); + LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); if (!lpwite) lpwite = INTERNET_AllocThreadError(); @@ -3099,7 +3031,7 @@ void INTERNET_SetLastError(DWORD dwError) */ DWORD INTERNET_GetLastError(void) { - LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex); + LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); if (!lpwite) return 0; /* TlsGetValue clears last error, so set it again here */ SetLastError(lpwite->dwError); @@ -3172,7 +3104,7 @@ BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest) */ LPSTR INTERNET_GetResponseBuffer(void) { - LPWITHREADERROR lpwite = TlsGetValue(g_dwTlsErrIndex); + LPWITHREADERROR lpwite = (LPWITHREADERROR)TlsGetValue(g_dwTlsErrIndex); if (!lpwite) lpwite = INTERNET_AllocThreadError(); TRACE("\n"); @@ -3261,7 +3193,7 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile, LPDWORD lpdwNumberOfBytesAvailble, DWORD dwFlags, DWORD_PTR dwContext) { - object_header_t *hdr; + WININETHANDLEHEADER *hdr; DWORD res; TRACE("(%p %p %x %lx)\n", hFile, lpdwNumberOfBytesAvailble, dwFlags, dwContext); @@ -3519,9 +3451,6 @@ static BOOL calc_url_length(LPURL_COMPONENTSW lpUrlComponents, if (lpUrlComponents->lpszUrlPath) *lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath); - if (lpUrlComponents->lpszExtraInfo) - *lpdwUrlLength += URL_GET_COMP_LENGTH(lpUrlComponents, ExtraInfo); - return TRUE; } @@ -3770,6 +3699,7 @@ BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags, } } + if (lpUrlComponents->lpszUrlPath) { dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, UrlPath); @@ -3777,13 +3707,6 @@ BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags, lpszUrl += dwLen; } - if (lpUrlComponents->lpszExtraInfo) - { - dwLen = URL_GET_COMP_LENGTH(lpUrlComponents, ExtraInfo); - memcpy(lpszUrl, lpUrlComponents->lpszExtraInfo, dwLen * sizeof(WCHAR)); - lpszUrl += dwLen; - } - *lpszUrl = '\0'; return TRUE; @@ -3809,31 +3732,6 @@ DWORD WINAPI InternetConfirmZoneCrossingW( HWND hWnd, LPWSTR szUrlPrev, LPWSTR s return ERROR_SUCCESS; } -static DWORD zone_preference = 3; - -/*********************************************************************** - * PrivacySetZonePreferenceW (WININET.@) - */ -DWORD WINAPI PrivacySetZonePreferenceW( DWORD zone, DWORD type, DWORD template, LPCWSTR preference ) -{ - FIXME( "%x %x %x %s: stub\n", zone, type, template, debugstr_w(preference) ); - - zone_preference = template; - return 0; -} - -/*********************************************************************** - * PrivacyGetZonePreferenceW (WININET.@) - */ -DWORD WINAPI PrivacyGetZonePreferenceW( DWORD zone, DWORD type, LPDWORD template, - LPWSTR preference, LPDWORD length ) -{ - FIXME( "%x %x %p %p %p: stub\n", zone, type, template, preference, length ); - - if (template) *template = zone_preference; - return 0; -} - DWORD WINAPI InternetDialA( HWND hwndParent, LPSTR lpszConnectoid, DWORD dwFlags, DWORD_PTR* lpdwConnection, DWORD dwReserved ) { diff --git a/reactos/dll/win32/wininet/internet.h b/reactos/dll/win32/wininet/internet.h index 75568faf253..0dcf5a22ce6 100644 --- a/reactos/dll/win32/wininet/internet.h +++ b/reactos/dll/win32/wininet/internet.h @@ -42,62 +42,53 @@ # include #endif -#if !defined(__MINGW32__) && !defined(_MSC_VER) +#if defined(__MINGW32__) || defined (_MSC_VER) +#include "ws2tcpip.h" +#ifndef MSG_WAITALL +#define MSG_WAITALL 0 +#endif +#else #define closesocket close #define ioctlsocket ioctl #endif /* __MINGW32__ */ +/* ReactOS-specific definitions */ +#undef CP_UNIXCP +#define CP_UNIXCP CP_THREAD_ACP + /* used for netconnection.c stuff */ typedef struct { BOOL useSSL; int socketFD; void *ssl_s; + char *peek_msg; + char *peek_msg_mem; + size_t peek_len; } WININET_NETCONNECTION; -static inline LPWSTR heap_strdupW(LPCWSTR str) +static inline LPWSTR WININET_strdupW( LPCWSTR str ) { - LPWSTR ret = NULL; - - if(str) { - DWORD size; - - size = (strlenW(str)+1)*sizeof(WCHAR); - ret = HeapAlloc(GetProcessHeap(), 0, size); - if(ret) - memcpy(ret, str, size); - } - + LPWSTR ret = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1)*sizeof(WCHAR) ); + if (ret) strcpyW( ret, str ); return ret; } -static inline WCHAR *heap_strdupAtoW(const char *str) +static inline LPWSTR WININET_strdup_AtoW( LPCSTR str ) { - LPWSTR ret = NULL; - - if(str) { - DWORD len; - - len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); - ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); - if(ret) - MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); - } - + int len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0); + LPWSTR ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + if (ret) + MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len); return ret; } -static inline char *heap_strdupWtoA(LPCWSTR str) +static inline LPSTR WININET_strdup_WtoA( LPCWSTR str ) { - char *ret = NULL; - - if(str) { - DWORD size = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); - ret = HeapAlloc(GetProcessHeap(), 0, size); - if(ret) - WideCharToMultiByte(CP_ACP, 0, str, -1, ret, size, NULL, NULL); - } - + int len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); + LPSTR ret = HeapAlloc( GetProcessHeap(), 0, len ); + if (ret) + WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL); return ret; } @@ -133,25 +124,24 @@ typedef enum #define INET_OPENURL 0x0001 #define INET_CALLBACKW 0x0002 -typedef struct _object_header_t object_header_t; +typedef struct _WININETHANDLEHEADER WININETHANDLEHEADER, *LPWININETHANDLEHEADER; typedef struct { - void (*Destroy)(object_header_t*); - void (*CloseConnection)(object_header_t*); - DWORD (*QueryOption)(object_header_t*,DWORD,void*,DWORD*,BOOL); - DWORD (*SetOption)(object_header_t*,DWORD,void*,DWORD); - DWORD (*ReadFile)(object_header_t*,void*,DWORD,DWORD*); - DWORD (*ReadFileExA)(object_header_t*,INTERNET_BUFFERSA*,DWORD,DWORD_PTR); - DWORD (*ReadFileExW)(object_header_t*,INTERNET_BUFFERSW*,DWORD,DWORD_PTR); - BOOL (*WriteFile)(object_header_t*,const void*,DWORD,DWORD*); - DWORD (*QueryDataAvailable)(object_header_t*,DWORD*,DWORD,DWORD_PTR); - DWORD (*FindNextFileW)(object_header_t*,void*); -} object_vtbl_t; + void (*Destroy)(WININETHANDLEHEADER*); + void (*CloseConnection)(WININETHANDLEHEADER*); + DWORD (*QueryOption)(WININETHANDLEHEADER*,DWORD,void*,DWORD*,BOOL); + DWORD (*SetOption)(WININETHANDLEHEADER*,DWORD,void*,DWORD); + DWORD (*ReadFile)(WININETHANDLEHEADER*,void*,DWORD,DWORD*); + DWORD (*ReadFileExA)(WININETHANDLEHEADER*,INTERNET_BUFFERSA*,DWORD,DWORD_PTR); + BOOL (*WriteFile)(WININETHANDLEHEADER*,const void*,DWORD,DWORD*); + DWORD (*QueryDataAvailable)(WININETHANDLEHEADER*,DWORD*,DWORD,DWORD_PTR); + DWORD (*FindNextFileW)(WININETHANDLEHEADER*,void*); +} HANDLEHEADERVtbl; -struct _object_header_t +struct _WININETHANDLEHEADER { WH_TYPE htype; - const object_vtbl_t *vtbl; + const HANDLEHEADERVtbl *vtbl; HINTERNET hInternet; DWORD dwFlags; DWORD_PTR dwContext; @@ -166,29 +156,28 @@ struct _object_header_t typedef struct { - object_header_t hdr; + WININETHANDLEHEADER hdr; LPWSTR lpszAgent; LPWSTR lpszProxy; LPWSTR lpszProxyBypass; LPWSTR lpszProxyUsername; LPWSTR lpszProxyPassword; DWORD dwAccessType; -} appinfo_t; +} WININETAPPINFOW, *LPWININETAPPINFOW; typedef struct { - object_header_t hdr; - appinfo_t *lpAppInfo; + WININETHANDLEHEADER hdr; + WININETAPPINFOW *lpAppInfo; LPWSTR lpszHostName; /* the final destination of the request */ LPWSTR lpszServerName; /* the name of the server we directly connect to */ LPWSTR lpszUserName; LPWSTR lpszPassword; INTERNET_PORT nHostPort; /* the final destination port of the request */ INTERNET_PORT nServerPort; /* the port of the server we directly connect to */ - struct sockaddr_storage socketAddress; - socklen_t sa_len; -} http_session_t; + struct sockaddr_in socketAddress; +} WININETHTTPSESSIONW, *LPWININETHTTPSESSIONW; #define HDR_ISREQUEST 0x0001 #define HDR_COMMADELIMITED 0x0002 @@ -205,38 +194,25 @@ typedef struct struct HttpAuthInfo; -typedef struct gzip_stream_t gzip_stream_t; - typedef struct { - object_header_t hdr; - http_session_t *lpHttpSession; + WININETHANDLEHEADER hdr; + WININETHTTPSESSIONW *lpHttpSession; LPWSTR lpszPath; LPWSTR lpszVerb; LPWSTR lpszRawHeaders; WININET_NETCONNECTION netConnection; LPWSTR lpszVersion; LPWSTR lpszStatusText; - DWORD dwBytesToWrite; - DWORD dwBytesWritten; + DWORD dwContentLength; /* total number of bytes to be read */ + DWORD dwContentRead; /* bytes of the content read so far */ HTTPHEADERW *pCustHeaders; DWORD nCustHeaders; HANDLE hCacheFile; LPWSTR lpszCacheFile; struct HttpAuthInfo *pAuthInfo; struct HttpAuthInfo *pProxyAuthInfo; - - CRITICAL_SECTION read_section; /* section to protect the following fields */ - DWORD dwContentLength; /* total number of bytes to be read */ - DWORD dwContentRead; /* bytes of the content read so far */ - BOOL read_chunked; /* are we reading in chunked mode? */ - DWORD read_pos; /* current read position in read_buf */ - DWORD read_size; /* valid data size in read_buf */ - BYTE read_buf[4096]; /* buffer for already read but not returned data */ - - BOOL decoding; - gzip_stream_t *gzip_stream; -} http_request_t; +} WININETHTTPREQW, *LPWININETHTTPREQW; @@ -321,12 +297,6 @@ struct WORKREQ_HTTPSENDREQUESTW BOOL bEndRequest; }; -struct WORKREQ_HTTPENDREQUESTW -{ - DWORD dwFlags; - DWORD_PTR dwContext; -}; - struct WORKREQ_SENDCALLBACK { DWORD_PTR dwContext; @@ -350,15 +320,10 @@ struct WORKREQ_INTERNETREADFILEEXA LPINTERNET_BUFFERSA lpBuffersOut; }; -struct WORKREQ_INTERNETREADFILEEXW -{ - LPINTERNET_BUFFERSW lpBuffersOut; -}; - typedef struct WORKREQ { void (*asyncproc)(struct WORKREQ*); - object_header_t *hdr; + WININETHANDLEHEADER *hdr; union { struct WORKREQ_FTPPUTFILEW FtpPutFileW; @@ -373,37 +338,35 @@ typedef struct WORKREQ struct WORKREQ_FTPRENAMEFILEW FtpRenameFileW; struct WORKREQ_FTPFINDNEXTW FtpFindNextW; struct WORKREQ_HTTPSENDREQUESTW HttpSendRequestW; - struct WORKREQ_HTTPENDREQUESTW HttpEndRequestW; struct WORKREQ_SENDCALLBACK SendCallback; - struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW; + struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW; struct WORKREQ_INTERNETREADFILEEXA InternetReadFileExA; - struct WORKREQ_INTERNETREADFILEEXW InternetReadFileExW; } u; } WORKREQUEST, *LPWORKREQUEST; -HINTERNET WININET_AllocHandle( object_header_t *info ); -object_header_t *WININET_GetObject( HINTERNET hinternet ); -object_header_t *WININET_AddRef( object_header_t *info ); -BOOL WININET_Release( object_header_t *info ); +HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info ); +LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet ); +LPWININETHANDLEHEADER WININET_AddRef( LPWININETHANDLEHEADER info ); +BOOL WININET_Release( LPWININETHANDLEHEADER info ); BOOL WININET_FreeHandle( HINTERNET hinternet ); DWORD INET_QueryOption(DWORD,void*,DWORD*,BOOL); time_t ConvertTimeString(LPCWSTR asctime); -HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, +HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext, DWORD dwInternalFlags); -HINTERNET HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, +HINTERNET HTTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext, DWORD dwInternalFlags); BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr *psa, socklen_t *sa_len); + struct sockaddr_in *psa); void INTERNET_SetLastError(DWORD dwError); DWORD INTERNET_GetLastError(void); @@ -411,25 +374,27 @@ BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest); LPSTR INTERNET_GetResponseBuffer(void); LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen); -BOOLAPI HTTP_HttpSendRequestW(http_request_t *req, LPCWSTR lpszHeaders, +BOOLAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders, DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength, DWORD dwContentLength, BOOL bEndRequest); -INTERNETAPI HINTERNET WINAPI HTTP_HttpOpenRequestW(http_session_t *session, +INTERNETAPI HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs, LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext); +BOOL HTTP_FinishedReading(LPWININETHTTPREQW lpwhr); -VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext, +VOID SendAsyncCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, DWORD dwStatusInfoLength); -VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, +VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, DWORD dwStatusInfoLength); +LPHTTPHEADERW HTTP_GetHeader(LPWININETHTTPREQW lpwhr, LPCWSTR header); + BOOL NETCON_connected(WININET_NETCONNECTION *connection); BOOL NETCON_init(WININET_NETCONNECTION *connnection, BOOL useSSL); -void NETCON_unload(void); BOOL NETCON_create(WININET_NETCONNECTION *connection, int domain, int type, int protocol); BOOL NETCON_close(WININET_NETCONNECTION *connection); @@ -441,6 +406,7 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags, int *recvd /* out */); BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available); +BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer); LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection); DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value); diff --git a/reactos/dll/win32/wininet/netconnection.c b/reactos/dll/win32/wininet/netconnection.c index 16cce406533..5d8b4d75534 100644 --- a/reactos/dll/win32/wininet/netconnection.c +++ b/reactos/dll/win32/wininet/netconnection.c @@ -23,10 +23,6 @@ #include "config.h" #include "wine/port.h" -#if defined(__MINGW32__) || defined (_MSC_VER) -#include -#endif - #include #ifdef HAVE_POLL_H #include @@ -37,12 +33,10 @@ #ifdef HAVE_SYS_TIME_H # include #endif +#include #ifdef HAVE_SYS_SOCKET_H # include #endif -#ifdef HAVE_SYS_FILIO_H -# include -#endif #ifdef HAVE_UNISTD_H # include #endif @@ -61,6 +55,9 @@ #undef FAR #undef DSA #endif +#ifdef HAVE_SYS_SOCKET_H +# include +#endif #include #include @@ -84,7 +81,7 @@ #include "winsock2.h" #define RESPONSE_TIMEOUT 30 /* FROM internet.c */ - +#define sock_get_error(x) WSAGetLastError() WINE_DEFAULT_DEBUG_CHANNEL(wininet); @@ -98,16 +95,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet); #include -static CRITICAL_SECTION init_ssl_cs; -static CRITICAL_SECTION_DEBUG init_ssl_cs_debug = -{ - 0, 0, &init_ssl_cs, - { &init_ssl_cs_debug.ProcessLocksList, - &init_ssl_cs_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": init_ssl_cs") } -}; -static CRITICAL_SECTION init_ssl_cs = { &init_ssl_cs_debug, -1, 0, 0, 0, 0 }; - static void *OpenSSL_ssl_handle; static void *OpenSSL_crypto_handle; @@ -120,7 +107,6 @@ static SSL_CTX *ctx; MAKE_FUNCPTR(SSL_library_init); MAKE_FUNCPTR(SSL_load_error_strings); MAKE_FUNCPTR(SSLv23_method); -MAKE_FUNCPTR(SSL_CTX_free); MAKE_FUNCPTR(SSL_CTX_new); MAKE_FUNCPTR(SSL_new); MAKE_FUNCPTR(SSL_free); @@ -129,38 +115,19 @@ MAKE_FUNCPTR(SSL_connect); MAKE_FUNCPTR(SSL_shutdown); MAKE_FUNCPTR(SSL_write); MAKE_FUNCPTR(SSL_read); -MAKE_FUNCPTR(SSL_pending); MAKE_FUNCPTR(SSL_get_verify_result); MAKE_FUNCPTR(SSL_get_peer_certificate); MAKE_FUNCPTR(SSL_CTX_get_timeout); MAKE_FUNCPTR(SSL_CTX_set_timeout); MAKE_FUNCPTR(SSL_CTX_set_default_verify_paths); +MAKE_FUNCPTR(i2d_X509); /* OpenSSL's libcrypto functions that we use */ MAKE_FUNCPTR(BIO_new_fp); -MAKE_FUNCPTR(CRYPTO_num_locks); -MAKE_FUNCPTR(CRYPTO_set_id_callback); -MAKE_FUNCPTR(CRYPTO_set_locking_callback); MAKE_FUNCPTR(ERR_get_error); MAKE_FUNCPTR(ERR_error_string); -MAKE_FUNCPTR(i2d_X509); #undef MAKE_FUNCPTR -static CRITICAL_SECTION *ssl_locks; - -static unsigned long ssl_thread_id(void) -{ - return GetCurrentThreadId(); -} - -static void ssl_lock_callback(int mode, int type, const char *file, int line) -{ - if (mode & CRYPTO_LOCK) - EnterCriticalSection(&ssl_locks[type]); - else - LeaveCriticalSection(&ssl_locks[type]); -} - #endif BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) @@ -170,22 +137,15 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) if (useSSL) { #if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO) - int i; - TRACE("using SSL connection\n"); - EnterCriticalSection(&init_ssl_cs); if (OpenSSL_ssl_handle) /* already initialized everything */ - { - LeaveCriticalSection(&init_ssl_cs); return TRUE; - } OpenSSL_ssl_handle = wine_dlopen(SONAME_LIBSSL, RTLD_NOW, NULL, 0); if (!OpenSSL_ssl_handle) { ERR("trying to use a SSL connection, but couldn't load %s. Expect trouble.\n", SONAME_LIBSSL); INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); - LeaveCriticalSection(&init_ssl_cs); return FALSE; } OpenSSL_crypto_handle = wine_dlopen(SONAME_LIBCRYPTO, RTLD_NOW, NULL, 0); @@ -194,7 +154,6 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) ERR("trying to use a SSL connection, but couldn't load %s. Expect trouble.\n", SONAME_LIBCRYPTO); INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); - LeaveCriticalSection(&init_ssl_cs); return FALSE; } @@ -205,14 +164,12 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) { \ ERR("failed to load symbol %s\n", #x); \ INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); \ - LeaveCriticalSection(&init_ssl_cs); \ return FALSE; \ } DYNSSL(SSL_library_init); DYNSSL(SSL_load_error_strings); DYNSSL(SSLv23_method); - DYNSSL(SSL_CTX_free); DYNSSL(SSL_CTX_new); DYNSSL(SSL_new); DYNSSL(SSL_free); @@ -221,12 +178,12 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) DYNSSL(SSL_shutdown); DYNSSL(SSL_write); DYNSSL(SSL_read); - DYNSSL(SSL_pending); DYNSSL(SSL_get_verify_result); DYNSSL(SSL_get_peer_certificate); DYNSSL(SSL_CTX_get_timeout); DYNSSL(SSL_CTX_set_timeout); DYNSSL(SSL_CTX_set_default_verify_paths); + DYNSSL(i2d_X509); #undef DYNSSL #define DYNCRYPTO(x) \ @@ -235,16 +192,11 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) { \ ERR("failed to load symbol %s\n", #x); \ INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); \ - LeaveCriticalSection(&init_ssl_cs); \ return FALSE; \ } DYNCRYPTO(BIO_new_fp); - DYNCRYPTO(CRYPTO_num_locks); - DYNCRYPTO(CRYPTO_set_id_callback); - DYNCRYPTO(CRYPTO_set_locking_callback); DYNCRYPTO(ERR_get_error); DYNCRYPTO(ERR_error_string); - DYNCRYPTO(i2d_X509); #undef DYNCRYPTO pSSL_library_init(); @@ -252,29 +204,8 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) pBIO_new_fp(stderr, BIO_NOCLOSE); /* FIXME: should use winedebug stuff */ meth = pSSLv23_method(); - ctx = pSSL_CTX_new(meth); - if (!pSSL_CTX_set_default_verify_paths(ctx)) - { - ERR("SSL_CTX_set_default_verify_paths failed: %s\n", - pERR_error_string(pERR_get_error(), 0)); - INTERNET_SetLastError(ERROR_OUTOFMEMORY); - LeaveCriticalSection(&init_ssl_cs); - return FALSE; - } - - pCRYPTO_set_id_callback(ssl_thread_id); - ssl_locks = HeapAlloc(GetProcessHeap(), 0, - pCRYPTO_num_locks() * sizeof(CRITICAL_SECTION)); - if (!ssl_locks) - { - INTERNET_SetLastError(ERROR_OUTOFMEMORY); - LeaveCriticalSection(&init_ssl_cs); - return FALSE; - } - for (i = 0; i < pCRYPTO_num_locks(); i++) - InitializeCriticalSection(&ssl_locks[i]); - pCRYPTO_set_locking_callback(ssl_lock_callback); - LeaveCriticalSection(&init_ssl_cs); + connection->peek_msg = NULL; + connection->peek_msg_mem = NULL; #else FIXME("can't use SSL, not compiled in.\n"); INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); @@ -284,28 +215,6 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL) return TRUE; } -void NETCON_unload(void) -{ -#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO) - if (OpenSSL_crypto_handle) - { - wine_dlclose(OpenSSL_crypto_handle, NULL, 0); - } - if (OpenSSL_ssl_handle) - { - if (ctx) - pSSL_CTX_free(ctx); - wine_dlclose(OpenSSL_ssl_handle, NULL, 0); - } - if (ssl_locks) - { - int i; - for (i = 0; i < pCRYPTO_num_locks(); i++) DeleteCriticalSection(&ssl_locks[i]); - HeapFree(GetProcessHeap(), 0, ssl_locks); - } -#endif -} - BOOL NETCON_connected(WININET_NETCONNECTION *connection) { if (connection->socketFD == -1) @@ -314,6 +223,7 @@ BOOL NETCON_connected(WININET_NETCONNECTION *connection) return TRUE; } +#if 0 /* translate a unix error code into a winsock one */ static int sock_get_error( int err ) { @@ -380,6 +290,7 @@ static int sock_get_error( int err ) #endif return err; } +#endif /****************************************************************************** * NETCON_create @@ -415,6 +326,11 @@ BOOL NETCON_close(WININET_NETCONNECTION *connection) #ifdef SONAME_LIBSSL if (connection->useSSL) { + HeapFree(GetProcessHeap(),0,connection->peek_msg_mem); + connection->peek_msg = NULL; + connection->peek_msg_mem = NULL; + connection->peek_len = 0; + pSSL_shutdown(connection->ssl_s); pSSL_free(connection->ssl_s); connection->ssl_s = NULL; @@ -459,6 +375,14 @@ BOOL NETCON_secure_connect(WININET_NETCONNECTION *connection, LPCWSTR hostname) return FALSE; } + ctx = pSSL_CTX_new(meth); + if (!pSSL_CTX_set_default_verify_paths(ctx)) + { + ERR("SSL_CTX_set_default_verify_paths failed: %s\n", + pERR_error_string(pERR_get_error(), 0)); + INTERNET_SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } connection->ssl_s = pSSL_new(ctx); if (!connection->ssl_s) { @@ -614,8 +538,55 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f else { #ifdef SONAME_LIBSSL - *recvd = pSSL_read(connection->ssl_s, buf, len); - return *recvd > 0 || !len; + if (flags & ~(MSG_PEEK|MSG_WAITALL)) + FIXME("SSL_read does not support the following flag: %08x\n", flags); + + /* this ugly hack is all for MSG_PEEK. eww gross */ + if (flags & MSG_PEEK && !connection->peek_msg) + { + connection->peek_msg = connection->peek_msg_mem = HeapAlloc(GetProcessHeap(), 0, (sizeof(char) * len) + 1); + } + else if (flags & MSG_PEEK && connection->peek_msg) + { + if (len < connection->peek_len) + FIXME("buffer isn't big enough. Do the expect us to wrap?\n"); + *recvd = min(len, connection->peek_len); + memcpy(buf, connection->peek_msg, *recvd); + return TRUE; + } + else if (connection->peek_msg) + { + *recvd = min(len, connection->peek_len); + memcpy(buf, connection->peek_msg, *recvd); + connection->peek_len -= *recvd; + connection->peek_msg += *recvd; + if (connection->peek_len == 0) + { + HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem); + connection->peek_msg_mem = NULL; + connection->peek_msg = NULL; + } + /* check if we got enough data from the peek buffer */ + if (!(flags & MSG_WAITALL) || (*recvd == len)) + return TRUE; + /* otherwise, fall through */ + } + *recvd += pSSL_read(connection->ssl_s, (char*)buf + *recvd, len - *recvd); + if (flags & MSG_PEEK) /* must copy stuff into buffer */ + { + connection->peek_len = *recvd; + if (!*recvd) + { + HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem); + connection->peek_msg_mem = NULL; + connection->peek_msg = NULL; + } + else + memcpy(connection->peek_msg, buf, *recvd); + } + if (*recvd < 1 && len) + return FALSE; + return TRUE; #else return FALSE; #endif @@ -633,9 +604,13 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail if (!NETCON_connected(connection)) return FALSE; +#ifdef SONAME_LIBSSL + if (connection->peek_msg) *available = connection->peek_len; +#endif + +#ifdef FIONREAD if (!connection->useSSL) { -#ifdef FIONREAD int unread; int retval = ioctlsocket(connection->socketFD, FIONREAD, &unread); if (!retval) @@ -643,17 +618,115 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail TRACE("%d bytes of queued, but unread data\n", unread); *available += unread; } + } #endif + return TRUE; +} + +/****************************************************************************** + * NETCON_getNextLine + */ +BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer) +{ + + TRACE("\n"); + + if (!NETCON_connected(connection)) return FALSE; + + if (!connection->useSSL) + { + struct timeval tv; + fd_set infd; + BOOL bSuccess = FALSE; + DWORD nRecv = 0; + + FD_ZERO(&infd); + FD_SET(connection->socketFD, &infd); + tv.tv_sec=RESPONSE_TIMEOUT; + tv.tv_usec=0; + + while (nRecv < *dwBuffer) + { + if (select(connection->socketFD+1,&infd,NULL,NULL,&tv) > 0) + { + if (recv(connection->socketFD, &lpszBuffer[nRecv], 1, 0) <= 0) + { + INTERNET_SetLastError(sock_get_error(errno)); + goto lend; + } + + if (lpszBuffer[nRecv] == '\n') + { + bSuccess = TRUE; + break; + } + if (lpszBuffer[nRecv] != '\r') + nRecv++; + } + else + { + INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT); + goto lend; + } + } + + lend: /* FIXME: don't use labels */ + if (bSuccess) + { + lpszBuffer[nRecv++] = '\0'; + *dwBuffer = nRecv; + TRACE(":%u %s\n", nRecv, lpszBuffer); + return TRUE; + } + else + { + return FALSE; + } } else { #ifdef SONAME_LIBSSL - *available = pSSL_pending(connection->ssl_s); + long prev_timeout; + DWORD nRecv = 0; + BOOL success = TRUE; + + prev_timeout = pSSL_CTX_get_timeout(ctx); + pSSL_CTX_set_timeout(ctx, RESPONSE_TIMEOUT); + + while (nRecv < *dwBuffer) + { + int recv = 1; + if (!NETCON_recv(connection, &lpszBuffer[nRecv], 1, 0, &recv)) + { + INTERNET_SetLastError(ERROR_CONNECTION_ABORTED); + success = FALSE; + } + + if (lpszBuffer[nRecv] == '\n') + { + success = TRUE; + break; + } + if (lpszBuffer[nRecv] != '\r') + nRecv++; + } + + pSSL_CTX_set_timeout(ctx, prev_timeout); + if (success) + { + lpszBuffer[nRecv++] = '\0'; + *dwBuffer = nRecv; + TRACE("_SSL:%u %s\n", nRecv, lpszBuffer); + return TRUE; + } + return FALSE; +#else + return FALSE; #endif } - return TRUE; } + LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection) { #ifdef SONAME_LIBSSL @@ -715,7 +788,7 @@ DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value tv.tv_usec = (value % 1000) * 1000; result = setsockopt(connection->socketFD, SOL_SOCKET, - send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv, + send ? SO_SNDTIMEO : SO_RCVTIMEO, &tv, sizeof(tv)); if (result == -1) diff --git a/reactos/dll/win32/wininet/resource.h b/reactos/dll/win32/wininet/resource.h index 279c1123db8..8a6e4d152e2 100644 --- a/reactos/dll/win32/wininet/resource.h +++ b/reactos/dll/win32/wininet/resource.h @@ -18,10 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include -#include - -#define IDD_AUTHDLG 0x399 #define IDD_PROXYDLG 0x400 #define IDC_PROXY 0x401 @@ -29,6 +25,5 @@ #define IDC_USERNAME 0x403 #define IDC_PASSWORD 0x404 #define IDC_SAVEPASSWORD 0x405 -#define IDC_SERVER 0x406 #define IDS_LANCONNECTION 0x500 diff --git a/reactos/dll/win32/wininet/urlcache.c b/reactos/dll/win32/wininet/urlcache.c index 29d26ab0b6b..c839419f136 100644 --- a/reactos/dll/win32/wininet/urlcache.c +++ b/reactos/dll/win32/wininet/urlcache.c @@ -465,6 +465,7 @@ static void URLCacheContainer_CloseIndex(URLCACHECONTAINER * pContainer) static BOOL URLCacheContainers_AddContainer(LPCWSTR cache_prefix, LPCWSTR path, LPWSTR mutex_name) { URLCACHECONTAINER * pContainer = HeapAlloc(GetProcessHeap(), 0, sizeof(URLCACHECONTAINER)); + int path_len = strlenW(path); int cache_prefix_len = strlenW(cache_prefix); if (!pContainer) @@ -475,13 +476,15 @@ static BOOL URLCacheContainers_AddContainer(LPCWSTR cache_prefix, LPCWSTR path, pContainer->hMapping = NULL; pContainer->file_size = 0; - pContainer->path = heap_strdupW(path); + pContainer->path = HeapAlloc(GetProcessHeap(), 0, (path_len + 1) * sizeof(WCHAR)); if (!pContainer->path) { HeapFree(GetProcessHeap(), 0, pContainer); return FALSE; } + memcpy(pContainer->path, path, (path_len + 1) * sizeof(WCHAR)); + pContainer->cache_prefix = HeapAlloc(GetProcessHeap(), 0, (cache_prefix_len + 1) * sizeof(WCHAR)); if (!pContainer->cache_prefix) { @@ -590,9 +593,6 @@ static DWORD URLCacheContainers_FindContainerW(LPCWSTR lpwszUrl, URLCACHECONTAIN TRACE("searching for prefix for URL: %s\n", debugstr_w(lpwszUrl)); - if(!lpwszUrl) - return ERROR_INVALID_PARAMETER; - LIST_FOR_EACH_ENTRY(pContainer, &UrlContainers, URLCACHECONTAINER, entry) { int prefix_len = strlenW(pContainer->cache_prefix); @@ -609,15 +609,17 @@ static DWORD URLCacheContainers_FindContainerW(LPCWSTR lpwszUrl, URLCACHECONTAIN static DWORD URLCacheContainers_FindContainerA(LPCSTR lpszUrl, URLCACHECONTAINER ** ppContainer) { - LPWSTR url = NULL; DWORD ret; - - if (lpszUrl && !(url = heap_strdupAtoW(lpszUrl))) - return ERROR_OUTOFMEMORY; - - ret = URLCacheContainers_FindContainerW(url, ppContainer); - HeapFree(GetProcessHeap(), 0, url); - return ret; + LPWSTR lpwszUrl; + int url_len = MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, NULL, 0); + if (url_len && (lpwszUrl = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(WCHAR)))) + { + MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, lpwszUrl, url_len); + ret = URLCacheContainers_FindContainerW(lpwszUrl, ppContainer); + HeapFree(GetProcessHeap(), 0, lpwszUrl); + return ret; + } + return GetLastError(); } static BOOL URLCacheContainers_Enum(LPCWSTR lpwszSearchPattern, DWORD dwIndex, URLCACHECONTAINER ** ppContainer) @@ -690,7 +692,6 @@ static LPURLCACHE_HEADER URLCacheContainer_LockIndex(URLCACHECONTAINER * pContai * of the memory mapped file */ if (pHeader->dwFileSize != pContainer->file_size) { - UnmapViewOfFile( pHeader ); URLCacheContainer_CloseIndex(pContainer); error = URLCacheContainer_OpenIndex(pContainer); if (error != ERROR_SUCCESS) @@ -1239,15 +1240,17 @@ static BOOL URLCache_FindHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, struct static BOOL URLCache_FindHashW(LPCURLCACHE_HEADER pHeader, LPCWSTR lpszUrl, struct _HASH_ENTRY ** ppHashEntry) { LPSTR urlA; + int url_len; BOOL ret; - urlA = heap_strdupWtoA(lpszUrl); + url_len = WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, NULL, 0, NULL, NULL); + urlA = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(CHAR)); if (!urlA) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } - + WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, urlA, url_len, NULL, NULL); ret = URLCache_FindHash(pHeader, urlA, ppHashEntry); HeapFree(GetProcessHeap(), 0, urlA); return ret; @@ -1448,28 +1451,6 @@ static BOOL URLCache_EnumHashTableEntries(LPCURLCACHE_HEADER pHeader, const HASH return FALSE; } -/*********************************************************************** - * FreeUrlCacheSpaceA (WININET.@) - * - */ -BOOL WINAPI FreeUrlCacheSpaceA(LPCSTR lpszCachePath, DWORD dwSize, DWORD dwFilter) -{ - FIXME("stub!\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - /*********************************************************************** - * FreeUrlCacheSpaceW (WININET.@) - * - */ -BOOL WINAPI FreeUrlCacheSpaceW(LPCWSTR lpszCachePath, DWORD dwSize, DWORD dwFilter) -{ - FIXME("stub!\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - /*********************************************************************** * GetUrlCacheEntryInfoExA (WININET.@) * @@ -1501,11 +1482,7 @@ BOOL WINAPI GetUrlCacheEntryInfoExA( return FALSE; } if (dwFlags != 0) - { FIXME("Undocumented flag(s): %x\n", dwFlags); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; - } return GetUrlCacheEntryInfoA(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize); } @@ -1705,11 +1682,7 @@ BOOL WINAPI GetUrlCacheEntryInfoExW( return FALSE; } if (dwFlags != 0) - { FIXME("Undocumented flag(s): %x\n", dwFlags); - SetLastError(ERROR_FILE_NOT_FOUND); - return FALSE; - } return GetUrlCacheEntryInfoW(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize); } @@ -1896,13 +1869,6 @@ BOOL WINAPI RetrieveUrlCacheEntryFileA( } pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry; - if (!pUrlEntry->dwOffsetLocalName) - { - URLCacheContainer_UnlockIndex(pContainer, pHeader); - SetLastError(ERROR_INVALID_DATA); - return FALSE; - } - TRACE("Found URL: %s\n", (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl); TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo); @@ -1992,13 +1958,6 @@ BOOL WINAPI RetrieveUrlCacheEntryFileW( } pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry; - if (!pUrlEntry->dwOffsetLocalName) - { - URLCacheContainer_UnlockIndex(pContainer, pHeader); - SetLastError(ERROR_INVALID_DATA); - return FALSE; - } - TRACE("Found URL: %s\n", (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl); TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo); @@ -2183,16 +2142,21 @@ BOOL WINAPI CreateUrlCacheEntryA( IN DWORD dwReserved ) { + DWORD len; WCHAR *url_name; WCHAR *file_extension; WCHAR file_name[MAX_PATH]; BOOL bSuccess = FALSE; DWORD dwError = 0; - if (lpszUrlName && (url_name = heap_strdupAtoW(lpszUrlName))) + if ((len = MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, NULL, 0)) != 0 && + (url_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))) != 0) { - if (lpszFileExtension && (file_extension = heap_strdupAtoW(lpszFileExtension))) + MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, url_name, len); + if ((len = MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, NULL, 0)) != 0 && + (file_extension = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))) != 0) { + MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, file_extension, len); if (CreateUrlCacheEntryW(url_name, dwExpectedFileSize, file_extension, file_name, dwReserved)) { if (WideCharToMultiByte(CP_ACP, 0, file_name, -1, lpszFileName, MAX_PATH, NULL, NULL) < MAX_PATH) @@ -2247,11 +2211,7 @@ BOOL WINAPI CreateUrlCacheEntryW( BOOL bFound = FALSE; int count; DWORD error; - HANDLE hFile; - FILETIME ft; - static const WCHAR szWWW[] = {'w','w','w',0}; - static const WCHAR fmt[] = {'%','0','8','X','%','s',0}; TRACE("(%s, 0x%08x, %s, %p, 0x%08x)\n", debugstr_w(lpszUrlName), @@ -2261,7 +2221,11 @@ BOOL WINAPI CreateUrlCacheEntryW( dwReserved); if (dwReserved) - FIXME("dwReserved 0x%08x\n", dwReserved); + { + ERR("dwReserved != 0\n"); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } lpszUrlEnd = lpszUrlName + strlenW(lpszUrlName); @@ -2354,6 +2318,7 @@ BOOL WINAPI CreateUrlCacheEntryW( for (i = 0; i < 255; i++) { static const WCHAR szFormat[] = {'[','%','u',']','%','s',0}; + HANDLE hFile; WCHAR *p; wsprintfW(lpszFileNameNoPath + countnoextension, szFormat, i, szExtension); @@ -2381,18 +2346,6 @@ BOOL WINAPI CreateUrlCacheEntryW( } } - GetSystemTimeAsFileTime(&ft); - wsprintfW(lpszFileNameNoPath + countnoextension, fmt, ft.dwLowDateTime, szExtension); - - TRACE("Trying: %s\n", debugstr_w(lpszFileName)); - hFile = CreateFileW(lpszFileName, GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL); - if (hFile != INVALID_HANDLE_VALUE) - { - CloseHandle(hFile); - return TRUE; - } - - WARN("Could not find a unique filename\n"); return FALSE; } @@ -2494,17 +2447,25 @@ static BOOL CommitUrlCacheEntryInternal( if (!(pHeader = URLCacheContainer_LockIndex(pContainer))) return FALSE; - lpszUrlNameA = heap_strdupWtoA(lpszUrlName); + len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, 0, NULL, NULL); + lpszUrlNameA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char)); if (!lpszUrlNameA) { error = GetLastError(); goto cleanup; } + WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, lpszUrlNameA, len, NULL, NULL); - if (lpszFileExtension && !(lpszFileExtensionA = heap_strdupWtoA(lpszFileExtension))) + if (lpszFileExtension) { - error = GetLastError(); - goto cleanup; + len = WideCharToMultiByte(CP_ACP, 0, lpszFileExtension, -1, NULL, 0, NULL, NULL); + lpszFileExtensionA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char)); + if (!lpszFileExtensionA) + { + error = GetLastError(); + goto cleanup; + } + WideCharToMultiByte(CP_ACP, 0, lpszFileExtension, -1, lpszFileExtensionA, len, NULL, NULL); } if (URLCache_FindHash(pHeader, lpszUrlNameA, &pHashEntry)) @@ -2661,6 +2622,7 @@ BOOL WINAPI CommitUrlCacheEntryA( IN LPCSTR lpszOriginalUrl ) { + DWORD len; WCHAR *url_name = NULL; WCHAR *local_file_name = NULL; WCHAR *original_url = NULL; @@ -2676,27 +2638,35 @@ BOOL WINAPI CommitUrlCacheEntryA( debugstr_a(lpszFileExtension), debugstr_a(lpszOriginalUrl)); - url_name = heap_strdupAtoW(lpszUrlName); + len = MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, NULL, 0); + url_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (!url_name) goto cleanup; + MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, url_name, len); if (lpszLocalFileName) { - local_file_name = heap_strdupAtoW(lpszLocalFileName); + len = MultiByteToWideChar(CP_ACP, 0, lpszLocalFileName, -1, NULL, 0); + local_file_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (!local_file_name) goto cleanup; + MultiByteToWideChar(CP_ACP, 0, lpszLocalFileName, -1, local_file_name, len); } if (lpszFileExtension) { - file_extension = heap_strdupAtoW(lpszFileExtension); + len = MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, NULL, 0); + file_extension = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (!file_extension) goto cleanup; + MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, file_extension, len); } if (lpszOriginalUrl) { - original_url = heap_strdupAtoW(lpszOriginalUrl); + len = MultiByteToWideChar(CP_ACP, 0, lpszOriginalUrl, -1, NULL, 0); + original_url = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (!original_url) goto cleanup; + MultiByteToWideChar(CP_ACP, 0, lpszOriginalUrl, -1, original_url, len); } bSuccess = CommitUrlCacheEntryInternal(url_name, local_file_name, ExpireTime, LastModifiedTime, @@ -2742,8 +2712,12 @@ BOOL WINAPI CommitUrlCacheEntryW( debugstr_w(lpszFileExtension), debugstr_w(lpszOriginalUrl)); - if (!lpHeaderInfo || (header_info = heap_strdupWtoA(lpHeaderInfo))) + if (!lpHeaderInfo || + ((len = WideCharToMultiByte(CP_ACP, 0, lpHeaderInfo, -1, NULL, 0, NULL, NULL)) != 0 && + (header_info = HeapAlloc(GetProcessHeap(), 0, sizeof(CHAR) * len)) != 0)) { + if (header_info) + WideCharToMultiByte(CP_ACP, 0, lpHeaderInfo, -1, header_info, len, NULL, NULL); if (CommitUrlCacheEntryInternal(lpszUrlName, lpszLocalFileName, ExpireTime, LastModifiedTime, CacheEntryType, (LPBYTE)header_info, len, lpszFileExtension, lpszOriginalUrl)) { @@ -2966,16 +2940,19 @@ BOOL WINAPI DeleteUrlCacheEntryW(LPCWSTR lpszUrlName) struct _HASH_ENTRY * pHashEntry; CACHEFILE_ENTRY * pEntry; LPSTR urlA; + int url_len; DWORD error; TRACE("(%s)\n", debugstr_w(lpszUrlName)); - urlA = heap_strdupWtoA(lpszUrlName); + url_len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, 0, NULL, NULL); + urlA = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(CHAR)); if (!urlA) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } + WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, urlA, url_len, NULL, NULL); error = URLCacheContainers_FindContainerW(lpszUrlName, &pContainer); if (error != ERROR_SUCCESS) @@ -3156,12 +3133,14 @@ INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryA(LPCSTR lpszUrlSearchPattern, pEntryHandle->dwMagic = URLCACHE_FIND_ENTRY_HANDLE_MAGIC; if (lpszUrlSearchPattern) { - pEntryHandle->lpszUrlSearchPattern = heap_strdupAtoW(lpszUrlSearchPattern); + int len = MultiByteToWideChar(CP_ACP, 0, lpszUrlSearchPattern, -1, NULL, 0); + pEntryHandle->lpszUrlSearchPattern = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); if (!pEntryHandle->lpszUrlSearchPattern) { HeapFree(GetProcessHeap(), 0, pEntryHandle); return NULL; } + MultiByteToWideChar(CP_ACP, 0, lpszUrlSearchPattern, -1, pEntryHandle->lpszUrlSearchPattern, len); } else pEntryHandle->lpszUrlSearchPattern = NULL; @@ -3195,12 +3174,14 @@ INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryW(LPCWSTR lpszUrlSearchPattern, pEntryHandle->dwMagic = URLCACHE_FIND_ENTRY_HANDLE_MAGIC; if (lpszUrlSearchPattern) { - pEntryHandle->lpszUrlSearchPattern = heap_strdupW(lpszUrlSearchPattern); + int len = strlenW(lpszUrlSearchPattern); + pEntryHandle->lpszUrlSearchPattern = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); if (!pEntryHandle->lpszUrlSearchPattern) { HeapFree(GetProcessHeap(), 0, pEntryHandle); return NULL; } + memcpy(pEntryHandle->lpszUrlSearchPattern, lpszUrlSearchPattern, (len + 1) * sizeof(WCHAR)); } else pEntryHandle->lpszUrlSearchPattern = NULL; @@ -3642,26 +3623,10 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa /*********************************************************************** * GetDiskInfoA (WININET.@) */ -BOOL WINAPI GetDiskInfoA(PCSTR path, PDWORD cluster_size, PDWORDLONG free, PDWORDLONG total) +BOOL WINAPI GetDiskInfoA(PCSTR p0, PDWORD p1, PDWORDLONG p2, PDWORDLONG p3) { - BOOL ret; - ULARGE_INTEGER bytes_free, bytes_total; - - TRACE("(%s, %p, %p, %p)\n", debugstr_a(path), cluster_size, free, total); - - if (!path) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if ((ret = GetDiskFreeSpaceExA(path, NULL, &bytes_total, &bytes_free))) - { - if (cluster_size) *cluster_size = 1; - if (free) *free = bytes_free.QuadPart; - if (total) *total = bytes_total.QuadPart; - } - return ret; + FIXME("(%p, %p, %p, %p)\n", p0, p1, p2, p3); + return FALSE; } /*********************************************************************** @@ -3672,12 +3637,3 @@ DWORD WINAPI RegisterUrlCacheNotification(LPVOID a, DWORD b, DWORD c, DWORD d, D FIXME("(%p %x %x %x %x %x)\n", a, b, c, d, e, f); return 0; } - -/*********************************************************************** - * IncrementUrlCacheHeaderData (WININET.@) - */ -BOOL WINAPI IncrementUrlCacheHeaderData(DWORD index, LPDWORD data) -{ - FIXME("(%u, %p)\n", index, data); - return FALSE; -} diff --git a/reactos/dll/win32/wininet/utility.c b/reactos/dll/win32/wininet/utility.c index 66fbecdd653..b0d9c9c91c6 100644 --- a/reactos/dll/win32/wininet/utility.c +++ b/reactos/dll/win32/wininet/utility.c @@ -25,10 +25,6 @@ #include "config.h" #include "wine/port.h" -#if defined(__MINGW32__) || defined (_MSC_VER) -#include -#endif - #include #include #include @@ -44,8 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet); -#ifndef HAVE_GETADDRINFO - /* critical section to protect non-reentrant gethostbyname() */ static CRITICAL_SECTION cs_gethostbyname; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -56,8 +50,6 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 }; -#endif - #define TIME_STRING_LEN 30 time_t ConvertTimeString(LPCWSTR asctime) @@ -145,18 +137,12 @@ time_t ConvertTimeString(LPCWSTR asctime) BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, - struct sockaddr *psa, socklen_t *sa_len) + struct sockaddr_in *psa) { WCHAR *found; char *name; int len, sz; -#ifdef HAVE_GETADDRINFO - struct addrinfo *res, hints; - int ret; -#else struct hostent *phe; - struct sockaddr_in *sin = (struct sockaddr_in *)psa; -#endif TRACE("%s\n", debugstr_w(lpszServerName)); @@ -172,75 +158,27 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, len = strlenW(lpszServerName); sz = WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, NULL, 0, NULL, NULL ); - if (!(name = HeapAlloc( GetProcessHeap(), 0, sz + 1 ))) return FALSE; + name = HeapAlloc(GetProcessHeap(), 0, sz+1); WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, name, sz, NULL, NULL ); name[sz] = 0; -#ifdef HAVE_GETADDRINFO - memset( &hints, 0, sizeof(struct addrinfo) ); - /* Prefer IPv4 to IPv6 addresses, since some servers do not listen on - * their IPv6 addresses even though they have IPv6 addresses in the DNS. - */ - hints.ai_family = AF_INET; - - ret = getaddrinfo( name, NULL, &hints, &res ); - HeapFree( GetProcessHeap(), 0, name ); - if (ret != 0) - { - TRACE("failed to get IPv4 address of %s (%s), retrying with IPv6\n", debugstr_w(lpszServerName), gai_strerror(ret)); - hints.ai_family = AF_INET6; - ret = getaddrinfo( name, NULL, &hints, &res ); - if (ret != 0) - { - TRACE("failed to get address of %s (%s)\n", debugstr_w(lpszServerName), gai_strerror(ret)); - return FALSE; - } - } - if (*sa_len < res->ai_addrlen) - { - WARN("address too small\n"); - freeaddrinfo( res ); - return FALSE; - } - *sa_len = res->ai_addrlen; - memcpy( psa, res->ai_addr, res->ai_addrlen ); - /* Copy port */ - switch (res->ai_family) - { - case AF_INET: - ((struct sockaddr_in *)psa)->sin_port = htons(nServerPort); - break; - case AF_INET6: - ((struct sockaddr_in6 *)psa)->sin6_port = htons(nServerPort); - break; - } - - freeaddrinfo( res ); -#else EnterCriticalSection( &cs_gethostbyname ); phe = gethostbyname(name); HeapFree( GetProcessHeap(), 0, name ); if (NULL == phe) { - TRACE("failed to get address of %s (%d)\n", debugstr_w(lpszServerName), h_errno); + TRACE("Failed to get hostname: (%s)\n", debugstr_w(lpszServerName) ); LeaveCriticalSection( &cs_gethostbyname ); return FALSE; } - if (*sa_len < sizeof(struct sockaddr_in)) - { - WARN("address too small\n"); - LeaveCriticalSection( &cs_gethostbyname ); - return FALSE; - } - *sa_len = sizeof(struct sockaddr_in); - memset(sin,0,sizeof(struct sockaddr_in)); - memcpy((char *)&sin->sin_addr, phe->h_addr, phe->h_length); - sin->sin_family = phe->h_addrtype; - sin->sin_port = htons(nServerPort); + + memset(psa,0,sizeof(struct sockaddr_in)); + memcpy((char *)&psa->sin_addr, phe->h_addr, phe->h_length); + psa->sin_family = phe->h_addrtype; + psa->sin_port = htons(nServerPort); LeaveCriticalSection( &cs_gethostbyname ); -#endif return TRUE; } @@ -286,7 +224,7 @@ static const char *get_callback_name(DWORD dwInternetStatus) { return "Unknown"; } -VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, +VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, DWORD dwStatusInfoLength) { @@ -306,11 +244,11 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, case INTERNET_STATUS_NAME_RESOLVED: case INTERNET_STATUS_CONNECTING_TO_SERVER: case INTERNET_STATUS_CONNECTED_TO_SERVER: - lpvNewInfo = heap_strdupAtoW(lpvStatusInfo); + lpvNewInfo = WININET_strdup_AtoW(lpvStatusInfo); break; case INTERNET_STATUS_RESOLVING_NAME: case INTERNET_STATUS_REDIRECT: - lpvNewInfo = heap_strdupW(lpvStatusInfo); + lpvNewInfo = WININET_strdupW(lpvStatusInfo); break; } }else { @@ -324,7 +262,7 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, break; case INTERNET_STATUS_RESOLVING_NAME: case INTERNET_STATUS_REDIRECT: - lpvNewInfo = heap_strdupWtoA(lpvStatusInfo); + lpvNewInfo = WININET_strdup_WtoA(lpvStatusInfo); break; } } @@ -356,7 +294,7 @@ static void SendAsyncCallbackProc(WORKREQUEST *workRequest) HeapFree(GetProcessHeap(), 0, req->lpvStatusInfo); } -void SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext, +VOID SendAsyncCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, DWORD dwStatusInfoLength) { diff --git a/reactos/dll/win32/wininet/wininet.rbuild b/reactos/dll/win32/wininet/wininet.rbuild index 1bb2b3bee40..11f6872b444 100644 --- a/reactos/dll/win32/wininet/wininet.rbuild +++ b/reactos/dll/win32/wininet/wininet.rbuild @@ -19,7 +19,6 @@ user32 advapi32 kernel32 - pseh ntdll secur32 crypt32 diff --git a/reactos/dll/win32/wininet/wininet.spec b/reactos/dll/win32/wininet/wininet.spec index 46dd04334e6..dfbc38c02fc 100644 --- a/reactos/dll/win32/wininet/wininet.spec +++ b/reactos/dll/win32/wininet/wininet.spec @@ -1,5 +1,5 @@ 101 stub -noname DoConnectoidsExist -102 stdcall -noname GetDiskInfoA(str ptr ptr ptr) +102 stub -noname GetDiskInfoA 103 stub -noname PerformOperationOverUrlCacheA 104 stub -noname HttpCheckDavComplianceA 105 stub -noname HttpCheckDavComplianceW @@ -9,7 +9,7 @@ 111 stub -noname ExportCookieFileW 112 stub -noname IsProfilesEnabled 116 stub -noname IsDomainlegalCookieDomainA -117 stdcall -noname IsDomainLegalCookieDomainW(wstr wstr) +117 stub -noname IsDomainLegalCookieDomainW 118 stub -noname FindP3PPolicySymbol 120 stub -noname MapResourceToPolicy 121 stub -noname GetP3PPolicy @@ -50,8 +50,8 @@ @ stdcall FindNextUrlCacheGroup(long ptr ptr) @ stub ForceNexusLookup @ stub ForceNexusLookupExW -@ stdcall FreeUrlCacheSpaceA(str long long) -@ stdcall FreeUrlCacheSpaceW(wstr long long) +@ stub FreeUrlCacheSpaceA +@ stub FreeUrlCacheSpaceW @ stdcall FtpCommandA(long long long str ptr ptr) @ stdcall FtpCommandW(long long long wstr ptr ptr) @ stdcall FtpCreateDirectoryA(ptr str) @@ -109,7 +109,7 @@ @ stdcall HttpSendRequestExA(long ptr ptr long long) @ stdcall HttpSendRequestExW(long ptr ptr long long) @ stdcall HttpSendRequestW(ptr wstr long ptr long) -@ stdcall IncrementUrlCacheHeaderData(long ptr) +@ stub IncrementUrlCacheHeaderData @ stub InternetAlgIdToStringA @ stub InternetAlgIdToStringW @ stdcall InternetAttemptConnect(long) @@ -213,10 +213,10 @@ @ stdcall IsUrlCacheEntryExpiredW(wstr long ptr) @ stub LoadUrlCacheContent @ stub ParseX509EncodedCertificateForListBoxEntry -@ stdcall PrivacyGetZonePreferenceW(long long ptr ptr ptr) -@ stdcall PrivacySetZonePreferenceW(long long long wstr) +@ stub PrivacyGetZonePreferenceW # (long long ptr ptr ptr) +@ stub PrivacySetZonePreferenceW # (long long long wstr) @ stdcall ReadUrlCacheEntryStream(ptr long ptr ptr long) -@ stdcall RegisterUrlCacheNotification(ptr long long long long long) +@ stub RegisterUrlCacheNotification @ stdcall ResumeSuspendedDownload(long long) @ stdcall RetrieveUrlCacheEntryFileA(str ptr ptr long) @ stdcall RetrieveUrlCacheEntryFileW(wstr ptr ptr long) diff --git a/reactos/dll/win32/wininet/wininet_Bg.rc b/reactos/dll/win32/wininet/wininet_Bg.rc index b25356e074e..52d797ed751 100644 --- a/reactos/dll/win32/wininet/wininet_Bg.rc +++ b/reactos/dll/win32/wininet/wininet_Bg.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Cs.rc b/reactos/dll/win32/wininet/wininet_Cs.rc index 443c0175190..9ca75397c4f 100644 --- a/reactos/dll/win32/wininet/wininet_Cs.rc +++ b/reactos/dll/win32/wininet/wininet_Cs.rc @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_CZECH, SUBLANG_DEFAULT /* Czech strings in CP1250 */ diff --git a/reactos/dll/win32/wininet/wininet_Da.rc b/reactos/dll/win32/wininet/wininet_Da.rc index 6b37857ed54..515dcabd8b3 100644 --- a/reactos/dll/win32/wininet/wininet_Da.rc +++ b/reactos/dll/win32/wininet/wininet_Da.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_DANISH, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_De.rc b/reactos/dll/win32/wininet/wininet_De.rc index 4519ad57930..9fb6be58c8d 100644 --- a/reactos/dll/win32/wininet/wininet_De.rc +++ b/reactos/dll/win32/wininet/wininet_De.rc @@ -1,6 +1,5 @@ /* * Copyright 2004 Henning Gerhardt - * Copyright 2009 AndrĂ© Hentschel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -17,10 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - -#pragma code_page(65001) - LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 @@ -30,8 +25,8 @@ FONT 8, "MS Shell Dlg" { LTEXT "Geben Sie Benutzernamen und Kennwort ein:", -1, 40, 6, 150, 15 LTEXT "Proxy", -1, 40, 26, 50, 10 - LTEXT "Bereich", -1, 40, 46, 50, 10 - LTEXT "Ben&utzer", -1, 40, 66, 50, 10 + LTEXT "Realm", -1, 40, 46, 50, 10 + LTEXT "Ben&utzername", -1, 40, 66, 50, 10 LTEXT "Kenn&wort", -1, 40, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 @@ -43,28 +38,7 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Abbrechen", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Benutzeranmeldung" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Geben Sie Benutzernamen und Kennwort ein:", -1, 40, 6, 150, 15 - LTEXT "Server", -1, 40, 26, 50, 10 - LTEXT "Bereich", -1, 40, 46, 50, 10 - LTEXT "Benutzer", -1, 40, 66, 50, 10 - LTEXT "Kennwort", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "Dieses &Kennwort speichern (unsicher)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Abbrechen", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "LAN Verbindung" } -#pragma code_page(default) diff --git a/reactos/dll/win32/wininet/wininet_En.rc b/reactos/dll/win32/wininet/wininet_En.rc index d22d249f1cd..66837dabc8e 100644 --- a/reactos/dll/win32/wininet/wininet_En.rc +++ b/reactos/dll/win32/wininet/wininet_En.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 @@ -40,26 +38,6 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Cancel", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Authentication Required" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Please enter your username and password:", -1, 40, 6, 150, 15 - LTEXT "Server", -1, 40, 26, 50, 10 - LTEXT "Realm", -1, 40, 46, 50, 10 - LTEXT "User", -1, 40, 66, 50, 10 - LTEXT "Password", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Save this password (insecure)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Cancel", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "LAN Connection" diff --git a/reactos/dll/win32/wininet/wininet_Eo.rc b/reactos/dll/win32/wininet/wininet_Eo.rc index 3fa19f37897..a145e263621 100644 --- a/reactos/dll/win32/wininet/wininet_Eo.rc +++ b/reactos/dll/win32/wininet/wininet_Eo.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Es.rc b/reactos/dll/win32/wininet/wininet_Es.rc index c9ce2cebbe2..bbf08aeb2f6 100644 --- a/reactos/dll/win32/wininet/wininet_Es.rc +++ b/reactos/dll/win32/wininet/wininet_Es.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Fi.rc b/reactos/dll/win32/wininet/wininet_Fi.rc index df5ca723044..176a00337ce 100644 --- a/reactos/dll/win32/wininet/wininet_Fi.rc +++ b/reactos/dll/win32/wininet/wininet_Fi.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Fr.rc b/reactos/dll/win32/wininet/wininet_Fr.rc index 0f31831cf84..0435b8eb711 100644 --- a/reactos/dll/win32/wininet/wininet_Fr.rc +++ b/reactos/dll/win32/wininet/wininet_Fr.rc @@ -3,9 +3,8 @@ * French language support * * Copyright 2003 Mike McCormack for CodeWeavers - * Copyright 2003 Vincent BĂ©ron + * Copyright 2003 Vincent Béron * Copyright 2005 Jonathan Ernst - * Copyright 2009 FrĂ©dĂ©ric Delanoy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,55 +21,29 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL -IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 218, 150 +IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Entrez le mot de passe rĂ©seau" +CAPTION "Entrez le mot de passe réseau" FONT 8, "MS Shell Dlg" { - LTEXT "Entrez votre nom d'utilisateur et votre mot de passe :", -1, 10, 8, 173, 12 - LTEXT "Serveur mandataire", -1, 10, 28, 50, 17 - LTEXT "Domaine", -1, 10, 50, 50, 10 - LTEXT "Utilisateur", -1, 10, 71, 50, 10 - LTEXT "Mot de passe", -1, 10, 90, 50, 10 - LTEXT "" IDC_PROXY, 58, 28, 150, 14, 0 - LTEXT "" IDC_REALM, 58, 48, 150, 14, 0 - EDITTEXT IDC_USERNAME, 58, 68, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 58, 88, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Enregistrer ce mot de passe (risquĂ©)", IDC_SAVEPASSWORD, - 58, 108, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 87, 128, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Annuler", IDCANCEL, 147, 128, 56, 14, WS_GROUP | WS_TABSTOP -} - -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 218, 150 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Authentification requise" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Entrez votre nom d'utilisateur et votre mot de passe :", -1, 10, 8, 173, 12 - LTEXT "Serveur", -1, 10, 28, 50, 17 - LTEXT "Domaine", -1, 10, 50, 50, 10 - LTEXT "Utilisateur", -1, 10, 71, 50, 10 - LTEXT "Mot de passe", -1, 10, 90, 50, 10 - LTEXT "" IDC_SERVER, 58, 28, 150, 14, 0 - LTEXT "" IDC_REALM, 58, 48, 150, 14, 0 - EDITTEXT IDC_USERNAME, 58, 68, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 58, 88, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Enregistrer ce mot de passe (risquĂ©)", IDC_SAVEPASSWORD, - 58, 108, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 87, 128, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Annuler", IDCANCEL, 147, 128, 56, 14, WS_GROUP | WS_TABSTOP + LTEXT "Entrez votre nom d'utilisateur et votre mot de passe :", -1, 40, 6, 150, 15 + LTEXT "Mandataire", -1, 40, 26, 50, 10 + LTEXT "Domaine", -1, 40, 46, 50, 10 + LTEXT "Utilisateur", -1, 40, 66, 50, 10 + LTEXT "Mot de passe", -1, 40, 86, 50, 10 + LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 + LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 + EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP + EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD + CHECKBOX "&Enregistrer ce mot de passe (risqué)", IDC_SAVEPASSWORD, + 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON + PUSHBUTTON "Annuler", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } STRINGTABLE DISCARDABLE { - IDS_LANCONNECTION "Connexion rĂ©seau local (LAN)" + IDS_LANCONNECTION "Connexion LAN" } -#pragma code_page(default) diff --git a/reactos/dll/win32/wininet/wininet_Hu.rc b/reactos/dll/win32/wininet/wininet_Hu.rc index b19e03dc007..c9704f9080b 100644 --- a/reactos/dll/win32/wininet/wininet_Hu.rc +++ b/reactos/dll/win32/wininet/wininet_Hu.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_It.rc b/reactos/dll/win32/wininet/wininet_It.rc index 04f71c5f177..45045460c33 100644 --- a/reactos/dll/win32/wininet/wininet_It.rc +++ b/reactos/dll/win32/wininet/wininet_It.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 @@ -42,26 +40,6 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Annulla", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Autenticazione richiesta" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Inserire il nome utente e la password:", -1, 40, 6, 150, 15 - LTEXT "Server", -1, 40, 26, 50, 10 - LTEXT "Realm", -1, 40, 46, 50, 10 - LTEXT "Utente", -1, 40, 66, 50, 10 - LTEXT "Password", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Memorizza la password (RISCHIOSO)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Annulla", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "Connessione LAN" diff --git a/reactos/dll/win32/wininet/wininet_Ja.rc b/reactos/dll/win32/wininet/wininet_Ja.rc index 52c420225d8..615d7be1c86 100644 --- a/reactos/dll/win32/wininet/wininet_Ja.rc +++ b/reactos/dll/win32/wininet/wininet_Ja.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - /* UTF-8 */ #pragma code_page(65001) @@ -47,4 +45,5 @@ STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "LAN 接続" } + #pragma code_page(default) diff --git a/reactos/dll/win32/wininet/wininet_Ko.rc b/reactos/dll/win32/wininet/wininet_Ko.rc index 5c2595a9b37..26ed4a2fad2 100644 --- a/reactos/dll/win32/wininet/wininet_Ko.rc +++ b/reactos/dll/win32/wininet/wininet_Ko.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Lt.rc b/reactos/dll/win32/wininet/wininet_Lt.rc deleted file mode 100644 index cd4bf482e35..00000000000 --- a/reactos/dll/win32/wininet/wininet_Lt.rc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2009 Aurimas Fišeras - * - * 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 - */ - -#include "resource.h" - -/* UTF-8 */ -#pragma code_page(65001) - -LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL - -IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Ä®veskite tinklo slaptaĹľodÄŻ" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Ä®veskite savo naudotojo vardÄ… ir slaptaĹľodÄŻ:", -1, 40, 6, 150, 15 - LTEXT "Ä®galiot. serv.", -1, 40, 26, 50, 10 - LTEXT "Sritis", -1, 40, 46, 50, 10 - LTEXT "Naudotojas", -1, 40, 66, 50, 10 - LTEXT "SlaptaĹľodis", -1, 40, 86, 50, 10 - LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "Ä®&rašyti šį slaptaĹľodÄŻ (nesaugu)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Gerai", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Atsisakyti", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Reikalingas tapatumo nustatymas" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Ä®veskite savo naudotojo vardÄ… ir slaptaĹľodÄŻ:", -1, 40, 6, 150, 15 - LTEXT "Serveris", -1, 40, 26, 50, 10 - LTEXT "Sritis", -1, 40, 46, 50, 10 - LTEXT "Naudotojas", -1, 40, 66, 50, 10 - LTEXT "SlaptaĹľodis", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "Ä®&rašyti šį slaptaĹľodÄŻ (nesaugu)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "Gerai", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Atsisakyti", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - -STRINGTABLE DISCARDABLE -{ - IDS_LANCONNECTION "Vietinio tinklo ryšys" -} diff --git a/reactos/dll/win32/wininet/wininet_Nl.rc b/reactos/dll/win32/wininet/wininet_Nl.rc index f0e891c7e19..16c80ccaad8 100644 --- a/reactos/dll/win32/wininet/wininet_Nl.rc +++ b/reactos/dll/win32/wininet/wininet_Nl.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 @@ -42,26 +40,6 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Annuleren", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Authenticatie vereist" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Voer uw gebruikersnaam en wachtwoord in:", -1, 40, 6, 150, 15 - LTEXT "Server", -1, 40, 26, 50, 10 - LTEXT "Realm", -1, 40, 46, 50, 10 - LTEXT "Gebruikersnaam", -1, 40, 66, 50, 10 - LTEXT "Wachtwoord", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Wachtwoord opslaan (onveilig)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Annuleren", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "LAN Verbinding" diff --git a/reactos/dll/win32/wininet/wininet_No.rc b/reactos/dll/win32/wininet/wininet_No.rc index c2fb42b539b..fb885e9030d 100644 --- a/reactos/dll/win32/wininet/wininet_No.rc +++ b/reactos/dll/win32/wininet/wininet_No.rc @@ -1,5 +1,5 @@ /* - * Copyright 2005-2009 Alexander N. Sørnes + * Copyright 2005 Alexander N. Sřrnes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,10 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - -#pragma code_page(65001) - LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 @@ -29,7 +25,7 @@ FONT 8, "MS Shell Dlg" { LTEXT "Skriv inn brukernavnet og passordet ditt:", -1, 40, 6, 150, 15 LTEXT "Mellomtjener", -1, 40, 26, 50, 10 - LTEXT "OmrĂĄde", -1, 40, 46, 50, 10 + LTEXT "Omrĺde", -1, 40, 46, 50, 10 LTEXT "Bruker", -1, 40, 66, 50, 10 LTEXT "Passord", -1, 40, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 @@ -42,28 +38,7 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Avbryt", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "PĂĄlogging" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Oppgi brukernavn og passord:", -1, 40, 6, 150, 15 - LTEXT "Tjener", -1, 40, 26, 50, 10 - LTEXT "OmrĂĄde", -1, 40, 46, 50, 10 - LTEXT "Bruker", -1, 40, 66, 50, 10 - LTEXT "Passord", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "Lagre pa&ssordet (sikkerhetsrisiko)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Avbryt", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "Lokal nettverksforbindelse" } -#pragma code_page(default) diff --git a/reactos/dll/win32/wininet/wininet_Pl.rc b/reactos/dll/win32/wininet/wininet_Pl.rc index 0c76d5335aa..7ddb399a584 100644 --- a/reactos/dll/win32/wininet/wininet_Pl.rc +++ b/reactos/dll/win32/wininet/wininet_Pl.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_POLISH, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Pt.rc b/reactos/dll/win32/wininet/wininet_Pt.rc index 95e06e6d6e8..57dd625a740 100644 --- a/reactos/dll/win32/wininet/wininet_Pt.rc +++ b/reactos/dll/win32/wininet/wininet_Pt.rc @@ -1,7 +1,6 @@ /* * Copyright 2003 Marcelo Duarte - * Copyright 2006-2007 AmĂ©rico JosĂ© Melo - * Copyright 2009 Ricardo Filipe + * Copyright 2006-2007 Américo José Melo * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,10 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - -#pragma code_page(65001) - LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 @@ -29,10 +24,10 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Entrar Senha da Rede" FONT 8, "MS Shell Dlg" { - LTEXT "Por favor, entre com o nome de usuário e a senha:", -1, 40, 6, 150, 15 + LTEXT "Por favor, entre com o nome de usuário e a senha:", -1, 40, 6, 150, 15 LTEXT "Proxy", -1, 40, 26, 50, 10 LTEXT "Realm", -1, 40, 46, 50, 10 - LTEXT "Usuário", -1, 40, 66, 50, 10 + LTEXT "Usuário", -1, 40, 66, 50, 10 LTEXT "Senha", -1, 40, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 @@ -66,36 +61,17 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Cancelar", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Autenticação necessária" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Por favor insira o seu nome de utilizador e palavra-passe:", -1, 40, 6, 150, 15 - LTEXT "Servidor", -1, 40, 26, 50, 10 - LTEXT "Reino", -1, 40, 46, 50, 10 - LTEXT "Utilizador", -1, 40, 66, 50, 10 - LTEXT "Palavra-passe", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Guardar esta palavra-passe (inseguro)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Cancelar", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN STRINGTABLE DISCARDABLE { - IDS_LANCONNECTION "ConexĂŁo LAN" + IDS_LANCONNECTION "Conexăo LAN" } LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE STRINGTABLE DISCARDABLE { - IDS_LANCONNECTION "Ligação LAN" + IDS_LANCONNECTION "Ligaçăo LAN" } diff --git a/reactos/dll/win32/wininet/wininet_Ro.rc b/reactos/dll/win32/wininet/wininet_Ro.rc index 13403eec1a6..367bbb5955a 100644 --- a/reactos/dll/win32/wininet/wininet_Ro.rc +++ b/reactos/dll/win32/wininet/wininet_Ro.rc @@ -17,8 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL #pragma code_page(65001) @@ -30,7 +28,7 @@ FONT 8, "MS Shell Dlg" { LTEXT "IntroduceČ›i numele de utilizator Č™i parola:", -1, 40, 6, 150, 15 LTEXT "Proxy", -1, 40, 26, 50, 10 - LTEXT "Domeniu", -1, 40, 46, 50, 10 + LTEXT "Realm", -1, 40, 46, 50, 10 LTEXT "Utilizator", -1, 40, 66, 50, 10 LTEXT "ParolÄ", -1, 40, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 @@ -43,27 +41,9 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "RenunČ›Ä", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Autentificare necesarÄ" -FONT 8, "MS Shell Dlg" -{ - LTEXT "IntroduceČ›i numele de utilizator Č™i parola:", -1, 40, 6, 150, 15 - LTEXT "Server", -1, 40, 26, 50, 10 - LTEXT "Domeniu", -1, 40, 46, 50, 10 - LTEXT "Utilizator", -1, 40, 66, 50, 10 - LTEXT "ParolÄ", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&SalveazÄ aceastÄ parolÄ (nesigur)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "RenunČ›Ä", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "Conexiune LAN" } + +#pragma code_page(default) diff --git a/reactos/dll/win32/wininet/wininet_Ru.rc b/reactos/dll/win32/wininet/wininet_Ru.rc index 04b48eb1526..d75985ba1b7 100644 --- a/reactos/dll/win32/wininet/wininet_Ru.rc +++ b/reactos/dll/win32/wininet/wininet_Ru.rc @@ -18,55 +18,29 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - -/* UTF-8 */ -#pragma code_page(65001) - LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Ввод Ńетевого пароля" +CAPTION "Ââîä ńĺňĺâîăî ďŕđîë˙" FONT 8, "MS Shell Dlg" { - LTEXT "Введите имя пользователя и пароль:", -1, 40, 6, 150, 15 - LTEXT "ПрокŃи", -1, 40, 26, 50, 10 - LTEXT "Домен", -1, 40, 46, 50, 10 - LTEXT "Пользователь", -1, 40, 66, 50, 10 - LTEXT "Пароль", -1, 40, 86, 50, 10 + LTEXT "Ââĺäčňĺ čě˙ ďîëüçîâŕňĺë˙ č ďŕđîëü:", -1, 40, 6, 150, 15 + LTEXT "Ďđîęńč", -1, 40, 26, 50, 10 + LTEXT "Äîěĺí", -1, 40, 46, 50, 10 + LTEXT "Ďîëüçîâŕňĺëü", -1, 40, 66, 50, 10 + LTEXT "Ďŕđîëü", -1, 40, 86, 50, 10 LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0 LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Сохранить этот пароль (небезопаŃно)", IDC_SAVEPASSWORD, + CHECKBOX "&Ńîőđŕíčňü ýňîň ďŕđîëü (íĺáĺçîďŕńíî)", IDC_SAVEPASSWORD, 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Отмена", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP -} - -IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "ТребŃетŃŃŹ идентификация" -FONT 8, "MS Shell Dlg" -{ - LTEXT "Введите имя пользователя и пароль:", -1, 40, 6, 150, 15 - LTEXT "Сервер", -1, 40, 26, 50, 10 - LTEXT "Домен", -1, 40, 46, 50, 10 - LTEXT "Пользователь", -1, 40, 66, 50, 10 - LTEXT "Пароль", -1, 40, 86, 50, 10 - LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0 - LTEXT "" IDC_REALM, 80, 46, 150, 14, 0 - EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP - EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD - CHECKBOX "&Сохранить этот пароль (небезопаŃно)", IDC_SAVEPASSWORD, - 80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP - PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON - PUSHBUTTON "Отмена", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Îňěĺíŕ", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP } STRINGTABLE DISCARDABLE { - IDS_LANCONNECTION "Сетевое подключение" + IDS_LANCONNECTION "Ńĺňĺâîĺ ďîäęëţ÷ĺíčĺ" } -#pragma code_page(default) diff --git a/reactos/dll/win32/wininet/wininet_Si.rc b/reactos/dll/win32/wininet/wininet_Si.rc index 97b0c3be5f0..93ac9e1f33b 100644 --- a/reactos/dll/win32/wininet/wininet_Si.rc +++ b/reactos/dll/win32/wininet/wininet_Si.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - #pragma code_page(65001) LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT @@ -46,4 +44,5 @@ STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "LAN povezava" } + #pragma code_page(default) diff --git a/reactos/dll/win32/wininet/wininet_Sv.rc b/reactos/dll/win32/wininet/wininet_Sv.rc index 8d3291ec750..6d71f2ef842 100644 --- a/reactos/dll/win32/wininet/wininet_Sv.rc +++ b/reactos/dll/win32/wininet/wininet_Sv.rc @@ -16,8 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Tr.rc b/reactos/dll/win32/wininet/wininet_Tr.rc index 8d26cf21694..dd796777236 100644 --- a/reactos/dll/win32/wininet/wininet_Tr.rc +++ b/reactos/dll/win32/wininet/wininet_Tr.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Uk.rc b/reactos/dll/win32/wininet/wininet_Uk.rc index 94a9611888b..be58bb621f2 100644 --- a/reactos/dll/win32/wininet/wininet_Uk.rc +++ b/reactos/dll/win32/wininet/wininet_Uk.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154 diff --git a/reactos/dll/win32/wininet/wininet_Zh.rc b/reactos/dll/win32/wininet/wininet_Zh.rc index e2e36ded277..4406bd87c1a 100644 --- a/reactos/dll/win32/wininet/wininet_Zh.rc +++ b/reactos/dll/win32/wininet/wininet_Zh.rc @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "resource.h" - /* Chinese text is encoded in UTF-8 */ #pragma code_page(65001) @@ -76,3 +74,5 @@ STRINGTABLE DISCARDABLE { IDS_LANCONNECTION "局域網連接" } + +#pragma code_page(default) From c71cdeb49d5e586a630e3ab5242cbe575e39a7ad Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 21 Nov 2009 13:00:37 +0000 Subject: [PATCH 083/140] - Disassociate the socket context before closing so we don't get signalled with a freed context (major cause of crashes) - Signal the connection directly from TCPSocketState - Remove some unused code - Queue completion requests on a separate list so we don't have to keep locking and unlocking while completing - Add better locking to tcpip (not the lib) - Remove some unused variables - Don't hold the cancel spin lock longer than necessary - Check that we successfully got the device description svn path=/trunk/; revision=44250 --- reactos/drivers/network/tcpip/datalink/lan.c | 5 + reactos/drivers/network/tcpip/include/tcp.h | 10 +- .../drivers/network/tcpip/include/titypes.h | 3 + reactos/drivers/network/tcpip/tcpip/ainfo.c | 5 + .../drivers/network/tcpip/tcpip/dispatch.c | 73 +++-- reactos/drivers/network/tcpip/tcpip/main.c | 4 +- reactos/lib/drivers/ip/network/ip.c | 3 - reactos/lib/drivers/ip/transport/tcp/event.c | 8 +- reactos/lib/drivers/ip/transport/tcp/tcp.c | 262 +++++++++--------- .../lib/drivers/oskittcp/oskittcp/interface.c | 15 +- 10 files changed, 216 insertions(+), 172 deletions(-) diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index fef1690dfa2..21601630fdd 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -991,6 +991,11 @@ BOOLEAN BindAdapter( GetName( RegistryPath, &IF->Name ); Status = FindDeviceDescForAdapter( &IF->Name, &IF->Description ); + if (!NT_SUCCESS(Status)) { + TI_DbgPrint(MIN_TRACE, ("Failed to get device description.\n")); + IPDestroyInterface(IF); + return FALSE; + } TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n", &IF->Description)); diff --git a/reactos/drivers/network/tcpip/include/tcp.h b/reactos/drivers/network/tcpip/include/tcp.h index 32c3ec907e7..b18fecdd295 100644 --- a/reactos/drivers/network/tcpip/include/tcp.h +++ b/reactos/drivers/network/tcpip/include/tcp.h @@ -59,6 +59,11 @@ typedef struct _SLEEPING_THREAD { KEVENT Event; } SLEEPING_THREAD, *PSLEEPING_THREAD; +typedef struct _CLIENT_DATA { + BOOLEAN Unlocked; + KSPIN_LOCK Lock; +} CLIENT_DATA, *PCLIENT_DATA; + /* Retransmission timeout constants */ /* Lower bound for retransmission timeout in TCP timer ticks */ @@ -84,6 +89,7 @@ typedef struct _SLEEPING_THREAD { #define SRF_FIN TCP_FIN extern LONG TCP_IPIdentification; +extern CLIENT_DATA ClientInfo; /* accept.c */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, @@ -106,6 +112,8 @@ VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ); +VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection); + PTCP_SEGMENT TCPCreateSegment( PIP_PACKET IPPacket, PTCPv4_HEADER TCPHeader, @@ -156,8 +164,6 @@ NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPTranslateError( int OskitError ); -VOID TCPTimeout(); - UINT TCPAllocatePort( UINT HintPort ); VOID TCPFreePort( UINT Port ); diff --git a/reactos/drivers/network/tcpip/include/titypes.h b/reactos/drivers/network/tcpip/include/titypes.h index 9ac9561e0bb..88a02bb15e5 100644 --- a/reactos/drivers/network/tcpip/include/titypes.h +++ b/reactos/drivers/network/tcpip/include/titypes.h @@ -263,6 +263,8 @@ typedef struct _TDI_BUCKET { LIST_ENTRY Entry; struct _CONNECTION_ENDPOINT *AssociatedEndpoint; TDI_REQUEST Request; + NTSTATUS Status; + ULONG Information; } TDI_BUCKET, *PTDI_BUCKET; /* Transport connection context structure A.K.A. Transmission Control Block @@ -280,6 +282,7 @@ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY ListenRequest; /* Queued listen requests */ LIST_ENTRY ReceiveRequest; /* Queued receive requests */ LIST_ENTRY SendRequest; /* Queued send requests */ + LIST_ENTRY CompletionQueue;/* Completed requests to finish */ /* Signals */ UINT SignalState; /* Active signals from oskit */ diff --git a/reactos/drivers/network/tcpip/tcpip/ainfo.c b/reactos/drivers/network/tcpip/tcpip/ainfo.c index a3ea2e8889c..0c1b11e717f 100644 --- a/reactos/drivers/network/tcpip/tcpip/ainfo.c +++ b/reactos/drivers/network/tcpip/tcpip/ainfo.c @@ -13,6 +13,8 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, PVOID Buffer, UINT BufferSize) { + //KIRQL OldIrql; + switch (ID->toi_id) { #if 0 @@ -20,7 +22,10 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, if (BufferSize < sizeof(UCHAR)) return TDI_INVALID_PARAMETER; + KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); AddrFile->TTL = *((PUCHAR)Buffer); + KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + return TDI_SUCCESS; #endif default: diff --git a/reactos/drivers/network/tcpip/tcpip/dispatch.c b/reactos/drivers/network/tcpip/tcpip/dispatch.c index 49de2fd9090..d08ef8aecfa 100644 --- a/reactos/drivers/network/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/network/tcpip/tcpip/dispatch.c @@ -72,7 +72,6 @@ VOID DispDataRequestComplete( { PIRP Irp; PIO_STACK_LOCATION IrpSp; - PTRANSPORT_CONTEXT TranContext; KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n", @@ -80,7 +79,6 @@ VOID DispDataRequestComplete( Irp = Context; IrpSp = IoGetCurrentIrpStackLocation(Irp); - TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; IoAcquireCancelSpinLock(&OldIrql); @@ -117,6 +115,8 @@ VOID NTAPI DispCancelRequest( PFILE_OBJECT FileObject; UCHAR MinorFunction; + IoReleaseCancelSpinLock(Irp->CancelIrql); + TI_DbgPrint(DEBUG_IRP, ("Called.\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -168,7 +168,6 @@ VOID NTAPI DispCancelRequest( break; } - IoReleaseCancelSpinLock(Irp->CancelIrql); IRPFinish(Irp, STATUS_CANCELLED); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); @@ -191,6 +190,8 @@ VOID NTAPI DispCancelListenRequest( PCONNECTION_ENDPOINT Connection; /*NTSTATUS Status = STATUS_SUCCESS;*/ + IoReleaseCancelSpinLock(Irp->CancelIrql); + TI_DbgPrint(DEBUG_IRP, ("Called.\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -213,8 +214,6 @@ VOID NTAPI DispCancelListenRequest( TCPAbortListenForSocket(Connection->AddressFile->Listener, Connection); - IoReleaseCancelSpinLock(Irp->CancelIrql); - Irp->IoStatus.Information = 0; IRPFinish(Irp, STATUS_CANCELLED); @@ -255,6 +254,7 @@ NTSTATUS DispTdiAssociateAddress( PFILE_OBJECT FileObject; PADDRESS_FILE AddrFile = NULL; NTSTATUS Status; + KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -274,11 +274,6 @@ NTSTATUS DispTdiAssociateAddress( return STATUS_INVALID_PARAMETER; } - if (Connection->AddressFile) { - TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n")); - return STATUS_INVALID_PARAMETER; - } - Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters; Status = ObReferenceObjectByHandle( @@ -294,8 +289,18 @@ NTSTATUS DispTdiAssociateAddress( return STATUS_INVALID_PARAMETER; } + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + if (Connection->AddressFile) { + ObDereferenceObject(FileObject); + KeReleaseSpinLock(&Connection->Lock, OldIrql); + TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n")); + return STATUS_INVALID_PARAMETER; + } + if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { ObDereferenceObject(FileObject); + KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n", FileObject->FsContext2)); return STATUS_INVALID_PARAMETER; @@ -306,17 +311,21 @@ NTSTATUS DispTdiAssociateAddress( TranContext = FileObject->FsContext; if (!TranContext) { ObDereferenceObject(FileObject); + KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); return STATUS_INVALID_PARAMETER; } AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; if (!AddrFile) { + KeReleaseSpinLock(&Connection->Lock, OldIrql); ObDereferenceObject(FileObject); TI_DbgPrint(MID_TRACE, ("No address file object.\n")); return STATUS_INVALID_PARAMETER; } + KeAcquireSpinLockAtDpcLevel(&AddrFile->Lock); + Connection->AddressFile = AddrFile; /* Add connection endpoint to the address file */ @@ -325,6 +334,9 @@ NTSTATUS DispTdiAssociateAddress( /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */ ObDereferenceObject(FileObject); + KeReleaseSpinLockFromDpcLevel(&AddrFile->Lock); + KeReleaseSpinLock(&Connection->Lock, OldIrql); + return Status; } @@ -405,6 +417,7 @@ NTSTATUS DispTdiDisassociateAddress( PCONNECTION_ENDPOINT Connection; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; + KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -424,17 +437,26 @@ NTSTATUS DispTdiDisassociateAddress( return STATUS_INVALID_PARAMETER; } + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + if (!Connection->AddressFile) { + KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n")); return STATUS_INVALID_PARAMETER; } + KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock); + /* Remove this connection from the address file */ Connection->AddressFile->Connection = NULL; + KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock); + /* Remove the address file from this connection */ Connection->AddressFile = NULL; + KeReleaseSpinLock(&Connection->Lock, OldIrql); + return STATUS_SUCCESS; } @@ -511,6 +533,7 @@ NTSTATUS DispTdiListen( PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; NTSTATUS Status = STATUS_SUCCESS; + KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -536,15 +559,23 @@ NTSTATUS DispTdiListen( Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters; - TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n", - Connection->AddressFile )); - ASSERT(Connection->AddressFile); - Status = DispPrepareIrpForCancel (TranContext->Handle.ConnectionContext, Irp, (PDRIVER_CANCEL)DispCancelListenRequest); + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + + if (Connection->AddressFile == NULL) + { + TI_DbgPrint(MID_TRACE, ("No associated address file\n")); + KeReleaseSpinLock(&Connection->Lock, OldIrql); + Status = STATUS_INVALID_PARAMETER; + goto done; + } + + KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock); + /* Listening will require us to create a listening socket and store it in * the address file. It will be signalled, and attempt to complete an irp * when a new connection arrives. */ @@ -581,6 +612,9 @@ NTSTATUS DispTdiListen( Irp ); } + KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock); + KeReleaseSpinLock(&Connection->Lock, OldIrql); + done: if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); @@ -657,12 +691,10 @@ NTSTATUS DispTdiQueryInformation( case TDI_CONNECTION_FILE: Endpoint = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; - TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE ); - DbgPrint("Returning socket address %x\n", Address->Address[0].Address[0].in_addr); RtlZeroMemory( &Address->Address[0].Address[0].sin_zero, sizeof(Address->Address[0].Address[0].sin_zero)); - return STATUS_SUCCESS; + return TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE ); default: TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); @@ -990,8 +1022,10 @@ NTSTATUS DispTdiSendDatagram( DataBuffer, BufferSize, &Irp->IoStatus.Information); - else + else { Status = STATUS_UNSUCCESSFUL; + ASSERT(FALSE); + } } done: @@ -1199,11 +1233,10 @@ VOID DispTdiQueryInformationExComplete( */ { PTI_QUERY_CONTEXT QueryContext; - UINT Count = 0; QueryContext = (PTI_QUERY_CONTEXT)Context; if (NT_SUCCESS(Status)) { - Count = CopyBufferToBufferChain( + CopyBufferToBufferChain( QueryContext->InputMdl, FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context), (PCHAR)&QueryContext->QueryInfo.Context, diff --git a/reactos/drivers/network/tcpip/tcpip/main.c b/reactos/drivers/network/tcpip/tcpip/main.c index f8aa2225bde..7e45cccba5a 100644 --- a/reactos/drivers/network/tcpip/tcpip/main.c +++ b/reactos/drivers/network/tcpip/tcpip/main.c @@ -322,7 +322,6 @@ TiDispatchOpenClose( { PIO_STACK_LOCATION IrpSp; NTSTATUS Status; - PTRANSPORT_CONTEXT Context; IRPRemember(Irp, __FILE__, __LINE__); @@ -338,8 +337,7 @@ TiDispatchOpenClose( /* Close an address file, connection endpoint, or control connection */ case IRP_MJ_CLOSE: - Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; - Status = TiCloseFileObject(DeviceObject, Irp); + Status = TiCloseFileObject(DeviceObject, Irp); break; default: diff --git a/reactos/lib/drivers/ip/network/ip.c b/reactos/lib/drivers/ip/network/ip.c index f13dd614e8c..9709ce4cee6 100644 --- a/reactos/lib/drivers/ip/network/ip.c +++ b/reactos/lib/drivers/ip/network/ip.c @@ -73,9 +73,6 @@ void NTAPI IPTimeout( PVOID Context ) { /* Clean possible outdated cached neighbor addresses */ NBTimeout(); - - /* Call upper layer timeout routines */ - TCPTimeout(); } diff --git a/reactos/lib/drivers/ip/transport/tcp/event.c b/reactos/lib/drivers/ip/transport/tcp/event.c index a4b2275b511..6d062dceb8b 100644 --- a/reactos/lib/drivers/ip/transport/tcp/event.c +++ b/reactos/lib/drivers/ip/transport/tcp/event.c @@ -29,7 +29,8 @@ int TCPSocketState(void *ClientData, return 0; } - KeAcquireSpinLockAtDpcLevel(&Connection->Lock); + if (ClientInfo.Unlocked) + KeAcquireSpinLockAtDpcLevel(&Connection->Lock); TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n", NewState, Connection, @@ -38,7 +39,10 @@ int TCPSocketState(void *ClientData, Connection->SignalState |= NewState; - KeReleaseSpinLockFromDpcLevel(&Connection->Lock); + HandleSignalledConnection(Connection); + + if (ClientInfo.Unlocked) + KeReleaseSpinLockFromDpcLevel(&Connection->Lock); return 0; } diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 25c8d4d8657..6f9f38c87a0 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -16,30 +16,38 @@ LONG TCP_IPIdentification = 0; static BOOLEAN TCPInitialized = FALSE; static NPAGED_LOOKASIDE_LIST TCPSegmentList; PORT_SET TCPPorts; +CLIENT_DATA ClientInfo; -static VOID DrainSignals() { - PCONNECTION_ENDPOINT Connection; - PLIST_ENTRY CurrentEntry, NextEntry; - KIRQL OldIrql; - NTSTATUS Status = STATUS_SUCCESS; - PTCP_COMPLETION_ROUTINE Complete; +static VOID +ProcessCompletions(PCONNECTION_ENDPOINT Connection) +{ + PLIST_ENTRY CurrentEntry; PTDI_BUCKET Bucket; - PLIST_ENTRY Entry; - PIRP Irp; - PMDL Mdl; - ULONG SocketError; + PTCP_COMPLETION_ROUTINE Complete; - KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - CurrentEntry = ConnectionEndpointListHead.Flink; - while (CurrentEntry != &ConnectionEndpointListHead) + while ((CurrentEntry = ExInterlockedRemoveHeadList(&Connection->CompletionQueue, + &Connection->Lock))) { - NextEntry = CurrentEntry->Flink; - KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); + Bucket = CONTAINING_RECORD(CurrentEntry, TDI_BUCKET, Entry); + Complete = Bucket->Request.RequestNotifyObject; - Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, - ListEntry ); + Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + exFreePool(Bucket); + } + + if (!Connection->SocketContext) + TCPFreeConnectionEndpoint(Connection); +} + +VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) +{ + PTDI_BUCKET Bucket; + PLIST_ENTRY Entry; + NTSTATUS Status; + PIRP Irp; + PMDL Mdl; + ULONG SocketError; TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", Connection, Connection->SocketContext)); @@ -47,8 +55,6 @@ static VOID DrainSignals() { if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) { TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - Connection->SignalState = 0; - /* If OskitTCP initiated the disconnect, try to read the socket error that occurred */ if (Connection->SocketContext) SocketError = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext)); @@ -57,140 +63,124 @@ static VOID DrainSignals() { if (!Connection->SocketContext || !SocketError) SocketError = STATUS_CANCELLED; - KeReleaseSpinLock(&Connection->Lock, OldIrql); - - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, - &Connection->Lock )) != NULL) + while (!IsListEmpty(&Connection->ReceiveRequest)) { + Entry = RemoveHeadList( &Connection->ReceiveRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, SocketError, 0 ); + Bucket->Status = SocketError; + Bucket->Information = 0; - exFreePool(Bucket); + InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } - while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, - &Connection->Lock )) != NULL) + while (!IsListEmpty(&Connection->SendRequest)) { + Entry = RemoveHeadList( &Connection->SendRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, SocketError, 0 ); + Bucket->Status = SocketError; + Bucket->Information = 0; - exFreePool(Bucket); + InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, - &Connection->Lock )) != NULL) + while (!IsListEmpty(&Connection->ListenRequest)) { + Entry = RemoveHeadList( &Connection->ListenRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, SocketError, 0 ); + Bucket->Status = SocketError; + Bucket->Information = 0; - exFreePool(Bucket); + InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } - while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, - &Connection->Lock )) != NULL) + while (!IsListEmpty(&Connection->ConnectRequest)) { + Entry = RemoveHeadList( &Connection->ConnectRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - Complete( Bucket->Request.RequestContext, SocketError, 0 ); + Bucket->Status = SocketError; + Bucket->Information = 0; - exFreePool(Bucket); + InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + Connection->SignalState = 0; } /* Things that can happen when we try the initial connection */ if( Connection->SignalState & SEL_CONNECT ) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, - &Connection->Lock )) != NULL ) { - - TI_DbgPrint(DEBUG_TCP, ("Connect Event\n")); + while (!IsListEmpty(&Connection->ConnectRequest)) { + Entry = RemoveHeadList( &Connection->ConnectRequest ); Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; - TI_DbgPrint(DEBUG_TCP, - ("Completing Request %x\n", Bucket->Request.RequestContext)); - Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); + Bucket->Status = STATUS_SUCCESS; + Bucket->Information = 0; - /* Frees the bucket allocated in TCPConnect */ - exFreePool( Bucket ); + InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); } if( Connection->SignalState & SEL_ACCEPT ) { /* Handle readable on a listening socket -- * TODO: Implement filtering */ - - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", Connection, IsListEmpty(&Connection->ListenRequest) ? "empty" : "nonempty")); - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, - &Connection->Lock )) != NULL ) { + while (!IsListEmpty(&Connection->ListenRequest)) { PIO_STACK_LOCATION IrpSp; + Entry = RemoveHeadList( &Connection->ListenRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; Irp = Bucket->Request.RequestContext; IrpSp = IoGetCurrentIrpStackLocation( Irp ); TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - Status = TCPServiceListeningSocket ( Connection->AddressFile->Listener, Bucket->AssociatedEndpoint, (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); if( Status == STATUS_PENDING ) { - ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, - &Connection->Lock ); + InsertHeadList( &Connection->ListenRequest, &Bucket->Entry ); break; } else { - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); + Bucket->Status = Status; + Bucket->Information = 0; + + InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } } - - KeAcquireSpinLock(&Connection->Lock, &OldIrql); } /* Things that happen after we're connected */ - if( Connection->SignalState & SEL_READ && - Connection->SignalState & SEL_CONNECT ) { + if( Connection->SignalState & SEL_READ ) { TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", IsListEmpty(&Connection->ReceiveRequest) ? "empty" : "nonempty")); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - - while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, - &Connection->Lock )) != NULL ) { + while (!IsListEmpty(&Connection->ReceiveRequest)) { OSK_UINT RecvLen = 0, Received = 0; PVOID RecvBuffer = 0; + Entry = RemoveHeadList( &Connection->ReceiveRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; Irp = Bucket->Request.RequestContext; Mdl = Irp->MdlAddress; @@ -210,8 +200,6 @@ static VOID DrainSignals() { Connection->SocketContext)); TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - Status = TCPTranslateError ( OskitTCPRecv( Connection->SocketContext, RecvBuffer, @@ -219,46 +207,35 @@ static VOID DrainSignals() { &Received, 0 ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); - if( Status == STATUS_SUCCESS ) { - TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", - Received, Status)); - Complete( Bucket->Request.RequestContext, - STATUS_SUCCESS, Received ); - exFreePool( Bucket ); - } else if( Status == STATUS_PENDING ) { - ExInterlockedInsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry, - &Connection->Lock ); + if( Status == STATUS_PENDING ) { + InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry ); break; } else { TI_DbgPrint(DEBUG_TCP, ("Completing Receive request: %x %x\n", Bucket->Request, Status)); - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); + + Bucket->Status = Status; + Bucket->Information = (Status == STATUS_SUCCESS) ? Received : 0; + + InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } } - - KeAcquireSpinLock(&Connection->Lock, &OldIrql); } - if( Connection->SignalState & SEL_WRITE && - Connection->SignalState & SEL_CONNECT ) { + if( Connection->SignalState & SEL_WRITE ) { TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", IsListEmpty(&Connection->SendRequest) ? "empty" : "nonempty")); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - - while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, - &Connection->Lock )) != NULL ) { + while (!IsListEmpty(&Connection->SendRequest)) { OSK_UINT SendLen = 0, Sent = 0; PVOID SendBuffer = 0; + Entry = RemoveHeadList( &Connection->SendRequest ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - Complete = Bucket->Request.RequestNotifyObject; Irp = Bucket->Request.RequestContext; Mdl = Irp->MdlAddress; @@ -277,8 +254,6 @@ static VOID DrainSignals() { ("Connection->SocketContext: %x\n", Connection->SocketContext)); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - Status = TCPTranslateError ( OskitTCPSend( Connection->SocketContext, SendBuffer, @@ -286,43 +261,55 @@ static VOID DrainSignals() { &Sent, 0 ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); - if( Status == STATUS_SUCCESS ) { - TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n", - Sent, Status)); - Complete( Bucket->Request.RequestContext, - STATUS_SUCCESS, Sent ); - exFreePool( Bucket ); - } else if( Status == STATUS_PENDING ) { - ExInterlockedInsertHeadList( &Connection->SendRequest, &Bucket->Entry, - &Connection->Lock ); + if( Status == STATUS_PENDING ) { + InsertHeadList( &Connection->SendRequest, &Bucket->Entry ); break; } else { TI_DbgPrint(DEBUG_TCP, ("Completing Send request: %x %x\n", Bucket->Request, Status)); - Complete( Bucket->Request.RequestContext, Status, 0 ); - exFreePool( Bucket ); + + Bucket->Status = Status; + Bucket->Information = (Status == STATUS_SUCCESS) ? Sent : 0; + + InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); } } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); } +} - KeReleaseSpinLock(&Connection->Lock, OldIrql); +static +VOID DrainSignals(VOID) { + PCONNECTION_ENDPOINT Connection; + PLIST_ENTRY CurrentEntry; + KIRQL OldIrql; - if (!Connection->SocketContext) - { - TCPFreeConnectionEndpoint(Connection); - } + KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + CurrentEntry = ConnectionEndpointListHead.Flink; + while (CurrentEntry != &ConnectionEndpointListHead) + { + Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, + ListEntry ); + CurrentEntry = CurrentEntry->Flink; + KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - CurrentEntry = NextEntry; + KeAcquireSpinLock(&Connection->Lock, &OldIrql); + if (Connection->SocketContext) + { + HandleSignalledConnection(Connection); + KeReleaseSpinLock(&Connection->Lock, OldIrql); - KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + ProcessCompletions(Connection); + } + else + { + KeReleaseSpinLock(&Connection->Lock, OldIrql); + } + + KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); } - KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); } @@ -342,6 +329,7 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { InitializeListHead(&Connection->ListenRequest); InitializeListHead(&Connection->ReceiveRequest); InitializeListHead(&Connection->SendRequest); + InitializeListHead(&Connection->CompletionQueue); /* Save client context pointer */ Connection->ClientContext = ClientContext; @@ -402,13 +390,21 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) * This is the low level interface for receiving TCP data */ { + KIRQL OldIrql; + TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to oskit\n", IPPacket->TotalSize, IPPacket->HeaderSize)); + KeAcquireSpinLock(&ClientInfo.Lock, &OldIrql); + ClientInfo.Unlocked = TRUE; + OskitTCPReceiveDatagram( IPPacket->Header, IPPacket->TotalSize, IPPacket->HeaderSize ); + + ClientInfo.Unlocked = FALSE; + KeReleaseSpinLock(&ClientInfo.Lock, OldIrql); } /* event.c */ @@ -467,7 +463,7 @@ TimerThread(PVOID Context) while ( 1 ) { if (Next == NextFast) { NextFast += 2; - } + } if (Next == NextSlow) { NextSlow += 5; } @@ -480,9 +476,7 @@ TimerThread(PVOID Context) } TimerOskitTCP( Next == NextFast, Next == NextSlow ); - if (Next == NextSlow) { - DrainSignals(); - } + DrainSignals(); Current = Next; if (10 <= Current) { @@ -502,7 +496,6 @@ StartTimer(VOID) TimerThread, NULL); } - NTSTATUS TCPStartup(VOID) /* * FUNCTION: Initializes the TCP subsystem @@ -523,6 +516,9 @@ NTSTATUS TCPStartup(VOID) return Status; } + KeInitializeSpinLock(&ClientInfo.Lock); + ClientInfo.Unlocked = FALSE; + RegisterOskitTCPEventHandlers( &EventHandlers ); InitOskitTCP(); @@ -862,10 +858,6 @@ NTSTATUS TCPSendData return Status; } -VOID TCPTimeout(VOID) { - /* Now handled by TimerThread */ -} - UINT TCPAllocatePort( UINT HintPort ) { if( HintPort ) { if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort; diff --git a/reactos/lib/drivers/oskittcp/oskittcp/interface.c b/reactos/lib/drivers/oskittcp/oskittcp/interface.c index 685e4bffc64..a925d330434 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/interface.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/interface.c @@ -285,11 +285,16 @@ int OskitTCPShutdown( void *socket, int disconn_type ) { int OskitTCPClose( void *socket ) { int error; + struct socket *so = socket; if (!socket) return OSK_ESHUTDOWN; OSKLock(); + /* We have to remove the socket context here otherwise we end up + * back in HandleSignalledConnection with a freed connection context + */ + so->so_connection = NULL; error = soclose( socket ); OSKUnlock(); @@ -435,16 +440,12 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, OSK_UINT IpHeaderLen ) { struct mbuf *Ip; struct ip *iph; - KIRQL OldIrql; - /* This function is a special case in which we cannot use OSKLock/OSKUnlock - * because we don't enter with the connection lock held */ - - OSKLockAndRaise(&OldIrql); + OSKLock(); Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); if( !Ip ) { - OSKUnlockAndLower(OldIrql); + OSKUnlock(); return; /* drop the segment */ } @@ -461,7 +462,7 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, IpHeaderLen)); tcp_input(Ip, IpHeaderLen); - OSKUnlockAndLower(OldIrql); + OSKUnlock(); /* The buffer Ip is freed by tcp_input */ } From 78b292be2c29b5d925d90042ff1189688ed137d1 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 21 Nov 2009 17:58:33 +0000 Subject: [PATCH 084/140] [ntoskrnl/se] - Factor out working code from SeAccessCheck into SepAccessCheck, taking out addition parameter - LowerImpersonationLevel. The lowest level for SeAccessCheck remains SecurityImpersonation, but for NtAccessCheck it's lowered to SecurityIdentification. Name of this patch's author has been lost. See issue #4169 for more details. svn path=/trunk/; revision=44260 --- reactos/ntoskrnl/se/semgr.c | 80 +++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index 4ceaa19c4af..85cbead194e 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -348,22 +348,18 @@ SeSetSecurityAccessMask(IN SECURITY_INFORMATION SecurityInformation, } } -/* PUBLIC FUNCTIONS ***********************************************************/ - -/* - * @implemented - */ BOOLEAN NTAPI -SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, - IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, - IN BOOLEAN SubjectContextLocked, - IN ACCESS_MASK DesiredAccess, - IN ACCESS_MASK PreviouslyGrantedAccess, - OUT PPRIVILEGE_SET* Privileges, - IN PGENERIC_MAPPING GenericMapping, - IN KPROCESSOR_MODE AccessMode, - OUT PACCESS_MASK GrantedAccess, - OUT PNTSTATUS AccessStatus) +SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, + IN BOOLEAN SubjectContextLocked, + IN ACCESS_MASK DesiredAccess, + IN ACCESS_MASK PreviouslyGrantedAccess, + OUT PPRIVILEGE_SET* Privileges, + IN PGENERIC_MAPPING GenericMapping, + IN KPROCESSOR_MODE AccessMode, + OUT PACCESS_MASK GrantedAccess, + OUT PNTSTATUS AccessStatus, + SECURITY_IMPERSONATION_LEVEL LowestImpersonationLevel) { LUID_AND_ATTRIBUTES Privilege; ACCESS_MASK CurrentAccess, AccessMask; @@ -409,7 +405,7 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, /* Check for invalid impersonation */ if ((SubjectSecurityContext->ClientToken) && - (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation)) + (SubjectSecurityContext->ImpersonationLevel < LowestImpersonationLevel)) { *AccessStatus = STATUS_BAD_IMPERSONATION_LEVEL; return FALSE; @@ -619,6 +615,37 @@ SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, } } +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @implemented + */ +BOOLEAN NTAPI +SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, + IN BOOLEAN SubjectContextLocked, + IN ACCESS_MASK DesiredAccess, + IN ACCESS_MASK PreviouslyGrantedAccess, + OUT PPRIVILEGE_SET* Privileges, + IN PGENERIC_MAPPING GenericMapping, + IN KPROCESSOR_MODE AccessMode, + OUT PACCESS_MASK GrantedAccess, + OUT PNTSTATUS AccessStatus) +{ + /* Call the internal function */ + return SepAccessCheck(SecurityDescriptor, + SubjectSecurityContext, + SubjectContextLocked, + DesiredAccess, + PreviouslyGrantedAccess, + Privileges, + GenericMapping, + AccessMode, + GrantedAccess, + AccessStatus, + SecurityImpersonation); +} + /* SYSTEM CALLS ***************************************************************/ /* @@ -691,16 +718,17 @@ NtAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, SeLockSubjectContext(&SubjectSecurityContext); /* Now perform the access check */ - SeAccessCheck(SecurityDescriptor, - &SubjectSecurityContext, - TRUE, - DesiredAccess, - 0, - &PrivilegeSet, //FIXME - GenericMapping, - PreviousMode, - GrantedAccess, - AccessStatus); + SepAccessCheck(SecurityDescriptor, + &SubjectSecurityContext, + TRUE, + DesiredAccess, + 0, + &PrivilegeSet, //FIXME + GenericMapping, + PreviousMode, + GrantedAccess, + AccessStatus, + SecurityIdentification); /* Unlock subject context and dereference the token */ SeUnlockSubjectContext(&SubjectSecurityContext); From f94c2c5f75220ce076a8e4799858edfe86308f49 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 21 Nov 2009 20:41:24 +0000 Subject: [PATCH 085/140] [kernel32] - Don't export unnecessary stub. Fixes Firefox 3.5.5 startup. svn path=/trunk/; revision=44261 --- reactos/dll/win32/kernel32/kernel32.pspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/dll/win32/kernel32/kernel32.pspec b/reactos/dll/win32/kernel32/kernel32.pspec index 353da456ec2..942bcafb3b7 100644 --- a/reactos/dll/win32/kernel32/kernel32.pspec +++ b/reactos/dll/win32/kernel32/kernel32.pspec @@ -627,7 +627,7 @@ @ stdcall LocalShrink(long long) @ stdcall LocalSize(long) @ stdcall LocalUnlock(long) -@ stub LocaleNameToLCID ; missing in XP SP3 +;@ stub LocaleNameToLCID ; missing in XP SP3 @ stdcall LockFile(long long long long long) @ stdcall LockFileEx(long long long long long ptr) @ stdcall LockResource(long) From 83bc88465fda853d5832f61e37004531b13a948b Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 21 Nov 2009 23:53:43 +0000 Subject: [PATCH 086/140] - Remove memtrack and use tags instead (ExAllocatePoolWithTag/ExFreePoolWithTag) - Cleanup DriverEntry - Remove DEFINE_TAG - Remove checkpoints in TiCreateFileObject svn path=/trunk/; revision=44266 --- reactos/drivers/network/tcpip/datalink/lan.c | 29 +-- .../drivers/network/tcpip/include/address.h | 1 - reactos/drivers/network/tcpip/include/debug.h | 2 - .../drivers/network/tcpip/include/dispatch.h | 2 + reactos/drivers/network/tcpip/include/ip.h | 3 - reactos/drivers/network/tcpip/include/irp.h | 13 -- .../drivers/network/tcpip/include/memtrack.h | 79 ------- .../drivers/network/tcpip/include/neighbor.h | 1 - .../drivers/network/tcpip/include/precomp.h | 3 +- .../drivers/network/tcpip/include/routines.h | 7 +- reactos/drivers/network/tcpip/include/tags.h | 39 ++++ .../drivers/network/tcpip/include/titypes.h | 8 - reactos/drivers/network/tcpip/tcpip.rbuild | 1 - reactos/drivers/network/tcpip/tcpip/buffer.c | 30 ++- .../drivers/network/tcpip/tcpip/dispatch.c | 29 ++- .../drivers/network/tcpip/tcpip/fileobjs.c | 22 +- reactos/drivers/network/tcpip/tcpip/iinfo.c | 8 +- reactos/drivers/network/tcpip/tcpip/irp.c | 37 ---- reactos/drivers/network/tcpip/tcpip/main.c | 202 +++++------------- reactos/drivers/network/tcpip/tcpip/ninfo.c | 16 +- reactos/lib/drivers/ip/ip.rbuild | 1 - reactos/lib/drivers/ip/network/address.c | 2 +- reactos/lib/drivers/ip/network/ip.c | 26 ++- reactos/lib/drivers/ip/network/memtrack.c | 153 ------------- reactos/lib/drivers/ip/network/neighbor.c | 20 +- reactos/lib/drivers/ip/network/ports.c | 5 +- reactos/lib/drivers/ip/network/receive.c | 30 +-- reactos/lib/drivers/ip/network/router.c | 6 +- reactos/lib/drivers/ip/network/routines.c | 4 +- reactos/lib/drivers/ip/network/transmit.c | 12 +- .../drivers/ip/transport/datagram/datagram.c | 9 +- reactos/lib/drivers/ip/transport/tcp/accept.c | 5 +- reactos/lib/drivers/ip/transport/tcp/event.c | 13 +- reactos/lib/drivers/ip/transport/tcp/tcp.c | 15 +- .../lib/drivers/oskittcp/include/memtrack.h | 80 ------- 35 files changed, 249 insertions(+), 664 deletions(-) delete mode 100644 reactos/drivers/network/tcpip/include/irp.h delete mode 100644 reactos/drivers/network/tcpip/include/memtrack.h create mode 100644 reactos/drivers/network/tcpip/include/tags.h delete mode 100644 reactos/drivers/network/tcpip/tcpip/irp.c delete mode 100644 reactos/lib/drivers/ip/network/memtrack.c delete mode 100644 reactos/lib/drivers/oskittcp/include/memtrack.h diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index 21601630fdd..fd0b818ac1b 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -108,7 +108,7 @@ VOID FreeAdapter( * Adapter = Pointer to LAN_ADAPTER structure to free */ { - exFreePool(Adapter); + ExFreePoolWithTag(Adapter, LAN_ADAPTER_TAG); } @@ -249,7 +249,7 @@ VOID LanReceiveWorker( PVOID Context ) { Adapter = WorkItem->Adapter; BytesTransferred = WorkItem->BytesTransferred; - exFreePool(WorkItem); + ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG); IPInitializePacket(&IPPacket, 0); @@ -300,7 +300,8 @@ VOID LanSubmitReceiveWork( PNDIS_PACKET Packet, NDIS_STATUS Status, UINT BytesTransferred) { - PLAN_WQ_ITEM WQItem = exAllocatePool(NonPagedPool, sizeof(LAN_WQ_ITEM)); + PLAN_WQ_ITEM WQItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_WQ_ITEM), + WQ_CONTEXT_TAG); PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; TI_DbgPrint(DEBUG_DATALINK,("called\n")); @@ -312,7 +313,7 @@ VOID LanSubmitReceiveWork( WQItem->BytesTransferred = BytesTransferred; if (!ChewCreate( LanReceiveWorker, WQItem )) - exFreePool(WQItem); + ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG); } VOID NTAPI ProtocolTransferDataComplete( @@ -768,9 +769,9 @@ NTSTATUS NTAPI AppendUnicodeString(PUNICODE_STRING ResultFirst, BOOLEAN Deallocate) { NTSTATUS Status; UNICODE_STRING Ustr = *ResultFirst; - PWSTR new_string = ExAllocatePoolWithTag + PWSTR new_string = ExAllocatePool (PagedPool, - (ResultFirst->Length + Second->Length + sizeof(WCHAR)), TAG_STRING); + (ResultFirst->Length + Second->Length + sizeof(WCHAR))); if( !new_string ) { return STATUS_NO_MEMORY; } @@ -1087,7 +1088,7 @@ NDIS_STATUS LANRegisterAdapter( TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); - IF = exAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER)); + IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_ADAPTER), LAN_ADAPTER_TAG); if (!IF) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NDIS_STATUS_RESOURCES; @@ -1125,7 +1126,7 @@ NDIS_STATUS LANRegisterAdapter( KeWaitForSingleObject(&IF->Event, UserRequest, KernelMode, FALSE, NULL); else if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ\n", AdapterName)); - exFreePool(IF); + ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); return NdisStatus; } @@ -1150,7 +1151,7 @@ NDIS_STATUS LANRegisterAdapter( default: /* Unsupported media */ TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n")); - exFreePool(IF); + ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); return NDIS_STATUS_NOT_SUPPORTED; } @@ -1162,7 +1163,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (NDISCall)\n", AdapterName)); - exFreePool(IF); + ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); return NdisStatus; } @@ -1174,7 +1175,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n")); - exFreePool(IF); + ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); return NdisStatus; } @@ -1197,7 +1198,7 @@ NDIS_STATUS LANRegisterAdapter( IF->HWAddressLength); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n")); - exFreePool(IF); + ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); return NdisStatus; } @@ -1209,7 +1210,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n")); - exFreePool(IF); + ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); return NdisStatus; } @@ -1219,7 +1220,7 @@ NDIS_STATUS LANRegisterAdapter( /* Bind adapter to IP layer */ if( !BindAdapter(IF, RegistryPath) ) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName)); - exFreePool(IF); + ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); return NDIS_STATUS_NOT_ACCEPTED; } diff --git a/reactos/drivers/network/tcpip/include/address.h b/reactos/drivers/network/tcpip/include/address.h index 71a0f876499..1bd1dbd5c15 100644 --- a/reactos/drivers/network/tcpip/include/address.h +++ b/reactos/drivers/network/tcpip/include/address.h @@ -15,7 +15,6 @@ */ #define AddrInitIPv4(IPAddress, RawAddress) \ { \ - INIT_TAG((IPAddress), '4VPI'); \ (IPAddress)->Type = IP_ADDRESS_V4; \ (IPAddress)->Address.IPv4Address = (RawAddress); \ } diff --git a/reactos/drivers/network/tcpip/include/debug.h b/reactos/drivers/network/tcpip/include/debug.h index 3bf4fb303c2..7f6d86b8e27 100644 --- a/reactos/drivers/network/tcpip/include/debug.h +++ b/reactos/drivers/network/tcpip/include/debug.h @@ -71,8 +71,6 @@ #define CP CHECKPOINT -#include - #define ASSERT_KM_POINTER(_x) \ ASSERT(((PVOID)_x) != (PVOID)0xcccccccc); \ ASSERT(((PVOID)_x) >= (PVOID)0x80000000); diff --git a/reactos/drivers/network/tcpip/include/dispatch.h b/reactos/drivers/network/tcpip/include/dispatch.h index f9344252a8a..6be0f269aed 100644 --- a/reactos/drivers/network/tcpip/include/dispatch.h +++ b/reactos/drivers/network/tcpip/include/dispatch.h @@ -72,6 +72,8 @@ NTSTATUS DispTdiDeleteIPAddress( VOID DispDoDisconnect( PVOID Data); +NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ); + #endif /* __DISPATCH_H */ /* EOF */ diff --git a/reactos/drivers/network/tcpip/include/ip.h b/reactos/drivers/network/tcpip/include/ip.h index 61f8e7a2414..068992f4839 100644 --- a/reactos/drivers/network/tcpip/include/ip.h +++ b/reactos/drivers/network/tcpip/include/ip.h @@ -21,7 +21,6 @@ typedef IPv6_RAW_ADDRESS *PIPv6_RAW_ADDRESS; /* IP style address */ typedef struct IP_ADDRESS { - DEFINE_TAG UCHAR Type; /* Type of IP address */ union { IPv4_RAW_ADDRESS IPv4Address;/* IPv4 address (in network byte order) */ @@ -76,7 +75,6 @@ typedef VOID (*PACKET_COMPLETION_ROUTINE)( /* Structure for an IP packet */ typedef struct _IP_PACKET { - DEFINE_TAG OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */ UCHAR Type; /* Type of IP packet (see IP_ADDRESS_xx above) */ UCHAR Flags; /* Flags for packet (see IP_PACKET_FLAG_xx below)*/ @@ -150,7 +148,6 @@ typedef struct _SEND_RECV_STATS { /* Information about an IP interface */ typedef struct _IP_INTERFACE { - DEFINE_TAG LIST_ENTRY ListEntry; /* Entry on list */ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources used by the object */ KSPIN_LOCK Lock; /* Spin lock for this object */ diff --git a/reactos/drivers/network/tcpip/include/irp.h b/reactos/drivers/network/tcpip/include/irp.h deleted file mode 100644 index 532200980ab..00000000000 --- a/reactos/drivers/network/tcpip/include/irp.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS TCP/IP protocol driver - * FILE: include/irp.h - * PURPOSE: IRP routines - */ -#ifndef __IRP_H -#define __IRP_H - -VOID IRPRemember( PIRP Irp, PCHAR File, UINT Line ); -NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ); - -#endif/*__IRP_H*/ diff --git a/reactos/drivers/network/tcpip/include/memtrack.h b/reactos/drivers/network/tcpip/include/memtrack.h deleted file mode 100644 index 778d7b75cc4..00000000000 --- a/reactos/drivers/network/tcpip/include/memtrack.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef MEMTRACK_H -#define MEMTRACK_H - -#include - -#ifndef FOURCC -#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) -#endif - -#define FBSD_MALLOC FOURCC('d','s','b','f') -#define EXALLOC_TAG FOURCC('E','x','A','l') -#define IRP_TAG FOURCC('P','I','R','P') -#define NPLOOK_TAG FOURCC('N','P','L','A') - -#define AllocatePacketWithBuffer(x,y,z) AllocatePacketWithBufferX(x,y,z,__FILE__,__LINE__) -#define FreeNdisPacket(x) FreeNdisPacketX(x,__FILE__,__LINE__) - -#if DBG -#define MTMARK() TrackDumpFL(__FILE__, __LINE__) -#define exAllocatePool(x,y) ExAllocatePoolX(x,y,__FILE__,__LINE__) -#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolX(x,y,__FILE__,__LINE__) -#define exFreePool(x) ExFreePoolX(x,__FILE__,__LINE__) -#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideListX(x,__FILE__,__LINE__) -#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideListX(x,y,__FILE__,__LINE__) - -typedef struct _ALLOCATION_TRACKER { - LIST_ENTRY Entry; - ULONG Tag; - PVOID Thing; - PCHAR FileName; - ULONG LineNo; -} ALLOCATION_TRACKER, *PALLOCATION_TRACKER; - -VOID TrackingInit(); -VOID TrackWithTag( ULONG Tag, PVOID Thing, PCHAR File, ULONG Line ); -#define Track(Tag,Thing) TrackWithTag(Tag,Thing,__FILE__,__LINE__) -VOID UntrackFL( PCHAR File, ULONG Line, PVOID Thing, ULONG Tag ); -#define Untrack(Thing) UntrackFL(__FILE__,__LINE__,Thing) -VOID TrackDumpFL( PCHAR File, ULONG Line ); -#define TrackDump() TrackDumpFL(__FILE__,__LINE__) - -static __inline PVOID ExAllocateFromNPagedLookasideListX( PNPAGED_LOOKASIDE_LIST List, PCHAR File, ULONG Line ) { - PVOID Out = ExAllocateFromNPagedLookasideList( List ); - if( Out ) TrackWithTag( NPLOOK_TAG, Out, File, Line ); - return Out; -} - -static __inline VOID ExFreeToNPagedLookasideListX( PNPAGED_LOOKASIDE_LIST List, PVOID Thing, PCHAR File, ULONG Line ) { - UntrackFL(File, Line, Thing, NPLOOK_TAG); - ExFreeToNPagedLookasideList( List, Thing ); -} - -static __inline PVOID ExAllocatePoolX( POOL_TYPE type, SIZE_T size, PCHAR File, ULONG Line ) { - PVOID Out = ExAllocatePool( type, size ); - if( Out ) TrackWithTag( EXALLOC_TAG, Out, File, Line ); - return Out; -} - -static __inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) { - UntrackFL(File, Line, Data, EXALLOC_TAG); - ExFreePool( Data ); -} - -#else -#define MTMARK() -#define Track(x,y) -#define TrackingInit() -#define TrackDump() -#define Untrack(x) -#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolWithTag(x,y,z) -#define exAllocatePool(x,y) ExAllocatePool(x,y) -#define exFreePool(x) ExFreePool(x) -#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideList(x) -#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideList(x,y) -#define TrackWithTag(w,x,y,z) -#define UntrackFL(w,x,y,z) -#endif - -#endif/*MEMMTRAC_H*/ diff --git a/reactos/drivers/network/tcpip/include/neighbor.h b/reactos/drivers/network/tcpip/include/neighbor.h index 95ea1f92769..6f125f06c51 100644 --- a/reactos/drivers/network/tcpip/include/neighbor.h +++ b/reactos/drivers/network/tcpip/include/neighbor.h @@ -27,7 +27,6 @@ typedef struct NEIGHBOR_CACHE_TABLE { /* Information about a neighbor */ typedef struct NEIGHBOR_CACHE_ENTRY { - DEFINE_TAG struct NEIGHBOR_CACHE_ENTRY *Next; /* Pointer to next entry */ UCHAR State; /* State of NCE */ UINT EventTimer; /* Ticks since last event */ diff --git a/reactos/drivers/network/tcpip/include/precomp.h b/reactos/drivers/network/tcpip/include/precomp.h index a7b2c885962..f37046d128e 100644 --- a/reactos/drivers/network/tcpip/include/precomp.h +++ b/reactos/drivers/network/tcpip/include/precomp.h @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -23,13 +24,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include diff --git a/reactos/drivers/network/tcpip/include/routines.h b/reactos/drivers/network/tcpip/include/routines.h index 31d7075abca..1fda0e5aee8 100644 --- a/reactos/drivers/network/tcpip/include/routines.h +++ b/reactos/drivers/network/tcpip/include/routines.h @@ -49,9 +49,10 @@ UINT ResizePacket( PNDIS_PACKET Packet, UINT Size); -NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, - PCHAR Data, UINT Len, - PCHAR File, UINT Line ); +NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket, + PCHAR Data, UINT Len ); + +VOID FreeNdisPacket( PNDIS_PACKET Packet ); void GetDataPtr( PNDIS_PACKET Packet, UINT Offset, diff --git a/reactos/drivers/network/tcpip/include/tags.h b/reactos/drivers/network/tcpip/include/tags.h new file mode 100644 index 00000000000..52c16a45cc9 --- /dev/null +++ b/reactos/drivers/network/tcpip/include/tags.h @@ -0,0 +1,39 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: include/tags.h + * PURPOSE: Memory tags + */ +#ifndef __TAGS_H +#define __TAGS_H + +#define CONN_ENDPT_TAG 'pEnC' +#define ADDR_FILE_TAG 'FrdA' +#define CONTROL_CHANNEL_TAG 'CnoC' +#define TRANS_CONTEXT_TAG 'noCT' +#define TDI_ENTITY_TAG 'EidT' +#define DATAGRAM_SEND_TAG 'StaD' +#define DATAGRAM_RECV_TAG 'RtaD' +#define QUERY_CONTEXT_TAG 'noCQ' +#define IP_ADDRESS_TAG 'dAPI' +#define IP_INTERFACE_TAG 'FIPI' +#define DATAGRAM_REASSEMBLY_TAG 'RDPI' +#define DATAGRAM_FRAGMENT_TAG 'GFPI' +#define DATAGRAM_HOLE_TAG 'LHPI' +#define OSKITTCP_CONTEXT_TAG 'TKSO' +#define NEIGHBOR_PACKET_TAG 'kPbN' +#define NCE_TAG ' ECN' +#define PORT_SET_TAG 'teSP' +#define PACKET_BUFFER_TAG 'fuBP' +#define FRAGMENT_DATA_TAG 'taDF' +#define FIB_TAG ' BIF' +#define IFC_TAG ' CFI' +#define TDI_BUCKET_TAG 'BidT' +#define FBSD_TAG 'DSBF' +#define OSK_OTHER_TAG 'OKSO' +#define OSK_LARGE_TAG 'LKSO' +#define OSK_SMALL_TAG 'SKSO' +#define LAN_ADAPTER_TAG ' NAL' +#define WQ_CONTEXT_TAG 'noCW' + +#endif diff --git a/reactos/drivers/network/tcpip/include/titypes.h b/reactos/drivers/network/tcpip/include/titypes.h index 88a02bb15e5..78584fb1391 100644 --- a/reactos/drivers/network/tcpip/include/titypes.h +++ b/reactos/drivers/network/tcpip/include/titypes.h @@ -10,10 +10,6 @@ #if DBG -#define DEFINE_TAG ULONG Tag; -#define INIT_TAG(_Object, _Tag) \ - ((_Object)->Tag = (_Tag)) - #define DEBUG_REFCHECK(Object) { \ if ((Object)->RefCount <= 0) { \ TI_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \ @@ -64,9 +60,6 @@ #else /* DBG */ -#define DEFINE_TAG -#define INIT_TAG(Object, Tag) - /* * VOID ReferenceObject( * PVOID Object) @@ -149,7 +142,6 @@ typedef struct _DATAGRAM_SEND_REQUEST { /* Transport address file context structure. The FileObject->FsContext2 field holds a pointer to this structure */ typedef struct _ADDRESS_FILE { - DEFINE_TAG LIST_ENTRY ListEntry; /* Entry on list */ KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ diff --git a/reactos/drivers/network/tcpip/tcpip.rbuild b/reactos/drivers/network/tcpip/tcpip.rbuild index 4dd14d3cbdf..ea9d3a6d5e1 100644 --- a/reactos/drivers/network/tcpip/tcpip.rbuild +++ b/reactos/drivers/network/tcpip/tcpip.rbuild @@ -28,7 +28,6 @@ fileobjs.c iinfo.c info.c - irp.c lock.c main.c ninfo.c diff --git a/reactos/drivers/network/tcpip/tcpip/buffer.c b/reactos/drivers/network/tcpip/tcpip/buffer.c index e604c7bcacc..6858ddea984 100644 --- a/reactos/drivers/network/tcpip/tcpip/buffer.c +++ b/reactos/drivers/network/tcpip/tcpip/buffer.c @@ -318,13 +318,16 @@ NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Length, PCHAR NewBuf; if( Copy ) { - NewBuf = exAllocatePool( NonPagedPool, Length ); + NewBuf = ExAllocatePoolWithTag( NonPagedPool, Length, PACKET_BUFFER_TAG ); if( !NewBuf ) return NDIS_STATUS_RESOURCES; RtlCopyMemory( NewBuf, Data, Length ); } else NewBuf = Data; NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewBuf, Length ); - if( Status != NDIS_STATUS_SUCCESS ) return Status; + if( Status != NDIS_STATUS_SUCCESS ) { + if (Copy) ExFreePoolWithTag(NewBuf, PACKET_BUFFER_TAG); + return Status; + } NdisChainBufferAtFront( Packet, Buffer ); @@ -342,33 +345,30 @@ void GetDataPtr( PNDIS_PACKET Packet, SkipToOffset( Buffer, Offset, DataOut, Size ); } -NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, - PCHAR Data, UINT Len, - PCHAR File, UINT Line ) { +NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket, + PCHAR Data, UINT Len ) { PNDIS_PACKET Packet; PNDIS_BUFFER Buffer; NDIS_STATUS Status; PCHAR NewData; - NewData = exAllocatePool( NonPagedPool, Len ); + NewData = ExAllocatePoolWithTag( NonPagedPool, Len, PACKET_BUFFER_TAG ); if( !NewData ) return NDIS_STATUS_RESOURCES; if( Data ) RtlCopyMemory(NewData, Data, Len); NdisAllocatePacket( &Status, &Packet, GlobalPacketPool ); if( Status != NDIS_STATUS_SUCCESS ) { - exFreePool( NewData ); + ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG ); return Status; } - TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line); NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len ); if( Status != NDIS_STATUS_SUCCESS ) { - exFreePool( NewData ); + ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG ); FreeNdisPacket( Packet ); return Status; } - TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line); NdisChainBufferAtFront( Packet, Buffer ); *NdisPacket = Packet; @@ -377,10 +377,8 @@ NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, } -VOID FreeNdisPacketX -( PNDIS_PACKET Packet, - PCHAR File, - UINT Line ) +VOID FreeNdisPacket +( PNDIS_PACKET Packet ) /* * FUNCTION: Frees an NDIS packet * ARGUMENTS: @@ -400,13 +398,11 @@ VOID FreeNdisPacketX NdisGetNextBuffer(Buffer, &NextBuffer); NdisQueryBuffer(Buffer, &Data, &Length); TI_DbgPrint(DEBUG_PBUFFER, ("Freeing ndis buffer (0x%X)\n", Buffer)); - UntrackFL(File,Line,Buffer,NDIS_BUFFER_TAG); NdisFreeBuffer(Buffer); TI_DbgPrint(DEBUG_PBUFFER, ("Freeing exal buffer (0x%X)\n", Data)); - exFreePool(Data); + ExFreePoolWithTag(Data, PACKET_BUFFER_TAG); } /* Finally free the NDIS packet discriptor */ - UntrackFL(File,Line,Packet,NDIS_PACKET_TAG); NdisFreePacket(Packet); } diff --git a/reactos/drivers/network/tcpip/tcpip/dispatch.c b/reactos/drivers/network/tcpip/tcpip/dispatch.c index d08ef8aecfa..c78aeceb89f 100644 --- a/reactos/drivers/network/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/network/tcpip/tcpip/dispatch.c @@ -12,6 +12,25 @@ #include "precomp.h" #include + +NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) { + KIRQL OldIrql; + + Irp->IoStatus.Status = Status; + + if( Status == STATUS_PENDING ) + IoMarkIrpPending( Irp ); + else { + IoAcquireCancelSpinLock(&OldIrql); + (void)IoSetCancelRoutine( Irp, NULL ); + IoReleaseCancelSpinLock(OldIrql); + + IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); + } + + return Status; +} + NTSTATUS DispPrepareIrpForCancel( PTRANSPORT_CONTEXT Context, PIRP Irp, @@ -1253,7 +1272,7 @@ VOID DispTdiQueryInformationExComplete( QueryContext->Irp->IoStatus.Information = ByteCount; QueryContext->Irp->IoStatus.Status = Status; - exFreePool(QueryContext); + ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); } @@ -1316,7 +1335,7 @@ NTSTATUS DispTdiQueryInformationEx( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; OutputBuffer = Irp->UserBuffer; - QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT)); + QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); if (QueryContext) { _SEH2_TRY { InputMdl = IoAllocateMdl(InputBuffer, @@ -1379,7 +1398,7 @@ NTSTATUS DispTdiQueryInformationEx( IoFreeMdl(OutputMdl); } - exFreePool(QueryContext); + ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); } else Status = STATUS_INSUFFICIENT_RESOURCES; } else if( InputBufferLength == @@ -1392,7 +1411,7 @@ NTSTATUS DispTdiQueryInformationEx( Size = 0; - QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT)); + QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES; _SEH2_TRY { @@ -1412,7 +1431,7 @@ NTSTATUS DispTdiQueryInformationEx( if( !NT_SUCCESS(Status) || !InputMdl ) { if( InputMdl ) IoFreeMdl( InputMdl ); - exFreePool(QueryContext); + ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); return Status; } diff --git a/reactos/drivers/network/tcpip/tcpip/fileobjs.c b/reactos/drivers/network/tcpip/tcpip/fileobjs.c index dec7a0c9576..88ac1858b1e 100644 --- a/reactos/drivers/network/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/network/tcpip/tcpip/fileobjs.c @@ -153,7 +153,7 @@ VOID AddrFileFree( * Object = Pointer to address file object to free */ { - exFreePool(Object); + ExFreePoolWithTag(Object, ADDR_FILE_TAG); } @@ -165,7 +165,7 @@ VOID ControlChannelFree( * Object = Pointer to address file object to free */ { - exFreePool(Object); + ExFreePoolWithTag(Object, CONTROL_CHANNEL_TAG); } @@ -189,7 +189,8 @@ NTSTATUS FileOpenAddress( TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol)); - AddrFile = exAllocatePool(NonPagedPool, sizeof(ADDRESS_FILE)); + AddrFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(ADDRESS_FILE), + ADDR_FILE_TAG); if (!AddrFile) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; @@ -212,7 +213,7 @@ NTSTATUS FileOpenAddress( if (!AddrIsUnspecified(&AddrFile->Address) && !AddrLocateInterface(&AddrFile->Address)) { - exFreePool(AddrFile); + ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", A2S(&AddrFile->Address))); return STATUS_INVALID_PARAMETER; } @@ -230,7 +231,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port != Address->Address[0].Address[0].sin_port) || AddrFile->Port == 0xffff) { - exFreePool(AddrFile); + ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); return STATUS_INVALID_PARAMETER; } @@ -248,7 +249,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port != Address->Address[0].Address[0].sin_port) || AddrFile->Port == 0xffff) { - exFreePool(AddrFile); + ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); return STATUS_INVALID_PARAMETER; } @@ -346,7 +347,7 @@ NTSTATUS FileCloseAddress( while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0); - /* exFreePool(ReceiveRequest); FIXME: WTF? */ + /* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */ } TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile)); @@ -355,7 +356,7 @@ NTSTATUS FileCloseAddress( while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry); (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0); - exFreePool(SendRequest); + ExFreePoolWithTag(SendRequest, DATAGRAM_SEND_TAG); } /* Protocol specific handling */ @@ -454,7 +455,8 @@ NTSTATUS FileOpenControlChannel( PCONTROL_CHANNEL ControlChannel; TI_DbgPrint(MID_TRACE, ("Called.\n")); - ControlChannel = exAllocatePool(NonPagedPool, sizeof(*ControlChannel)); + ControlChannel = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ControlChannel), + CONTROL_CHANNEL_TAG); if (!ControlChannel) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); @@ -494,7 +496,7 @@ NTSTATUS FileCloseControlChannel( PCONTROL_CHANNEL ControlChannel = Request->Handle.ControlChannel; NTSTATUS Status = STATUS_SUCCESS; - exFreePool(ControlChannel); + ExFreePoolWithTag(ControlChannel, CONTROL_CHANNEL_TAG); Request->Handle.ControlChannel = NULL; return Status; diff --git a/reactos/drivers/network/tcpip/tcpip/iinfo.c b/reactos/drivers/network/tcpip/tcpip/iinfo.c index 7494d0a8113..7a9f35c794f 100644 --- a/reactos/drivers/network/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/network/tcpip/tcpip/iinfo.c @@ -32,7 +32,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID ID, Interface, IF, ID.tei_entity, ID.tei_instance)); OutData = - (PIFENTRY)exAllocatePool( NonPagedPool, + (PIFENTRY)ExAllocatePool( NonPagedPool, sizeof(IFENTRY) + MAX_IFDESCR_LEN ); if( !OutData ) return TDI_NO_RESOURCES; /* Out of memory */ @@ -99,7 +99,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID ID, ID.tei_entity, ID.tei_instance, Size)); Status = InfoCopyOut( (PCHAR)OutData, Size, Buffer, BufferSize ); - exFreePool( OutData ); + ExFreePool( OutData ); TI_DbgPrint(DEBUG_INFO,("Returning %x\n", Status)); @@ -117,14 +117,14 @@ TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID ID, if (MemSize != 0) { - ArpEntries = exAllocatePoolWithTag( NonPagedPool, MemSize, FOURCC('A','R','P','t') ); + ArpEntries = ExAllocatePool( NonPagedPool, MemSize ); if( !ArpEntries ) return STATUS_NO_MEMORY; NBCopyNeighbors( Interface, ArpEntries ); Status = InfoCopyOut( (PVOID)ArpEntries, MemSize, Buffer, BufferSize ); - exFreePool( ArpEntries ); + ExFreePool( ArpEntries ); } else { diff --git a/reactos/drivers/network/tcpip/tcpip/irp.c b/reactos/drivers/network/tcpip/tcpip/irp.c deleted file mode 100644 index f2fc589d19b..00000000000 --- a/reactos/drivers/network/tcpip/tcpip/irp.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS TCP/IP protocol driver - * FILE: tcpip/dispatch.h - * PURPOSE: TDI dispatch routines - * PROGRAMMERS: arty - * REVISIONS: - * CSH 01/08-2000 Created - * TODO: Validate device object in all dispatch routines - */ - -#include "precomp.h" - -VOID IRPRemember( PIRP Irp, PCHAR File, UINT Line ) { - TrackWithTag( IRP_TAG, Irp, File, Line ); -} - -NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) { - KIRQL OldIrql; - - UntrackFL( __FILE__, __LINE__, Irp, IRP_TAG ); - - Irp->IoStatus.Status = Status; - - if( Status == STATUS_PENDING ) - IoMarkIrpPending( Irp ); - else { - IoAcquireCancelSpinLock(&OldIrql); - (void)IoSetCancelRoutine( Irp, NULL ); - IoReleaseCancelSpinLock(OldIrql); - - IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); - } - - return Status; -} - diff --git a/reactos/drivers/network/tcpip/tcpip/main.c b/reactos/drivers/network/tcpip/tcpip/main.c index 7e45cccba5a..d1ce6c73c1d 100644 --- a/reactos/drivers/network/tcpip/tcpip/main.c +++ b/reactos/drivers/network/tcpip/tcpip/main.c @@ -119,30 +119,25 @@ NTSTATUS TiCreateFileObject( TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp)); EaInfo = Irp->AssociatedIrp.SystemBuffer; -CP + /* Parameter check */ /* No EA information means that we're opening for SET/QUERY_INFORMATION * style calls. */ -#if 0 - if (!EaInfo) { - TI_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n")); - return STATUS_INVALID_PARAMETER; - } -#endif -CP + /* Allocate resources here. We release them again if something failed */ - Context = exAllocatePool(NonPagedPool, sizeof(TRANSPORT_CONTEXT)); + Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSPORT_CONTEXT), + TRANS_CONTEXT_TAG); if (!Context) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; } -CP + Context->CancelIrps = FALSE; -CP + IrpSp = IoGetCurrentIrpStackLocation(Irp); IrpSp->FileObject->FsContext = Context; Request.RequestContext = Irp; -CP + /* Branch to the right handler */ if (EaInfo && (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) && @@ -150,7 +145,7 @@ CP (&EaInfo->EaName, TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH)) { /* This is a request to open an address */ -CP + /* XXX This should probably be done in IoCreateFile() */ /* Parameter checks */ @@ -169,10 +164,10 @@ CP TI_DbgPrint(MIN_TRACE, ("AddressType: %\n", Address->Address[0].AddressType)); } - exFreePool(Context); + ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); return STATUS_INVALID_PARAMETER; } -CP + /* Open address file object */ /* Protocol depends on device object so find the protocol */ @@ -186,21 +181,21 @@ CP Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n")); - exFreePool(Context); + ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); return STATUS_INVALID_PARAMETER; } } else { TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject)); - exFreePool(Context); + ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); return STATUS_INVALID_PARAMETER; } -CP + Status = FileOpenAddress(&Request, Address, Protocol, NULL); if (NT_SUCCESS(Status)) { IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE; Context->Handle.AddressHandle = Request.Handle.AddressHandle; } -CP + } else if (EaInfo && (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) && (RtlCompareMemory @@ -208,12 +203,12 @@ CP TDI_CONNECTION_CONTEXT_LENGTH) == TDI_CONNECTION_CONTEXT_LENGTH)) { /* This is a request to open a connection endpoint */ -CP + /* Parameter checks */ if (EaInfo->EaValueLength < sizeof(PVOID)) { TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n")); - exFreePool(Context); + ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); return STATUS_INVALID_PARAMETER; } @@ -221,7 +216,7 @@ CP if (DeviceObject != TCPDeviceObject) { TI_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - exFreePool(Context); + ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); return STATUS_INVALID_PARAMETER; } @@ -244,7 +239,7 @@ CP } if (!NT_SUCCESS(Status)) - exFreePool(Context); + ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status)); @@ -323,8 +318,6 @@ TiDispatchOpenClose( PIO_STACK_LOCATION IrpSp; NTSTATUS Status; - IRPRemember(Irp, __FILE__, __LINE__); - // DbgPrint("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp); IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -367,8 +360,6 @@ TiDispatchInternal( BOOLEAN Complete = TRUE; PIO_STACK_LOCATION IrpSp; - IRPRemember(Irp, __FILE__, __LINE__); - IrpSp = IoGetCurrentIrpStackLocation(Irp); TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n", @@ -471,8 +462,6 @@ TiDispatch( NTSTATUS Status; PIO_STACK_LOCATION IrpSp; - IRPRemember(Irp, __FILE__, __LINE__); - IrpSp = IoGetCurrentIrpStackLocation(Irp); TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp)); @@ -541,8 +530,6 @@ VOID NTAPI TiUnload( } TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); #endif - ChewShutdown(); - /* Cancel timer */ KeCancelTimer(&IPTimer); @@ -580,11 +567,13 @@ VOID NTAPI TiUnload( if (RawIPDeviceObject) IoDeleteDevice(RawIPDeviceObject); - if (IPDeviceObject) - IoDeleteDevice(IPDeviceObject); + if (IPDeviceObject) { + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + } if (EntityList) - exFreePool(EntityList); + ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } @@ -635,17 +624,22 @@ DriverEntry( TI_DbgPrint(MAX_TRACE, ("Called.\n")); - TrackingInit(); - /* TdiInitialize() ? */ /* FIXME: Create symbolic links in Win32 namespace */ + /* Initialize our periodic timer and its associated DPC object. When the + timer expires, the IPTimeout deferred procedure call (DPC) is queued */ + ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL ); + KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL); + KeInitializeTimer(&IPTimer); + /* Create IP device object */ Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status)); + TiUnload(DriverObject); return Status; } @@ -656,8 +650,7 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status)); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); + TiUnload(DriverObject); return Status; } @@ -666,9 +659,7 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status)); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); + TiUnload(DriverObject); return Status; } @@ -677,23 +668,18 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status)); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); + TiUnload(DriverObject); return Status; } /* Setup network layer and transport layer entities */ KeInitializeSpinLock(&EntityListLock); - EntityList = exAllocatePool(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES ); + EntityList = ExAllocatePoolWithTag(NonPagedPool, + sizeof(TDIEntityID) * MAX_TDI_ENTITIES, + TDI_ENTITY_TAG ); if (!EntityList) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); + TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } @@ -703,25 +689,14 @@ DriverEntry( /* Allocate NDIS packet descriptors */ NdisAllocatePacketPool(&NdisStatus, &GlobalPacketPool, 100, sizeof(PACKET_CONTEXT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); - exFreePool(EntityList); + TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate NDIS buffer descriptors */ NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 100); if (NdisStatus != NDIS_STATUS_SUCCESS) { - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); - exFreePool(EntityList); - NdisFreePacketPool(GlobalPacketPool); + TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } @@ -743,64 +718,26 @@ DriverEntry( /* Initialize transport level protocol subsystems */ Status = RawIPStartup(); if( !NT_SUCCESS(Status) ) { - IPShutdown(); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); - exFreePool(EntityList); - NdisFreePacketPool(GlobalPacketPool); - NdisFreeBufferPool(GlobalBufferPool); - return Status; + TiUnload(DriverObject); + return Status; } Status = UDPStartup(); if( !NT_SUCCESS(Status) ) { - RawIPShutdown(); - IPShutdown(); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); - exFreePool(EntityList); - NdisFreePacketPool(GlobalPacketPool); - NdisFreeBufferPool(GlobalBufferPool); - return Status; + TiUnload(DriverObject); + return Status; } Status = TCPStartup(); if( !NT_SUCCESS(Status) ) { - UDPShutdown(); - RawIPShutdown(); - IPShutdown(); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); - exFreePool(EntityList); - NdisFreePacketPool(GlobalPacketPool); - NdisFreeBufferPool(GlobalBufferPool); - return Status; + TiUnload(DriverObject); + return Status; } Status = ICMPStartup(); if( !NT_SUCCESS(Status) ) { - TCPShutdown(); - UDPShutdown(); - RawIPShutdown(); - IPShutdown(); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); - exFreePool(EntityList); - NdisFreePacketPool(GlobalPacketPool); - NdisFreeBufferPool(GlobalBufferPool); - return Status; + TiUnload(DriverObject); + return Status; } /* Use direct I/O */ @@ -817,33 +754,11 @@ DriverEntry( DriverObject->DriverUnload = TiUnload; - /* Initialize our periodic timer and its associated DPC object. When the - timer expires, the IPTimeout deferred procedure call (DPC) is queued */ - ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL ); - KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL); - KeInitializeTimer(&IPTimer); - - /* Start the periodic timer with an initial and periodic - relative expiration time of IP_TIMEOUT milliseconds */ - DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000; - KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc); - /* Open loopback adapter */ Status = LoopRegisterAdapter(NULL, NULL); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status)); - TCPShutdown(); - UDPShutdown(); - RawIPShutdown(); - IPShutdown(); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); - exFreePool(EntityList); - NdisFreePacketPool(GlobalPacketPool); - NdisFreeBufferPool(GlobalBufferPool); + TiUnload(DriverObject); return Status; } @@ -860,25 +775,18 @@ DriverEntry( NULL, 0, NULL); - TCPShutdown(); - UDPShutdown(); - RawIPShutdown(); - IPShutdown(); - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - IoDeleteDevice(RawIPDeviceObject); - IoDeleteDevice(UDPDeviceObject); - IoDeleteDevice(TCPDeviceObject); - exFreePool(EntityList); - NdisFreePacketPool(GlobalPacketPool); - NdisFreeBufferPool(GlobalBufferPool); - return Status; + TiUnload(DriverObject); + return Status; } + /* Start the periodic timer with an initial and periodic + relative expiration time of IP_TIMEOUT milliseconds */ + DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000; + KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc); + return STATUS_SUCCESS; } - VOID NTAPI IPAddInterface( ULONG Unknown0, diff --git a/reactos/drivers/network/tcpip/tcpip/ninfo.c b/reactos/drivers/network/tcpip/tcpip/ninfo.c index af4fb99723e..293eb19a027 100644 --- a/reactos/drivers/network/tcpip/tcpip/ninfo.c +++ b/reactos/drivers/network/tcpip/tcpip/ninfo.c @@ -22,9 +22,9 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI UINT RtCount = CountFIBs(IF); UINT Size = sizeof( IPROUTE_ENTRY ) * RtCount; PFIB_ENTRY RCache = - exAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ), + ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ), RCacheCur = RCache; - PIPROUTE_ENTRY RouteEntries = exAllocatePool( NonPagedPool, Size ), + PIPROUTE_ENTRY RouteEntries = ExAllocatePool( NonPagedPool, Size ), RtCurrent = RouteEntries; UINT i; @@ -32,8 +32,8 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI RtCount, RCache)); if( !RCache || !RouteEntries ) { - if( RCache ) exFreePool( RCache ); - if( RouteEntries ) exFreePool( RouteEntries ); + if( RCache ) ExFreePool( RCache ); + if( RouteEntries ) ExFreePool( RouteEntries ); return TDI_NO_RESOURCES; } @@ -83,8 +83,8 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize ); - exFreePool( RouteEntries ); - exFreePool( RCache ); + ExFreePool( RouteEntries ); + ExFreePool( RCache ); TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status)); @@ -118,7 +118,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID, return TDI_INVALID_PARAMETER; } - IPEntry = exAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY)); + IPEntry = ExAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY)); if (!IPEntry) { TcpipReleaseSpinLock(&EntityListLock, OldIrql); @@ -143,7 +143,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID, InfoCopyOut((PCHAR)IPEntry, sizeof(IPADDR_ENTRY), Buffer, BufferSize); - exFreePool(IPEntry); + ExFreePool(IPEntry); return TDI_SUCCESS; } diff --git a/reactos/lib/drivers/ip/ip.rbuild b/reactos/lib/drivers/ip/ip.rbuild index d6ee690692a..6a3e5500c30 100644 --- a/reactos/lib/drivers/ip/ip.rbuild +++ b/reactos/lib/drivers/ip/ip.rbuild @@ -17,7 +17,6 @@ interface.c ip.c loopback.c - memtrack.c neighbor.c ports.c receive.c diff --git a/reactos/lib/drivers/ip/network/address.c b/reactos/lib/drivers/ip/network/address.c index 974dc7103a8..6ddbfd97e6d 100644 --- a/reactos/lib/drivers/ip/network/address.c +++ b/reactos/lib/drivers/ip/network/address.c @@ -106,7 +106,7 @@ VOID IPAddressFree( * Nothing */ { - exFreePool(Object); + ExFreePoolWithTag(Object, IP_ADDRESS_TAG); } diff --git a/reactos/lib/drivers/ip/network/ip.c b/reactos/lib/drivers/ip/network/ip.c index 9709ce4cee6..2d3621ba60f 100644 --- a/reactos/lib/drivers/ip/network/ip.c +++ b/reactos/lib/drivers/ip/network/ip.c @@ -39,7 +39,7 @@ VOID FreeIF( * Object = Pointer to an interface structure */ { - exFreePool(Object); + ExFreePoolWithTag(Object, IP_INTERFACE_TAG); } PIP_PACKET IPInitializePacket( @@ -56,8 +56,6 @@ PIP_PACKET IPInitializePacket( /* FIXME: Is this needed? */ RtlZeroMemory(IPPacket, sizeof(IP_PACKET)); - INIT_TAG(IPPacket, 'TKPI'); - IPPacket->Free = DontFreePacket; IPPacket->Type = Type; @@ -139,14 +137,13 @@ PIP_INTERFACE IPCreateInterface( } #endif - IF = exAllocatePool(NonPagedPool, sizeof(IP_INTERFACE)); + IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(IP_INTERFACE), + IP_INTERFACE_TAG); if (!IF) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } - INIT_TAG(IF, 'ECAF'); - RtlZeroMemory(IF, sizeof(IP_INTERFACE)); IF->Free = FreeIF; @@ -165,10 +162,11 @@ PIP_INTERFACE IPCreateInterface( TcpipInitializeSpinLock(&IF->Lock); - IF->TCPContext = exAllocatePool - ( NonPagedPool, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in ) ); + IF->TCPContext = ExAllocatePoolWithTag + ( NonPagedPool, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in ), + OSKITTCP_CONTEXT_TAG ); if (!IF->TCPContext) { - exFreePool(IF); + ExFreePoolWithTag(IF, IP_INTERFACE_TAG); return NULL; } @@ -194,8 +192,8 @@ VOID IPDestroyInterface( RemoveTDIInterfaceEntity( IF ); #endif - exFreePool(IF->TCPContext); - exFreePool(IF); + ExFreePoolWithTag(IF->TCPContext, OSKITTCP_CONTEXT_TAG); + ExFreePoolWithTag(IF, IP_INTERFACE_TAG); } VOID IPAddInterfaceRoute( PIP_INTERFACE IF ) { @@ -361,7 +359,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IPDATAGRAM_REASSEMBLY), /* Size of each entry */ - 'RDPI', /* Tag */ + DATAGRAM_REASSEMBLY_TAG, /* Tag */ 0); /* Depth */ ExInitializeNPagedLookasideList( @@ -370,7 +368,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IP_FRAGMENT), /* Size of each entry */ - 'GFPI', /* Tag */ + DATAGRAM_FRAGMENT_TAG, /* Tag */ 0); /* Depth */ ExInitializeNPagedLookasideList( @@ -379,7 +377,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IPDATAGRAM_HOLE), /* Size of each entry */ - 'LHPI', /* Tag */ + DATAGRAM_HOLE_TAG, /* Tag */ 0); /* Depth */ /* Start routing subsystem */ diff --git a/reactos/lib/drivers/ip/network/memtrack.c b/reactos/lib/drivers/ip/network/memtrack.c deleted file mode 100644 index 5e8304f913b..00000000000 --- a/reactos/lib/drivers/ip/network/memtrack.c +++ /dev/null @@ -1,153 +0,0 @@ -#define MEMTRACK_NO_POOL -#include "precomp.h" - - -#if DBG -#define TRACK_TAG 'KCrT' - -static LIST_ENTRY AllocatedObjectsList; -static KSPIN_LOCK AllocatedObjectsLock; -static NPAGED_LOOKASIDE_LIST AllocatedObjectsLookasideList; - -VOID TrackingInit() { - TcpipInitializeSpinLock( &AllocatedObjectsLock ); - InitializeListHead( &AllocatedObjectsList ); - ExInitializeNPagedLookasideList(&AllocatedObjectsLookasideList, - NULL, - NULL, - 0, - sizeof(ALLOCATION_TRACKER), - TRACK_TAG, - 0 ); -} - -VOID ShowTrackedThing( PCHAR What, PALLOCATION_TRACKER Thing, BOOLEAN ForceShow ) { - - if (ForceShow) - { - DbgPrint("[%s] Thing %08x %c%c%c%c (%s:%d)\n", - What, - Thing->Thing, - ((PCHAR)&Thing->Tag)[3], - ((PCHAR)&Thing->Tag)[2], - ((PCHAR)&Thing->Tag)[1], - ((PCHAR)&Thing->Tag)[0], - Thing->FileName, - Thing->LineNo); - } - else - { - TI_DbgPrint(MAX_TRACE, - ("[%s] Thing %08x %c%c%c%c (%s:%d)\n", - What, - Thing->Thing, - ((PCHAR)&Thing->Tag)[3], - ((PCHAR)&Thing->Tag)[2], - ((PCHAR)&Thing->Tag)[1], - ((PCHAR)&Thing->Tag)[0], - Thing->FileName, - Thing->LineNo)); - } -} - -VOID TrackWithTag( ULONG Tag, PVOID Thing, PCHAR FileName, ULONG LineNo ) { - PALLOCATION_TRACKER TrackedThing = - ExAllocateFromNPagedLookasideList( &AllocatedObjectsLookasideList ); - - KIRQL OldIrql; - PLIST_ENTRY Entry; - PALLOCATION_TRACKER ThingInList; - - if (!TrackedThing) return; - - TrackedThing->Tag = Tag; - TrackedThing->Thing = Thing; - TrackedThing->FileName = FileName; - TrackedThing->LineNo = LineNo; - - ShowTrackedThing( "Alloc", TrackedThing, FALSE ); - - TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); - Entry = AllocatedObjectsList.Flink; - while( Entry != &AllocatedObjectsList ) { - ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); - if( ThingInList->Thing == Thing ) { - RemoveEntryList(Entry); - - ShowTrackedThing( "Double Alloc (Item in list)", ThingInList, TRUE ); - ShowTrackedThing( "Double Alloc (Item not in list)", TrackedThing, TRUE ); - - ExFreeToNPagedLookasideList( &AllocatedObjectsLookasideList, - ThingInList ); - - break; - } - Entry = Entry->Flink; - } - - InsertHeadList( &AllocatedObjectsList, &TrackedThing->Entry ); - - TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); -} - -VOID UntrackFL( PCHAR File, ULONG Line, PVOID Thing, ULONG Tag ) { - KIRQL OldIrql; - PLIST_ENTRY Entry; - PALLOCATION_TRACKER ThingInList; - - TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); - Entry = AllocatedObjectsList.Flink; - while( Entry != &AllocatedObjectsList ) { - ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); - if( ThingInList->Thing == Thing ) { - RemoveEntryList(Entry); - - ShowTrackedThing( "Free ", ThingInList, FALSE ); - - if ( ThingInList->Tag != Tag ) { - DbgPrint("UNTRACK: TAG DOES NOT MATCH (%x)\n", Thing); - ShowTrackedThing("Tag Mismatch (Item in list)", ThingInList, TRUE); - ASSERT( FALSE ); - } - - ExFreeToNPagedLookasideList( &AllocatedObjectsLookasideList, - ThingInList ); - - TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); - - return; - } - Entry = Entry->Flink; - } - TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); - - DbgPrint("[Double Free] Thing %08x %c%c%c%c (%s:%d)\n", - Thing, - ((PCHAR)&Tag)[3], - ((PCHAR)&Tag)[2], - ((PCHAR)&Tag)[1], - ((PCHAR)&Tag)[0], - File, - Line); - - ASSERT( FALSE ); -} - -VOID TrackDumpFL( PCHAR File, ULONG Line ) { - KIRQL OldIrql; - PLIST_ENTRY Entry; - PALLOCATION_TRACKER Thing; - - TI_DbgPrint(MAX_TRACE,("Dump: %s:%d\n", File, Line)); - - TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); - Entry = AllocatedObjectsList.Flink; - while( Entry != &AllocatedObjectsList ) { - Thing = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); - ShowTrackedThing( "Dump ", Thing, FALSE ); - Entry = Entry->Flink; - } - TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); -} - -#endif /* DBG */ diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index 375aac19457..ae5e3a5bb19 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -21,7 +21,7 @@ VOID NBCompleteSend( PVOID Context, ASSERT_KM_POINTER(Packet->Complete); Packet->Complete( Packet->Context, Packet->Packet, Status ); TI_DbgPrint(MID_TRACE, ("Completed\n")); - exFreePool( Packet ); + ExFreePoolWithTag( Packet, NEIGHBOR_PACKET_TAG ); TI_DbgPrint(MID_TRACE, ("Freed\n")); } @@ -84,7 +84,7 @@ VOID NBFlushPacketQueue( PNEIGHBOR_CACHE_ENTRY NCE, Packet->Packet, ErrorCode ); - exFreePool( Packet ); + ExFreePoolWithTag( Packet, NEIGHBOR_PACKET_TAG ); } } @@ -128,7 +128,7 @@ VOID NBTimeout(VOID) *PrevNCE = NCE->Next; NBFlushPacketQueue(NCE, NDIS_STATUS_REQUEST_ABORTED); - exFreePool(NCE); + ExFreePoolWithTag(NCE, NCE_TAG); continue; } @@ -179,7 +179,7 @@ VOID NBShutdown(VOID) /* Flush wait queue */ NBFlushPacketQueue( CurNCE, NDIS_STATUS_NOT_ACCEPTED ); - exFreePool(CurNCE); + ExFreePoolWithTag(CurNCE, NCE_TAG); CurNCE = NextNCE; } @@ -241,16 +241,15 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor( "LinkAddress (0x%X) LinkAddressLength (%d) State (0x%X)\n", Interface, Address, LinkAddress, LinkAddressLength, State)); - NCE = exAllocatePool - (NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength); + NCE = ExAllocatePoolWithTag + (NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength, + NCE_TAG); if (NCE == NULL) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } - INIT_TAG(NCE, ' ECN'); - NCE->Interface = Interface; NCE->Address = *Address; NCE->LinkAddressLength = LinkAddressLength; @@ -452,7 +451,8 @@ BOOLEAN NBQueuePacket( (DEBUG_NCACHE, ("Called. NCE (0x%X) NdisPacket (0x%X).\n", NCE, NdisPacket)); - Packet = exAllocatePool( NonPagedPool, sizeof(NEIGHBOR_PACKET) ); + Packet = ExAllocatePoolWithTag( NonPagedPool, sizeof(NEIGHBOR_PACKET), + NEIGHBOR_PACKET_TAG ); if( !Packet ) return FALSE; /* FIXME: Should we limit the number of queued packets? */ @@ -514,7 +514,7 @@ VOID NBRemoveNeighbor( *PrevNCE = CurNCE->Next; NBFlushPacketQueue( CurNCE, NDIS_STATUS_REQUEST_ABORTED ); - exFreePool(CurNCE); + ExFreePoolWithTag(CurNCE, NCE_TAG); break; } diff --git a/reactos/lib/drivers/ip/network/ports.c b/reactos/lib/drivers/ip/network/ports.c index c8b0835c0f1..cd9dbd2f05f 100644 --- a/reactos/lib/drivers/ip/network/ports.c +++ b/reactos/lib/drivers/ip/network/ports.c @@ -17,7 +17,8 @@ NTSTATUS PortsStartup( PPORT_SET PortSet, PortSet->PortsToOversee = PortsToManage; PortSet->ProtoBitBuffer = - exAllocatePool( NonPagedPool, (PortSet->PortsToOversee + 7) / 8 ); + ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8, + PORT_SET_TAG ); if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES; RtlInitializeBitMap( &PortSet->ProtoBitmap, PortSet->ProtoBitBuffer, @@ -28,7 +29,7 @@ NTSTATUS PortsStartup( PPORT_SET PortSet, } VOID PortsShutdown( PPORT_SET PortSet ) { - exFreePool( PortSet->ProtoBitBuffer ); + ExFreePoolWithTag( PortSet->ProtoBitBuffer, PORT_SET_TAG ); } VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) { diff --git a/reactos/lib/drivers/ip/network/receive.c b/reactos/lib/drivers/ip/network/receive.c index 174b647abfd..afdca21600f 100644 --- a/reactos/lib/drivers/ip/network/receive.c +++ b/reactos/lib/drivers/ip/network/receive.c @@ -35,7 +35,7 @@ PIPDATAGRAM_HOLE CreateHoleDescriptor( TI_DbgPrint(DEBUG_IP, ("Called. First (%d) Last (%d).\n", First, Last)); - Hole = exAllocateFromNPagedLookasideList(&IPHoleList); + Hole = ExAllocateFromNPagedLookasideList(&IPHoleList); if (!Hole) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; @@ -76,7 +76,7 @@ VOID FreeIPDR( TI_DbgPrint(DEBUG_IP, ("Freeing hole descriptor at (0x%X).\n", CurrentH)); /* And free the hole descriptor */ - exFreeToNPagedLookasideList(&IPHoleList, CurrentH); + ExFreeToNPagedLookasideList(&IPHoleList, CurrentH); CurrentEntry = NextEntry; } @@ -92,18 +92,18 @@ VOID FreeIPDR( TI_DbgPrint(DEBUG_IP, ("Freeing fragment data at (0x%X).\n", CurrentF->Data)); /* Free the fragment data buffer */ - exFreePool(CurrentF->Data); + ExFreePoolWithTag(CurrentF->Data, FRAGMENT_DATA_TAG); TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF)); /* And free the fragment descriptor */ - exFreeToNPagedLookasideList(&IPFragmentList, CurrentF); + ExFreeToNPagedLookasideList(&IPFragmentList, CurrentF); CurrentEntry = NextEntry; } TI_DbgPrint(DEBUG_IP, ("Freeing IPDR data at (0x%X).\n", IPDR)); - exFreeToNPagedLookasideList(&IPDRList, IPDR); + ExFreeToNPagedLookasideList(&IPDRList, IPDR); } @@ -205,7 +205,7 @@ ReassembleDatagram( RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS)); /* Allocate space for full IP datagram */ - IPPacket->Header = exAllocatePool(NonPagedPool, IPPacket->TotalSize); + IPPacket->Header = ExAllocatePoolWithTag(NonPagedPool, IPPacket->TotalSize, PACKET_BUFFER_TAG); if (!IPPacket->Header) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); (*IPPacket->Free)(IPPacket); @@ -297,7 +297,7 @@ VOID ProcessFragment( TI_DbgPrint(DEBUG_IP, ("Starting new assembly.\n")); /* We don't have a reassembly structure, create one */ - IPDR = exAllocateFromNPagedLookasideList(&IPDRList); + IPDR = ExAllocateFromNPagedLookasideList(&IPDRList); if (!IPDR) /* We don't have the resources to process this packet, discard it */ return; @@ -308,7 +308,7 @@ VOID ProcessFragment( Hole = CreateHoleDescriptor(0, 65536); if (!Hole) { /* We don't have the resources to process this packet, discard it */ - exFreeToNPagedLookasideList(&IPDRList, IPDR); + ExFreeToNPagedLookasideList(&IPDRList, IPDR); return; } AddrInitIPv4(&IPDR->SrcAddr, IPv4Header->SrcAddr); @@ -361,7 +361,7 @@ VOID ProcessFragment( NewHole = CreateHoleDescriptor(Hole->First, FragFirst - 1); if (!NewHole) { /* We don't have the resources to process this packet, discard it */ - exFreeToNPagedLookasideList(&IPHoleList, Hole); + ExFreeToNPagedLookasideList(&IPHoleList, Hole); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -374,7 +374,7 @@ VOID ProcessFragment( NewHole = CreateHoleDescriptor(FragLast + 1, Hole->Last); if (!NewHole) { /* We don't have the resources to process this packet, discard it */ - exFreeToNPagedLookasideList(&IPHoleList, Hole); + ExFreeToNPagedLookasideList(&IPHoleList, Hole); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -383,7 +383,7 @@ VOID ProcessFragment( InsertTailList(&IPDR->HoleListHead, &NewHole->ListEntry); } - exFreeToNPagedLookasideList(&IPHoleList, Hole); + ExFreeToNPagedLookasideList(&IPHoleList, Hole); /* If this is the first fragment, save the IP header */ if (FragFirst == 0) { @@ -397,7 +397,7 @@ VOID ProcessFragment( /* Create a buffer, copy the data into it and put it in the fragment list */ - Fragment = exAllocateFromNPagedLookasideList(&IPFragmentList); + Fragment = ExAllocateFromNPagedLookasideList(&IPFragmentList); if (!Fragment) { /* We don't have the resources to process this packet, discard it */ Cleanup(&IPDR->Lock, OldIrql, IPDR); @@ -407,10 +407,10 @@ VOID ProcessFragment( TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment)); Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize; - Fragment->Data = exAllocatePool(NonPagedPool, Fragment->Size); + Fragment->Data = ExAllocatePoolWithTag(NonPagedPool, Fragment->Size, FRAGMENT_DATA_TAG); if (!Fragment->Data) { /* We don't have the resources to process this packet, discard it */ - exFreeToNPagedLookasideList(&IPFragmentList, Fragment); + ExFreeToNPagedLookasideList(&IPFragmentList, Fragment); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -465,7 +465,7 @@ VOID ProcessFragment( IF->Stats.InBytes += Datagram.TotalSize; /* We're done with this datagram */ - exFreePool(Datagram.Header); + ExFreePoolWithTag(Datagram.Header, PACKET_BUFFER_TAG); TI_DbgPrint(MAX_TRACE, ("Freeing datagram at (0x%X).\n", Datagram)); (*Datagram.Free)(&Datagram); } else diff --git a/reactos/lib/drivers/ip/network/router.c b/reactos/lib/drivers/ip/network/router.c index c2b79a2f968..d5411240549 100644 --- a/reactos/lib/drivers/ip/network/router.c +++ b/reactos/lib/drivers/ip/network/router.c @@ -51,7 +51,7 @@ VOID FreeFIB( * Object = Pointer to an forward information base structure */ { - exFreePool(Object); + ExFreePoolWithTag(Object, FIB_TAG); } @@ -217,14 +217,12 @@ PFIB_ENTRY RouterAddRoute( A2S(Netmask), A2S(&Router->Address))); - FIBE = exAllocatePool(NonPagedPool, sizeof(FIB_ENTRY)); + FIBE = ExAllocatePoolWithTag(NonPagedPool, sizeof(FIB_ENTRY), FIB_TAG); if (!FIBE) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } - INIT_TAG(Router, 'TUOR'); - RtlCopyMemory( &FIBE->NetworkAddress, NetworkAddress, sizeof(FIBE->NetworkAddress) ); RtlCopyMemory( &FIBE->Netmask, Netmask, diff --git a/reactos/lib/drivers/ip/network/routines.c b/reactos/lib/drivers/ip/network/routines.c index 6407ecb25c7..44aa2761076 100644 --- a/reactos/lib/drivers/ip/network/routines.c +++ b/reactos/lib/drivers/ip/network/routines.c @@ -115,11 +115,11 @@ VOID DisplayTCPPacket( if (IPPacket->NdisPacket) { NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length); - Buffer = exAllocatePool(NonPagedPool, Length); + Buffer = ExAllocatePool(NonPagedPool, Length); if (Buffer) { Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, 0, Length); DisplayTCPHeader(Buffer, Length); - exFreePool(Buffer); + ExFreePool(Buffer); } } else { Buffer = IPPacket->Header; diff --git a/reactos/lib/drivers/ip/network/transmit.c b/reactos/lib/drivers/ip/network/transmit.c index 554f5778cbf..b97318223f2 100644 --- a/reactos/lib/drivers/ip/network/transmit.c +++ b/reactos/lib/drivers/ip/network/transmit.c @@ -42,7 +42,7 @@ VOID IPSendComplete { FreeNdisPacket(IFC->NdisPacket); IFC->Complete(IFC->Context, IFC->Datagram, Status); - exFreePool(IFC); + ExFreePoolWithTag(IFC, IFC_TAG); } } else { TI_DbgPrint(MAX_TRACE, ("Calling completion handler.\n")); @@ -50,7 +50,7 @@ VOID IPSendComplete /* There are no more fragments to transmit, so call completion handler */ FreeNdisPacket(IFC->NdisPacket); IFC->Complete(IFC->Context, IFC->Datagram, NdisStatus); - exFreePool(IFC); + ExFreePoolWithTag(IFC, IFC_TAG); } } @@ -178,7 +178,7 @@ NTSTATUS SendFragments( TI_DbgPrint(MAX_TRACE, ("Fragment buffer is %d bytes\n", BufferSize)); - IFC = exAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT)); + IFC = ExAllocatePoolWithTag(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT), IFC_TAG); if (IFC == NULL) return STATUS_INSUFFICIENT_RESOURCES; @@ -187,7 +187,7 @@ NTSTATUS SendFragments( ( &IFC->NdisPacket, NULL, BufferSize ); if( !NT_SUCCESS(NdisStatus) ) { - exFreePool( IFC ); + ExFreePoolWithTag( IFC, IFC_TAG ); return NdisStatus; } @@ -215,14 +215,14 @@ NTSTATUS SendFragments( if (!PrepareNextFragment(IFC)) { FreeNdisPacket(IFC->NdisPacket); - exFreePool(IFC); + ExFreePoolWithTag(IFC, IFC_TAG); return NDIS_STATUS_FAILURE; } if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC)))) { FreeNdisPacket(IFC->NdisPacket); - exFreePool(IFC); + ExFreePoolWithTag(IFC, IFC_TAG); } return NdisStatus; diff --git a/reactos/lib/drivers/ip/transport/datagram/datagram.c b/reactos/lib/drivers/ip/transport/datagram/datagram.c index fafea75f84a..14562e4ddbf 100644 --- a/reactos/lib/drivers/ip/transport/datagram/datagram.c +++ b/reactos/lib/drivers/ip/transport/datagram/datagram.c @@ -35,7 +35,7 @@ VOID DGRemoveIRP( if (ReceiveRequest->Irp == Irp) { RemoveEntryList(&ReceiveRequest->ListEntry); - exFreePool(ReceiveRequest); + ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); break; } } @@ -197,7 +197,7 @@ VOID DGReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count) { (PDATAGRAM_RECEIVE_REQUEST)Context; TI_DbgPrint(MAX_TRACE,("Called (%08x:%08x)\n", Status, Count)); ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status, Count ); - exFreePool( ReceiveRequest ); + ExFreePoolWithTag( ReceiveRequest, DATAGRAM_RECV_TAG ); TI_DbgPrint(MAX_TRACE,("Done\n")); } @@ -236,7 +236,8 @@ NTSTATUS DGReceiveDatagram( KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); - ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST)); + ReceiveRequest = ExAllocatePoolWithTag(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST), + DATAGRAM_RECV_TAG); if (ReceiveRequest) { /* Initialize a receive request */ @@ -250,7 +251,7 @@ NTSTATUS DGReceiveDatagram( &ReceiveRequest->RemotePort); if (!NT_SUCCESS(Status)) { - exFreePool(ReceiveRequest); + ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; } diff --git a/reactos/lib/drivers/ip/transport/tcp/accept.c b/reactos/lib/drivers/ip/transport/tcp/accept.c index b99c03b203c..0bdefb32ec0 100644 --- a/reactos/lib/drivers/ip/transport/tcp/accept.c +++ b/reactos/lib/drivers/ip/transport/tcp/accept.c @@ -118,7 +118,7 @@ VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, if( Bucket->AssociatedEndpoint == Connection ) { RemoveEntryList( &Bucket->Entry ); - exFreePool( Bucket ); + ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG ); break; } @@ -148,7 +148,8 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request, KeReleaseSpinLock(&Listener->Lock, OldIrql); if( Status == STATUS_PENDING ) { - Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); + Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), + TDI_BUCKET_TAG ); if( Bucket ) { Bucket->AssociatedEndpoint = Connection; diff --git a/reactos/lib/drivers/ip/transport/tcp/event.c b/reactos/lib/drivers/ip/transport/tcp/event.c index 6d062dceb8b..f3d5a145597 100644 --- a/reactos/lib/drivers/ip/transport/tcp/event.c +++ b/reactos/lib/drivers/ip/transport/tcp/event.c @@ -126,8 +126,6 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { #define SIGNATURE_LARGE 'LLLL' #define SIGNATURE_SMALL 'SSSS' #define SIGNATURE_OTHER 'OOOO' -#define TCP_TAG ' PCT' - static NPAGED_LOOKASIDE_LIST LargeLookasideList; static NPAGED_LOOKASIDE_LIST SmallLookasideList; @@ -139,14 +137,14 @@ TCPMemStartup( void ) NULL, 0, LARGE_SIZE + sizeof( ULONG ), - TCP_TAG, + OSK_LARGE_TAG, 0 ); ExInitializeNPagedLookasideList( &SmallLookasideList, NULL, NULL, 0, SMALL_SIZE + sizeof( ULONG ), - TCP_TAG, + OSK_SMALL_TAG, 0 ); return STATUS_SUCCESS; @@ -216,13 +214,13 @@ void *TCPMalloc( void *ClientData, v = ExAllocateFromNPagedLookasideList( &LargeLookasideList ); Signature = SIGNATURE_LARGE; } else { - v = ExAllocatePool( NonPagedPool, Bytes + sizeof(ULONG) ); + v = ExAllocatePoolWithTag( NonPagedPool, Bytes + sizeof(ULONG), + OSK_OTHER_TAG ); Signature = SIGNATURE_OTHER; } if( v ) { *((ULONG *) v) = Signature; v = (void *)((char *) v + sizeof(ULONG)); - TrackWithTag( FOURCC('f','b','s','d'), v, (PCHAR)File, Line ); } return v; @@ -232,7 +230,6 @@ void TCPFree( void *ClientData, void *data, OSK_PCHAR File, OSK_UINT Line ) { ULONG Signature; - UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') ); data = (void *)((char *) data - sizeof(ULONG)); Signature = *((ULONG *) data); if ( SIGNATURE_SMALL == Signature ) { @@ -240,7 +237,7 @@ void TCPFree( void *ClientData, } else if ( SIGNATURE_LARGE == Signature ) { ExFreeToNPagedLookasideList( &LargeLookasideList, data ); } else if ( SIGNATURE_OTHER == Signature ) { - ExFreePool( data ); + ExFreePoolWithTag( data, OSK_OTHER_TAG ); } else { ASSERT( FALSE ); } diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 6f9f38c87a0..f0e104efe6d 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -33,7 +33,7 @@ ProcessCompletions(PCONNECTION_ENDPOINT Connection) Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information); - exFreePool(Bucket); + ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG); } if (!Connection->SocketContext) @@ -315,7 +315,8 @@ VOID DrainSignals(VOID) { PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { PCONNECTION_ENDPOINT Connection = - exAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT)); + ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT), + CONN_ENDPT_TAG); if (!Connection) return Connection; @@ -351,7 +352,7 @@ VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) { RemoveEntryList(&Connection->ListEntry); TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - exFreePool( Connection ); + ExFreePoolWithTag( Connection, CONN_ENDPT_TAG ); } NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, @@ -667,7 +668,7 @@ NTSTATUS TCPConnect if (Status == STATUS_PENDING) { - Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); + Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); if( !Bucket ) { return STATUS_NO_MEMORY; @@ -776,7 +777,7 @@ NTSTATUS TCPReceiveData /* Keep this request around ... there was no data yet */ if( Status == STATUS_PENDING ) { /* Freed in TCPSocketState */ - Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); + Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); if( !Bucket ) { TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); return STATUS_NO_MEMORY; @@ -835,7 +836,7 @@ NTSTATUS TCPSendData /* Keep this request around ... there was no data yet */ if( Status == STATUS_PENDING ) { /* Freed in TCPSocketState */ - Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); + Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); if( !Bucket ) { TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); return STATUS_NO_MEMORY; @@ -927,7 +928,7 @@ VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { if( Bucket->Request.RequestContext == Irp ) { RemoveEntryList( &Bucket->Entry ); - exFreePool( Bucket ); + ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG ); break; } } diff --git a/reactos/lib/drivers/oskittcp/include/memtrack.h b/reactos/lib/drivers/oskittcp/include/memtrack.h deleted file mode 100644 index 802ed74aed1..00000000000 --- a/reactos/lib/drivers/oskittcp/include/memtrack.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef MEMTRACK_H -#define MEMTRACK_H - -#ifndef FOURCC -#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) -#endif - -#define FBSD_MALLOC FOURCC('d','s','b','f') -#define EXALLOC_TAG FOURCC('E','x','A','l') - -#if DBG -#define MTMARK() TrackDumpFL(__FILE__, __LINE__) -#define NdisAllocateBuffer(x,y,z,a,b) { \ - NdisAllocateBuffer(x,y,z,a,b); \ - if( *x == NDIS_STATUS_SUCCESS ) { \ - Track(NDIS_BUFFER_TAG, *y); \ - } \ -} -#define NdisAllocatePacket(x,y,z) { \ - NdisAllocatePacket(x,y,z); \ - if( *x == NDIS_STATUS_SUCCESS ) { \ - Track(NDIS_PACKET_TAG, *y); \ - } \ -} -#define FreeNdisPacket(x) { TI_DbgPrint(MID_TRACE,("Deleting Packet %x\n", x)); FreeNdisPacketX(x); } -#define NdisFreePacket(x) { Untrack(x); NdisFreePacket(x); } -#define NdisFreeBuffer(x) { Untrack(x); NdisFreeBuffer(x); } -#define exAllocatePool(x,y) ExAllocatePoolX(x,y,__FILE__,__LINE__) -#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolX(x,y,__FILE__,__LINE__) -#define exFreePool(x) ExFreePoolX(x,__FILE__,__LINE__) - -extern LIST_ENTRY AllocatedObjectsHead; -extern KSPIN_LOCK AllocatedObjectsLock; - -typedef struct _ALLOCATION_TRACKER { - LIST_ENTRY Entry; - DWORD Tag; - PVOID Thing; - PCHAR FileName; - DWORD LineNo; -} ALLOCATION_TRACKER, *PALLOCATION_TRACKER; - -VOID TrackingInit(); -VOID TrackWithTag( DWORD Tag, PVOID Thing, PCHAR File, DWORD Line ); -#define Track(Tag,Thing) TrackWithTag(Tag,Thing,__FILE__,__LINE__) -VOID UntrackFL( PCHAR File, DWORD Line, PVOID Thing ); -#define Untrack(Thing) UntrackFL(__FILE__,__LINE__,Thing) -VOID TrackDumpFL( PCHAR File, DWORD Line ); -#define TrackDump() TrackDumpFL(__FILE__,__LINE__) -VOID TrackTag( DWORD Tag ); - -static __inline PVOID ExAllocatePoolX( POOL_TYPE type, SIZE_T size, PCHAR File, ULONG Line ) { - PVOID Out = ExAllocatePool( type, size ); - if( Out ) TrackWithTag( EXALLOC_TAG, Out, File, Line ); - return Out; -} -static __inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) { - UntrackFL(File, Line, Data); - ExFreePool(Data); -} - -#define MEMTRACK_MAX_TAGS_TO_TRACK 64 -#else -#define MTMARK() -#define Track(x,y) -#define TrackingInit() -#define TrackDump() -#define Untrack(x) -#define TrackTag(x) -#define FreeNdisPacket FreeNdisPacketX -#define exFreePool(x) ExFreePool(x) -#define exAllocatePool(x,y) ExAllocatePool(x,y) -#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolWithTag(x,y,z) -#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideList(x) -#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideList(x,y) -#define TrackWithTag(w,x,y,z) -#define UntrackFL(w,x,y,z) -#endif - -#endif/*MEMMTRAC_H*/ From e016a230afb20abc112a79d29a0deae875d744fd Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 22 Nov 2009 02:32:47 +0000 Subject: [PATCH 087/140] - Fix a race condition that occurs when an IRP gets cancelled after it is inserted into the completion queue but before it is completed svn path=/trunk/; revision=44267 --- .../drivers/network/tcpip/include/datagram.h | 2 +- reactos/drivers/network/tcpip/include/tcp.h | 6 ++--- .../drivers/network/tcpip/tcpip/dispatch.c | 27 ++++++++++--------- .../drivers/ip/transport/datagram/datagram.c | 6 ++++- reactos/lib/drivers/ip/transport/tcp/accept.c | 6 ++++- reactos/lib/drivers/ip/transport/tcp/tcp.c | 6 ++++- 6 files changed, 33 insertions(+), 20 deletions(-) diff --git a/reactos/drivers/network/tcpip/include/datagram.h b/reactos/drivers/network/tcpip/include/datagram.h index 760ba3a85be..f05107a7de1 100644 --- a/reactos/drivers/network/tcpip/include/datagram.h +++ b/reactos/drivers/network/tcpip/include/datagram.h @@ -21,7 +21,7 @@ NTSTATUS DGReceiveDatagram( PVOID Context, PIRP Irp); -VOID DGRemoveIRP( +BOOLEAN DGRemoveIRP( PADDRESS_FILE AddrFile, PIRP Irp); diff --git a/reactos/drivers/network/tcpip/include/tcp.h b/reactos/drivers/network/tcpip/include/tcp.h index b18fecdd295..a02c03b796e 100644 --- a/reactos/drivers/network/tcpip/include/tcp.h +++ b/reactos/drivers/network/tcpip/include/tcp.h @@ -96,8 +96,8 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection, PTDI_REQUEST_KERNEL Request ); NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ); -VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, - PCONNECTION_ENDPOINT Connection ); +BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, + PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPAccept ( PTDI_REQUEST Request, PCONNECTION_ENDPOINT Listener, @@ -179,6 +179,6 @@ NTSTATUS TCPStartup( NTSTATUS TCPShutdown( VOID); -VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp ); +BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp ); #endif /* __TCP_H */ diff --git a/reactos/drivers/network/tcpip/tcpip/dispatch.c b/reactos/drivers/network/tcpip/tcpip/dispatch.c index c78aeceb89f..c6f2d2a55e9 100644 --- a/reactos/drivers/network/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/network/tcpip/tcpip/dispatch.c @@ -133,6 +133,7 @@ VOID NTAPI DispCancelRequest( PTRANSPORT_CONTEXT TranContext; PFILE_OBJECT FileObject; UCHAR MinorFunction; + BOOLEAN DequeuedIrp = TRUE; IoReleaseCancelSpinLock(Irp->CancelIrql); @@ -157,7 +158,7 @@ VOID NTAPI DispCancelRequest( switch(MinorFunction) { case TDI_SEND: case TDI_RECEIVE: - TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp ); + DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp ); break; case TDI_SEND_DATAGRAM: @@ -166,7 +167,7 @@ VOID NTAPI DispCancelRequest( break; } - DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); + DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); break; case TDI_RECEIVE_DATAGRAM: @@ -175,19 +176,21 @@ VOID NTAPI DispCancelRequest( break; } - DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); + DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); break; case TDI_CONNECT: - TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp); + DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp); break; default: TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction)); + ASSERT(FALSE); break; } - IRPFinish(Irp, STATUS_CANCELLED); + if (DequeuedIrp) + IRPFinish(Irp, STATUS_CANCELLED); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } @@ -207,7 +210,6 @@ VOID NTAPI DispCancelListenRequest( PTRANSPORT_CONTEXT TranContext; PFILE_OBJECT FileObject; PCONNECTION_ENDPOINT Connection; - /*NTSTATUS Status = STATUS_SUCCESS;*/ IoReleaseCancelSpinLock(Irp->CancelIrql); @@ -228,13 +230,12 @@ VOID NTAPI DispCancelListenRequest( /* Try canceling the request */ Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; - TCPRemoveIRP(Connection, Irp); - - TCPAbortListenForSocket(Connection->AddressFile->Listener, - Connection); - - Irp->IoStatus.Information = 0; - IRPFinish(Irp, STATUS_CANCELLED); + if (TCPAbortListenForSocket(Connection->AddressFile->Listener, + Connection)) + { + Irp->IoStatus.Information = 0; + IRPFinish(Irp, STATUS_CANCELLED); + } TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } diff --git a/reactos/lib/drivers/ip/transport/datagram/datagram.c b/reactos/lib/drivers/ip/transport/datagram/datagram.c index 14562e4ddbf..3c92aa26002 100644 --- a/reactos/lib/drivers/ip/transport/datagram/datagram.c +++ b/reactos/lib/drivers/ip/transport/datagram/datagram.c @@ -10,13 +10,14 @@ #include "precomp.h" -VOID DGRemoveIRP( +BOOLEAN DGRemoveIRP( PADDRESS_FILE AddrFile, PIRP Irp) { PLIST_ENTRY ListEntry; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; KIRQL OldIrql; + BOOLEAN Found = FALSE; TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n", Irp, AddrFile)); @@ -36,6 +37,7 @@ VOID DGRemoveIRP( { RemoveEntryList(&ReceiveRequest->ListEntry); ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); + Found = TRUE; break; } } @@ -43,6 +45,8 @@ VOID DGRemoveIRP( KeReleaseSpinLock(&AddrFile->Lock, OldIrql); TI_DbgPrint(MAX_TRACE, ("Done.\n")); + + return Found; } VOID DGDeliverData( diff --git a/reactos/lib/drivers/ip/transport/tcp/accept.c b/reactos/lib/drivers/ip/transport/tcp/accept.c index 0bdefb32ec0..059d109af73 100644 --- a/reactos/lib/drivers/ip/transport/tcp/accept.c +++ b/reactos/lib/drivers/ip/transport/tcp/accept.c @@ -104,11 +104,12 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { return Status; } -VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, +BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection ) { PLIST_ENTRY ListEntry; PTDI_BUCKET Bucket; KIRQL OldIrql; + BOOLEAN Found = FALSE; KeAcquireSpinLock(&Listener->Lock, &OldIrql); @@ -119,6 +120,7 @@ VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, if( Bucket->AssociatedEndpoint == Connection ) { RemoveEntryList( &Bucket->Entry ); ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG ); + Found = TRUE; break; } @@ -126,6 +128,8 @@ VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, } KeReleaseSpinLock(&Listener->Lock, OldIrql); + + return Found; } NTSTATUS TCPAccept ( PTDI_REQUEST Request, diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index f0e104efe6d..8c051677353 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -904,12 +904,13 @@ NTSTATUS TCPGetSockAddress return Status; } -VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { +BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { PLIST_ENTRY Entry; PLIST_ENTRY ListHead[4]; KIRQL OldIrql; PTDI_BUCKET Bucket; UINT i = 0; + BOOLEAN Found = FALSE; ListHead[0] = &Endpoint->SendRequest; ListHead[1] = &Endpoint->ReceiveRequest; @@ -929,12 +930,15 @@ VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { { RemoveEntryList( &Bucket->Entry ); ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG ); + Found = TRUE; break; } } } TcpipReleaseSpinLock( &Endpoint->Lock, OldIrql ); + + return Found; } /* EOF */ From 70dc807bf2d1c37ee595e58e3fd8735a1fbefcb0 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Tue, 24 Nov 2009 20:36:53 +0000 Subject: [PATCH 088/140] [rosautotest]: Find the last underscore instead of the first one when building a module name, hurray for twain_32_winetest and ws2_32_winetest See issue #4929 for more details. svn path=/trunk/; revision=44282 --- rostests/rosautotest/CWineTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rostests/rosautotest/CWineTest.cpp b/rostests/rosautotest/CWineTest.cpp index 471e6ab7e98..976343b8296 100644 --- a/rostests/rosautotest/CWineTest.cpp +++ b/rostests/rosautotest/CWineTest.cpp @@ -227,7 +227,7 @@ CWineTest::GetNextTestInfo() TestInfo->CommandLine += AsciiToUnicode(m_CurrentTest); /* Store the Module name */ - UnderscorePosition = m_CurrentFile.find('_'); + UnderscorePosition = m_CurrentFile.find_last_of('_'); if(UnderscorePosition == m_CurrentFile.npos) { From 1d110c440a3ed74489f2e646225a18e0abe66212 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 24 Nov 2009 22:39:25 +0000 Subject: [PATCH 089/140] [IDL] - Make our IDLs files to not specify a [range] tag for string datatypes, and 0,256 range for an unsigned type. Fixes compiling with newer WIDL and (probably) MIDL. svn path=/trunk/; revision=44283 --- reactos/include/reactos/idl/eventlogrpc.idl | 6 +- reactos/include/reactos/idl/pnp.idl | 136 +++++++++--------- reactos/include/reactos/idl/svcctl.idl | 150 ++++++++++---------- 3 files changed, 146 insertions(+), 146 deletions(-) diff --git a/reactos/include/reactos/idl/eventlogrpc.idl b/reactos/include/reactos/idl/eventlogrpc.idl index ae78f89a81e..e5cdbd3459d 100644 --- a/reactos/include/reactos/idl/eventlogrpc.idl +++ b/reactos/include/reactos/idl/eventlogrpc.idl @@ -115,7 +115,7 @@ interface eventlog [in] USHORT EventType, [in] USHORT EventCategory, [in] DWORD EventID, - [in, range(0, 256)] USHORT NumStrings, + [in/*, max_is(256)*/] USHORT NumStrings, [in, range(0, 61440)] DWORD DataSize, [in] PRPC_UNICODE_STRING ComputerName, [in, unique] PRPC_SID UserSID, @@ -178,7 +178,7 @@ interface eventlog [in] USHORT EventType, [in] USHORT EventCategory, [in] DWORD EventID, - [in, range(0, 256)] USHORT NumStrings, + [in/*, max_is(256)*/] USHORT NumStrings, [in, range(0, 61440)] DWORD DataSize, [in] PRPC_STRING ComputerName, [in, unique] PRPC_SID UserSID, @@ -229,7 +229,7 @@ interface eventlog [in] USHORT EventCategory, [in] ULONG EventID, [in] PRPC_UNICODE_STRING SourceName, - [in, range(0, 256)] USHORT NumStrings, + [in/*, max_is(256)*/] USHORT NumStrings, [in, range(0, 61440)] DWORD DataSize, [in] PRPC_UNICODE_STRING ComputerName, [in, unique] PRPC_SID UserSID, diff --git a/reactos/include/reactos/idl/pnp.idl b/reactos/include/reactos/idl/pnp.idl index a668de5afcb..cf3fc891253 100644 --- a/reactos/include/reactos/idl/pnp.idl +++ b/reactos/include/reactos/idl/pnp.idl @@ -18,10 +18,14 @@ cpp_quote("#ifndef _CFGMGR32_H_") typedef unsigned long RESOURCEID; cpp_quote("#endif") typedef unsigned long DEVPROPTYPE; -typedef [range(0, PNP_MAX_PROP_SIZE)] unsigned long PNP_PROP_SIZE, *PPNP_PROP_SIZE; -typedef [range(0, PNP_MAX_PROP_COUNT)] unsigned long PNP_PROP_COUNT, *PPNP_PROP_COUNT; -typedef [range(0, PNP_MAX_STRING_LEN)] unsigned long PNP_RPC_STRING_LEN, *PPNP_RPC_STRING_LEN; -typedef [range(0, PNP_MAX_BUFFER_SIZE)] unsigned long PNP_RPC_BUFFER_SIZE, *PPNP_RPC_BUFFER_SIZE; +typedef [range(0, PNP_MAX_PROP_SIZE)] unsigned long PNP_PROP_SIZE; +typedef [range(0, PNP_MAX_PROP_COUNT)] unsigned long PNP_PROP_COUNT; +typedef [range(0, PNP_MAX_STRING_LEN)] unsigned long PNP_RPC_STRING_LEN; +typedef [range(0, PNP_MAX_BUFFER_SIZE)] unsigned long PNP_RPC_BUFFER_SIZE; +typedef PNP_PROP_SIZE *PPNP_PROP_SIZE; +typedef PNP_PROP_COUNT *PPNP_PROP_COUNT; +typedef PNP_RPC_STRING_LEN *PPNP_RPC_STRING_LEN; +typedef PNP_RPC_BUFFER_SIZE *PPNP_RPC_BUFFER_SIZE; cpp_quote("#ifndef _CFG_INCLUDED_") @@ -286,7 +290,7 @@ interface pnp /* Function 6 */ DWORD PNP_ValidateDeviceInstance( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulFlags); /* Function 7 */ @@ -302,7 +306,7 @@ interface pnp DWORD PNP_GetRelatedDeviceInstance( [in] handle_t hBinding, [in] DWORD ulRelationship, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [out, string, size_is(*pulLength)] LPWSTR pRelatedDeviceId, [in, out] PNP_RPC_STRING_LEN *pulLength, [in] DWORD ulFlags); @@ -322,7 +326,7 @@ interface pnp /* Function 10 */ DWORD PNP_GetDeviceList( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_STRING_LEN)] LPWSTR pszFilter, + [in, string, unique] LPWSTR pszFilter, [out, size_is(*pulLength), length_is(*pulLength)] LPWSTR Buffer, [in, out] PNP_RPC_STRING_LEN *pulLength, [in] DWORD ulFlags); @@ -330,21 +334,21 @@ interface pnp /* Function 11 */ DWORD PNP_GetDeviceListSize( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_STRING_LEN)] LPWSTR pszFilter, + [in, string, unique] LPWSTR pszFilter, [out] PNP_RPC_BUFFER_SIZE *pulLen, [in] DWORD ulFlags); /* Function 12 */ DWORD PNP_GetDepth( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, + [in, string, ref] LPWSTR pszDeviceID, [out] DWORD *pulDepth, [in] DWORD ulFlags); /* Function 13 */ DWORD PNP_GetDeviceRegProp( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulProperty, [in, out] DWORD *pulRegDataType, [out, size_is(*pulTransferLen), length_is(*pulTransferLen)] BYTE *Buffer, @@ -355,7 +359,7 @@ interface pnp /* Function 14 */ DWORD PNP_SetDeviceRegProp( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceId, + [in, string, ref] LPWSTR pDeviceId, [in] DWORD ulProperty, [in] DWORD ulDataType, [in, size_is(ulLength)] BYTE *Buffer, @@ -365,23 +369,23 @@ interface pnp /* Function 15 */ DWORD PNP_GetClassInstance( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceId, + [in, string, ref] LPWSTR pDeviceId, [out, string, size_is(ulLength)] LPWSTR pszClassInstance, [in] PNP_RPC_STRING_LEN ulLength); /* Function 16 */ DWORD PNP_CreateKey( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_CM_PATH)] LPWSTR pszSubKey, + [in, string, ref] LPWSTR pszSubKey, [in] DWORD samDesired, [in] DWORD ulFlags); /* Function 17 */ DWORD PNP_DeleteRegistryKey( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, - [in, string, ref, range(0, PNP_MAX_CM_PATH)] LPWSTR pszParentKey, - [in, string, ref, range(0, PNP_MAX_CM_PATH)] LPWSTR pszChildKey, + [in, string, ref] LPWSTR pszDeviceID, + [in, string, ref] LPWSTR pszParentKey, + [in, string, ref] LPWSTR pszChildKey, [in] DWORD ulFlags); /* Function 18 */ @@ -393,7 +397,7 @@ interface pnp /* Function 19 */ DWORD PNP_GetClassName( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_GUID_STRING_LEN)] LPWSTR pszClassGuid, + [in, string, ref] LPWSTR pszClassGuid, [out, string, size_is(*pulLength)] LPWSTR Buffer, [in, out] PNP_RPC_STRING_LEN *pulLength, [in] DWORD ulFlags); @@ -401,13 +405,13 @@ interface pnp /* Function 20 */ DWORD PNP_DeleteClassKey( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_GUID_STRING_LEN)] LPWSTR pszClassGuid, + [in, string, ref] LPWSTR pszClassGuid, [in] DWORD ulFlags); /* Function 21 */ DWORD PNP_GetInterfaceDeviceAlias( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVINTERFACE_LEN)] LPWSTR pszInterfaceDevice, + [in, string, ref] LPWSTR pszInterfaceDevice, [in] GUID *AliasInterfaceGuid, [out, string, size_is(*pulTransferLen)] LPWSTR pszAliasInterfaceDevice, [in, out] PNP_RPC_STRING_LEN *pulLength, @@ -418,7 +422,7 @@ interface pnp DWORD PNP_GetInterfaceDeviceList( [in] handle_t hBinding, [in] GUID *InterfaceGuid, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, + [in, string, unique] LPWSTR pszDeviceID, [out, size_is(*pulLength), length_is(*pulLength)] BYTE *Buffer, [in, out] PNP_RPC_BUFFER_SIZE *pulLength, [in] DWORD ulFlags); @@ -428,15 +432,15 @@ interface pnp [in] handle_t hBinding, [out] PNP_RPC_BUFFER_SIZE *pulLen, [in] GUID *InterfaceGuid, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, + [in, string, unique] LPWSTR pszDeviceID, [in] DWORD ulFlags); /* Function 24 */ DWORD PNP_RegisterDeviceClassAssociation( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, + [in, string, unique] LPWSTR pszDeviceID, [in] GUID *InterfaceGuid, - [in, string, unique, range(0, PNP_MAX_STRING_LEN)] LPWSTR pszReference, + [in, string, unique] LPWSTR pszReference, [out, string, size_is(*pulTransferLen)] LPWSTR pszSymLink, [in, out] PNP_RPC_STRING_LEN *pulLength, [in, out] PNP_RPC_STRING_LEN *pulTransferLen, @@ -445,13 +449,13 @@ interface pnp /* Function 25 */ DWORD PNP_UnregisterDeviceClassAssociation( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_DEVINTERFACE_LEN)] LPWSTR pszInterfaceDevice, + [in, string, unique] LPWSTR pszInterfaceDevice, [in] DWORD ulFlags); /* Function 26 */ DWORD PNP_GetClassRegProp( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_GUID_STRING_LEN)] LPWSTR pszClassGuid, + [in, string, ref] LPWSTR pszClassGuid, [in] DWORD ulProperty, [in, out] DWORD *pulRegDataType, [out, size_is(*pulTransferLen), length_is(*pulTransferLen)] BYTE *Buffer, @@ -462,7 +466,7 @@ interface pnp /* Function 27 */ DWORD PNP_SetClassRegProp( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_GUID_STRING_LEN)] LPWSTR *pszClassGuid, + [in, string, ref] LPWSTR *pszClassGuid, [in] DWORD ulProperty, [in] DWORD ulDataType, [in, size_is(ulLength)] BYTE *Buffer, @@ -473,7 +477,7 @@ interface pnp DWORD PNP_CreateDevInst( [in] handle_t hBinding, [in, out, string, size_is(ulLength)] LPWSTR pszDeviceID, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszParentDeviceID, + [in, string, ref] LPWSTR pszParentDeviceID, [in] PNP_RPC_STRING_LEN ulLength, [in] DWORD ulFlags); @@ -482,13 +486,13 @@ interface pnp [in] handle_t hBinding, [in] DWORD ulMajorAction, [in] DWORD ulMinorAction, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceInstance1, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceInstance2); + [in, string, unique] LPWSTR pszDeviceInstance1, + [in, string, unique] LPWSTR pszDeviceInstance2); /* Function 30 */ DWORD PNP_GetDeviceStatus( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, unique] LPWSTR pDeviceID, [out] DWORD *pulStatus, [out] DWORD *pulProblem, [in] DWORD ulFlags); @@ -496,56 +500,53 @@ interface pnp /* Function 31 */ DWORD PNP_SetDeviceProblem( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, unique] LPWSTR pDeviceID, [in] DWORD ulProblem, [in] DWORD ulFlags); /* Function 32 */ DWORD PNP_DisableDevInst( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, unique] LPWSTR pDeviceID, [in, out, unique] PPNP_VETO_TYPE pVetoType, - [in, out, string, unique, size_is(ulNameLength), range(0, PNP_MAX_STRING_LEN)] LPWSTR pszVetoName, - /* FIXME: should be [in, out, string, unique, max_is(ulNameLength), range(0, PNP_MAX_STRING_LEN)] LPWSTR pszVetoName, */ + [in, out, string, unique, size_is(ulNameLength)] LPWSTR pszVetoName, [in] DWORD ulNameLength, [in] DWORD ulFlags); /* Function 33 */ DWORD PNP_UninstallDevInst( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, unique] LPWSTR pDeviceID, [in] DWORD ulFlags); /* Function 34 */ DWORD PNP_AddID( [in] handle_t hBinding, - [in, string, unique, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszID, + [in, string, unique] LPWSTR pszDeviceID, + [in, string, ref] LPWSTR pszID, [in] DWORD ulFlags); /* Function 35 */ DWORD PNP_RegisterDriver( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, + [in, string, ref] LPWSTR pszDeviceID, [in] DWORD ulFlags); /* Function 36 */ DWORD PNP_QueryRemove( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, + [in, string, ref] LPWSTR pszDeviceID, [in, out, unique] PPNP_VETO_TYPE pVetoType, - [in, out, string, unique, size_is(ulNameLength), range(0, PNP_MAX_STRING_LEN)] LPWSTR pszVetoName, - /* FIXME: should be [in, out, string, unique, max_is(ulNameLength), range(0, PNP_MAX_STRING_LEN)] LPWSTR pszVetoName, */ + [in, out, string, unique, size_is(ulNameLength)] LPWSTR pszVetoName, [in] DWORD ulNameLength, [in] DWORD ulFlags); /* Function 37 */ DWORD PNP_RequestDeviceEject( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pszDeviceID, + [in, string, ref] LPWSTR pszDeviceID, [in, out, unique] PPNP_VETO_TYPE pVetoType, - [in, out, string, unique, size_is(ulNameLength), range(0, PNP_MAX_STRING_LEN)] LPWSTR pszVetoName, - /* FIXME: should be [in, out, string, unique, max_is(ulNameLength), range(0, PNP_MAX_STRING_LEN)] LPWSTR pszVetoName, */ + [in, out, string, unique, size_is(ulNameLength)] LPWSTR pszVetoName, [in] DWORD ulNameLength, [in] DWORD ulFlags); @@ -564,12 +565,11 @@ interface pnp DWORD PNP_HwProfFlags( [in] handle_t hBinding, [in] DWORD ulAction, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulConfig, [in, out] DWORD *pulValue, [in, out, unique] PPNP_VETO_TYPE pVetoType, - [in, out, string, unique, size_is(ulNameLength), range(0, PNP_MAX_STRING_LEN)] LPWSTR pszVetoName, - /* FIXME: should be [in, out, string, unique, max_is(ulNameLength), range(0, PNP_MAX_STRING_LEN)] LPWSTR pszVetoName, */ + [in, out, string, unique, size_is(ulNameLength)] LPWSTR pszVetoName, [in] DWORD ulNameLength, [in] DWORD ulFlags); @@ -585,7 +585,7 @@ interface pnp /* Function 42 */ DWORD PNP_AddEmptyLogConf( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulPriority, [out] DWORD *pulLogConfTag, [in] DWORD ulFlags); @@ -593,7 +593,7 @@ interface pnp /* Function 43 */ DWORD PNP_FreeLogConf( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfType, [in] DWORD ulLogConfTag, [in] DWORD ulFlags); @@ -601,7 +601,7 @@ interface pnp /* Function 44 */ DWORD PNP_GetFirstLogConf( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfType, [out] DWORD *pulLogConfTag, [in] DWORD ulFlags); @@ -609,7 +609,7 @@ interface pnp /* Function 45 */ DWORD PNP_GetNextLogConf( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfType, [in] DWORD ulCurrentTag, [out] DWORD *pulNextTag, @@ -618,7 +618,7 @@ interface pnp /* Function 46 */ DWORD PNP_GetLogConfPriority( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulType, [in] DWORD ulTag, [out] DWORD *pPriority, @@ -627,7 +627,7 @@ interface pnp /* Function 47 */ DWORD PNP_AddResDes( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfTag, [in] DWORD ulLogConfType, [in] RESOURCEID ResourceID, @@ -639,7 +639,7 @@ interface pnp /* Function 48 */ DWORD PNP_FreeResDes( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfTag, [in] DWORD ulLogConfType, [in] RESOURCEID ResourceID, @@ -651,7 +651,7 @@ interface pnp /* Function 49 */ DWORD PNP_GetNextResDes( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfTag, [in] DWORD ulLogConfType, [in] RESOURCEID ResourceID, @@ -663,7 +663,7 @@ interface pnp /* Function 50 */ DWORD PNP_GetResDesData( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfTag, [in] DWORD ulLogConfType, [in] RESOURCEID ResourceID, @@ -675,7 +675,7 @@ interface pnp /* Function 51 */ DWORD PNP_GetResDesDataSize( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfTag, [in] DWORD ulLogConfType, [in] RESOURCEID ResourceID, @@ -686,7 +686,7 @@ interface pnp /* Function 52 */ DWORD PNP_ModifyResDes( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] DWORD ulLogConfTag, [in] DWORD ulLogConfType, [in] RESOURCEID CurrentResourceID, @@ -699,7 +699,7 @@ interface pnp /* Function 53 */ DWORD PNP_DetectResourceConflict( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] RESOURCEID ResourceID, [in, size_is(ResourceLen)] BYTE *ResourceData, [in] PNP_RPC_BUFFER_SIZE ResourceLen, @@ -709,7 +709,7 @@ interface pnp /* Function 54 */ DWORD PNP_QueryResConfList( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, + [in, string, ref] LPWSTR pDeviceID, [in] RESOURCEID ResourceID, [in, size_is(ResourceLen)] BYTE *ResourceData, [in] PNP_RPC_BUFFER_SIZE ResourceLen, @@ -747,8 +747,8 @@ cpp_quote("#if _WIN32_WINNT >= 0x0501") /* Function 61 */ DWORD PNP_GetCustomDevProp( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_DEVICE_ID_LEN)] LPWSTR pDeviceID, - [in, string, ref, range(0, PNP_MAX_STRING_LEN)] LPWSTR CustomPropName, + [in, string, ref] LPWSTR pDeviceID, + [in, string, ref] LPWSTR CustomPropName, [out] DWORD *pulRegDataType, [out, size_is(*pulLength), length_is(*pulTransferLen)] BYTE *Buffer, [out] PNP_RPC_STRING_LEN *pulTransferLen, @@ -779,9 +779,9 @@ cpp_quote("#if _WIN32_WINNT >= 0x0600") /* Function 65 */ DWORD PNP_GetObjectPropKeys( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_STRING_LEN)] LPWSTR ObjectName, + [in, string, ref] LPWSTR ObjectName, [in] DWORD ObjectType, - [in, string, unique, range(0, PNP_MAX_CULTURE_NAME_LEN)] LPWSTR PropertyCultureName, + [in, string, unique] LPWSTR PropertyCultureName, [in, out] PNP_PROP_COUNT *PropertyCount, [out] PNP_PROP_COUNT *TransferLen, [out, size_is(*PropertyCount), length_is(*TransferLen)] DEVPROPKEY *PropertyKeys, @@ -790,9 +790,9 @@ cpp_quote("#if _WIN32_WINNT >= 0x0600") /* Function 66 */ DWORD PNP_GetObjectProp( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_STRING_LEN)] LPWSTR ObjectName, + [in, string, ref] LPWSTR ObjectName, [in] DWORD ObjectType, - [in, string, unique, range(0, PNP_MAX_CULTURE_NAME_LEN)] LPWSTR PropertyCultureName, + [in, string, unique] LPWSTR PropertyCultureName, [in] const DEVPROPKEY *PropertyKey, [out] DEVPROPTYPE *PropertyType, [in, out] PNP_PROP_SIZE *PropertySize, @@ -803,9 +803,9 @@ cpp_quote("#if _WIN32_WINNT >= 0x0600") /* Function 67 */ DWORD PNP_SetObjectProp( [in] handle_t hBinding, - [in, string, ref, range(0, PNP_MAX_STRING_LEN)] LPWSTR ObjectName, + [in, string, ref] LPWSTR ObjectName, [in] DWORD ObjectType, - [in, string, unique, range(0, PNP_MAX_CULTURE_NAME_LEN)] LPWSTR PropertyCultureName, + [in, string, unique] LPWSTR PropertyCultureName, [in] const DEVPROPKEY *PropertyKey, [in] DEVPROPTYPE PropertyType, [in] PNP_PROP_SIZE PropertySize, diff --git a/reactos/include/reactos/idl/svcctl.idl b/reactos/include/reactos/idl/svcctl.idl index 115d1f44225..fe4dc89ffb1 100644 --- a/reactos/include/reactos/idl/svcctl.idl +++ b/reactos/include/reactos/idl/svcctl.idl @@ -56,26 +56,26 @@ typedef struct _SERVICE_STATUS_PROCESS { } SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS; typedef struct _ENUM_SERVICE_STATUSA { - [string, range(0, 8 * 1024)] LPSTR lpServiceName; - [string, range(0, 8 * 1024)] LPSTR lpDisplayName; + [string] LPSTR lpServiceName; + [string] LPSTR lpDisplayName; SERVICE_STATUS ServiceStatus; } ENUM_SERVICE_STATUSA, *LPENUM_SERVICE_STATUSA; typedef struct _ENUM_SERVICE_STATUSW { - [string, range(0, 8 * 1024)] LPWSTR lpServiceName; - [string, range(0, 8 * 1024)] LPWSTR lpDisplayName; + [string] LPWSTR lpServiceName; + [string] LPWSTR lpDisplayName; SERVICE_STATUS ServiceStatus; } ENUM_SERVICE_STATUSW, *LPENUM_SERVICE_STATUSW; typedef struct _ENUM_SERVICE_STATUS_PROCESSA { - [string, range(0, 8 * 1024)] LPSTR lpServiceName; - [string, range(0, 8 * 1024)] LPSTR lpDisplayName; + [string] LPSTR lpServiceName; + [string] LPSTR lpDisplayName; SERVICE_STATUS_PROCESS ServiceStatusProcess; } ENUM_SERVICE_STATUS_PROCESSA, *LPENUM_SERVICE_STATUS_PROCESSA; typedef struct _ENUM_SERVICE_STATUS_PROCESSW { - [string, range(0, 8 * 1024)] LPWSTR lpServiceName; - [string, range(0, 8 * 1024)] LPWSTR lpDisplayName; + [string] LPWSTR lpServiceName; + [string] LPWSTR lpDisplayName; SERVICE_STATUS_PROCESS ServiceStatusProcess; } ENUM_SERVICE_STATUS_PROCESSW, *LPENUM_SERVICE_STATUS_PROCESSW; @@ -83,11 +83,11 @@ typedef struct _QUERY_SERVICE_CONFIGA { DWORD dwServiceType; DWORD dwStartType; DWORD dwErrorControl; - [string, range(0, 8 * 1024)] LPSTR lpBinaryPathName; - [string, range(0, 8 * 1024)] LPSTR lpLoadOrderGroup; + [string] LPSTR lpBinaryPathName; + [string] LPSTR lpLoadOrderGroup; DWORD dwTagId; - [string, range(0, 8 * 1024)] LPSTR lpDependencies; - [string, range(0, 8 * 1024)] LPSTR lpServiceStartName; + [string] LPSTR lpDependencies; + [string] LPSTR lpServiceStartName; LPSTR lpDisplayName; } QUERY_SERVICE_CONFIGA, *LPQUERY_SERVICE_CONFIGA; @@ -95,23 +95,23 @@ typedef struct _QUERY_SERVICE_CONFIGW { DWORD dwServiceType; DWORD dwStartType; DWORD dwErrorControl; - [string, range(0, 8 * 1024)] LPWSTR lpBinaryPathName; - [string, range(0, 8 * 1024)] LPWSTR lpLoadOrderGroup; + [string] LPWSTR lpBinaryPathName; + [string] LPWSTR lpLoadOrderGroup; DWORD dwTagId; - [string, range(0, 8 * 1024)] LPWSTR lpDependencies; - [string, range(0, 8 * 1024)] LPWSTR lpServiceStartName; + [string] LPWSTR lpDependencies; + [string] LPWSTR lpServiceStartName; LPWSTR lpDisplayName; } QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW; typedef struct _QUERY_SERVICE_LOCK_STATUSA { DWORD fIsLocked; - [string, range(0, 8 * 1024)] LPSTR lpLockOwner; + [string] LPSTR lpLockOwner; DWORD dwLockDuration; } QUERY_SERVICE_LOCK_STATUSA, *LPQUERY_SERVICE_LOCK_STATUSA; typedef struct _QUERY_SERVICE_LOCK_STATUSW { DWORD fIsLocked; - [string, range(0, 8 * 1024)] LPWSTR lpLockOwner; + [string] LPWSTR lpLockOwner; DWORD dwLockDuration; } QUERY_SERVICE_LOCK_STATUSW, *LPQUERY_SERVICE_LOCK_STATUSW; @@ -132,25 +132,25 @@ typedef [v1_enum] enum _SC_ENUM_TYPE { } SC_ENUM_TYPE; typedef struct _SERVICE_DESCRIPTIONA { - [string, range(0, 8 * 1024)] LPSTR lpDescription; + [string] LPSTR lpDescription; } SERVICE_DESCRIPTIONA, *LPSERVICE_DESCRIPTIONA; typedef struct _SERVICE_DESCRIPTIONW { - [string, range(0, 8 * 1024)] LPWSTR lpDescription; + [string] LPWSTR lpDescription; } SERVICE_DESCRIPTIONW, *LPSERVICE_DESCRIPTIONW; typedef struct _SERVICE_FAILURE_ACTIONSA { DWORD dwResetPeriod; - [string, range(0, 8 * 1024)] LPSTR lpRebootMsg; - [string, range(0, 8 * 1024)] LPSTR lpCommand; + [string] LPSTR lpRebootMsg; + [string] LPSTR lpCommand; [range(0, 1024)] DWORD cActions; [size_is(cActions)] SC_ACTION* lpsaActions; } SERVICE_FAILURE_ACTIONSA, *LPSERVICE_FAILURE_ACTIONSA; typedef struct _SERVICE_FAILURE_ACTIONSW { DWORD dwResetPeriod; - [string, range(0, 8 * 1024)] LPWSTR lpRebootMsg; - [string, range(0, 8 * 1024)] LPWSTR lpCommand; + [string] LPWSTR lpRebootMsg; + [string] LPWSTR lpCommand; [range(0, 1024)] DWORD cActions; [size_is(cActions)] SC_ACTION* lpsaActions; } SERVICE_FAILURE_ACTIONSW, *LPSERVICE_FAILURE_ACTIONSW; @@ -189,7 +189,7 @@ typedef struct _SC_RPC_CONFIG_INFOA { [case(6)] LPSERVICE_RPC_REQUIRED_PRIVILEGES_INFO psrp; [case(7)] LPSERVICE_PRESHUTDOWN_INFO psps; } DUMMYUNIONNAME; - [string, range(0, 8 * 1024)] LPSTR lpDescription; //FIXME + [string] LPSTR lpDescription; //FIXME } SC_RPC_CONFIG_INFOA, *LPSC_RPC_CONFIG_INFOA; typedef struct _SC_RPC_CONFIG_INFOW { @@ -224,7 +224,7 @@ typedef struct _SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_2 { DWORD dwNotificationStatus; DWORD dwSequence; DWORD dwNotificationTriggered; - [string, range(0, 64 * 1024)] PWSTR pszServiceNames; + [string] PWSTR pszServiceNames; } SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_2, *PSERVICE_NOTIFY_STATUS_CHANGE_PARAMS_2; typedef struct _SC_RPC_NOTIFY_PARAMS { @@ -270,12 +270,12 @@ typedef [v1_enum] enum _SC_STATUS_TYPE { typedef struct _SERVICE_CONTROL_STATUS_REASON_IN_PARAMSA { DWORD dwReason; - [string, range(0, SC_MAX_COMMENT_LENGTH)] LPSTR pszComment; + [string] LPSTR pszComment; } SERVICE_CONTROL_STATUS_REASON_IN_PARAMSA, *LPSERVICE_CONTROL_STATUS_REASON_IN_PARAMSA; typedef struct _SERVICE_CONTROL_STATUS_REASON_IN_PARAMSW { DWORD dwReason; - [string, range(0, SC_MAX_COMMENT_LENGTH)] LPWSTR pszComment; + [string] LPWSTR pszComment; } SERVICE_CONTROL_STATUS_REASON_IN_PARAMSW, *LPSERVICE_CONTROL_STATUS_REASON_IN_PARAMSW; typedef struct _SERVICE_CONTROL_STATUS_REASON_OUT_PARAMS { @@ -287,11 +287,11 @@ typedef SERVICE_NOTIFY_STATUS_CHANGE_PARAMS_2 SERVICE_NOTIFY_STATUS_CHANGE_PARAM cpp_quote("#endif") typedef struct _STRING_PTRSA { - [string, range(0, SC_MAX_ARGUMENT_LENGTH)] LPSTR StringPtr; + [string] LPSTR StringPtr; } STRING_PTRSA, *PSTRING_PTRSA, *LPSTRING_PTRSA; typedef struct _STRING_PTRSW { - [string, range(0, SC_MAX_ARGUMENT_LENGTH)] LPWSTR StringPtr; + [string] LPWSTR StringPtr; } STRING_PTRSW, *PSTRING_PTRSW, *LPSTRING_PTRSW; [ @@ -351,7 +351,7 @@ interface svcctl /* Function 9 */ DWORD RNotifyBootConfigStatus( - [in, string, unique, range(0, SC_MAX_COMPUTER_NAME_LENGTH)] SVCCTL_HANDLEW lpMachineName, + [in, string, unique] SVCCTL_HANDLEW lpMachineName, [in] DWORD BootAcceptable); /* Function 10 */ @@ -368,31 +368,31 @@ interface svcctl [in] DWORD dwServiceType, [in] DWORD dwStartType, [in] DWORD dwErrorControl, - [in, string, unique, range(0, SC_MAX_PATH_LENGTH)] LPWSTR lpBinaryPathName, - [in, string, unique, range(0, SC_MAX_PATH_LENGTH)] LPWSTR lpLoadOrderGroup, + [in, string, unique] LPWSTR lpBinaryPathName, + [in, string, unique] LPWSTR lpLoadOrderGroup, [in, out, unique] LPDWORD lpdwTagId, [in, unique, size_is(dwDependSize)] LPBYTE lpDependencies, [in, range(0, SC_MAX_DEPEND_SIZE)] DWORD dwDependSize, - [in, string, unique, range(0, SC_MAX_ACCOUNT_NAME_LENGTH)] LPWSTR lpServiceStartName, + [in, string, unique] LPWSTR lpServiceStartName, [in, unique, size_is(dwPwSize)] LPBYTE lpPassword, [in, range(0, SC_MAX_PWD_SIZE)] DWORD dwPwSize, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPWSTR lpDisplayName); + [in, string, unique] LPWSTR lpDisplayName); /* Function 12 */ DWORD RCreateServiceW( [in] SC_RPC_HANDLE hSCManager, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPCWSTR lpServiceName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPCWSTR lpDisplayName, + [in, string] LPCWSTR lpServiceName, + [in, string, unique] LPCWSTR lpDisplayName, [in] DWORD dwDesiredAccess, [in] DWORD dwServiceType, [in] DWORD dwStartType, [in] DWORD dwErrorControl, - [in, string, range(0, SC_MAX_PATH_LENGTH)] LPCWSTR lpBinaryPathName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPCWSTR lpLoadOrderGroup, + [in, string] LPCWSTR lpBinaryPathName, + [in, string, unique] LPCWSTR lpLoadOrderGroup, [in, out, unique] LPDWORD lpdwTagId, [in, unique, size_is(dwDependSize)] LPBYTE lpDependencies, [in, range(0, SC_MAX_DEPEND_SIZE)] DWORD dwDependSize, - [in, string, unique, range(0, SC_MAX_ACCOUNT_NAME_LENGTH)] LPCWSTR lpServiceStartName, + [in, string, unique] LPCWSTR lpServiceStartName, [in, unique, size_is(dwPwSize)] LPBYTE lpPassword, [in, range(0, SC_MAX_PWD_SIZE)] DWORD dwPwSize, [out] LPSC_RPC_HANDLE lpServiceHandle); @@ -419,15 +419,15 @@ interface svcctl /* Function 15 */ DWORD ROpenSCManagerW( - [in, string, unique, range(0, SC_MAX_COMPUTER_NAME_LENGTH)] SVCCTL_HANDLEW lpMachineName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPWSTR lpDatabaseName, + [in, string, unique] SVCCTL_HANDLEW lpMachineName, + [in, string, unique] LPWSTR lpDatabaseName, [in] DWORD dwDesiredAccess, [out] LPSC_RPC_HANDLE lpScHandle); /* Function 16 */ DWORD ROpenServiceW( [in] SC_RPC_HANDLE hSCManager, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPWSTR lpServiceName, + [in, string] LPWSTR lpServiceName, [in] DWORD dwDesiredAccess, [out] LPSC_RPC_HANDLE lpServiceHandle); @@ -455,15 +455,15 @@ interface svcctl /* Function 20 */ DWORD RGetServiceDisplayNameW( [in] SC_RPC_HANDLE hSCManager, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPCWSTR lpServiceName, - [out, string, range(1, 4*1024+1), size_is(*lpcchBuffer + 1)] LPWSTR lpDisplayName, + [in, string] LPCWSTR lpServiceName, + [out, string, size_is(*lpcchBuffer + 1)] LPWSTR lpDisplayName, [in, out] DWORD* lpcchBuffer); /* Function 21 */ DWORD RGetServiceKeyNameW( [in] SC_RPC_HANDLE hSCManager, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPCWSTR lpDisplayName, - [out, string, range(1, 4*1024+1), size_is(*lpcchBuffer + 1)] LPWSTR lpServiceName, + [in, string] LPCWSTR lpDisplayName, + [out, string, size_is(*lpcchBuffer + 1)] LPWSTR lpServiceName, [in, out] DWORD* lpcchBuffer); /* Function 22 */ @@ -480,31 +480,31 @@ interface svcctl [in] DWORD dwServiceType, [in] DWORD dwStartType, [in] DWORD dwErrorControl, - [in, string, unique, range(0, SC_MAX_PATH_LENGTH)] LPSTR lpBinaryPathName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpLoadOrderGroup, + [in, string, unique] LPSTR lpBinaryPathName, + [in, string, unique] LPSTR lpLoadOrderGroup, [in, out, unique] LPDWORD lpdwTagId, [in, unique, size_is(dwDependSize)] LPSTR lpDependencies, [in, range(0, SC_MAX_DEPEND_SIZE)] DWORD dwDependSize, - [in, string, unique, range(0, SC_MAX_ACCOUNT_NAME_LENGTH)] LPSTR lpServiceStartName, + [in, string, unique] LPSTR lpServiceStartName, [in, unique, size_is(dwPwSize)] LPBYTE lpPassword, [in, range(0, SC_MAX_PWD_SIZE)] DWORD dwPwSize, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpDisplayName); + [in, string, unique] LPSTR lpDisplayName); /* Function 24 */ DWORD RCreateServiceA( [in] SC_RPC_HANDLE hSCManager, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpServiceName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpDisplayName, + [in, string] LPSTR lpServiceName, + [in, string, unique] LPSTR lpDisplayName, [in] DWORD dwDesiredAccess, [in] DWORD dwServiceType, [in] DWORD dwStartType, [in] DWORD dwErrorControl, - [in, string, range(0, SC_MAX_PATH_LENGTH)] LPSTR lpBinaryPathName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpLoadOrderGroup, + [in, string] LPSTR lpBinaryPathName, + [in, string, unique] LPSTR lpLoadOrderGroup, [in, out, unique] LPDWORD lpdwTagId, [in, unique, size_is(dwDependSize)] LPBYTE lpDependencies, [in, range(0, SC_MAX_DEPEND_SIZE)] DWORD dwDependSize, - [in, string, unique, range(0, SC_MAX_ACCOUNT_NAME_LENGTH)] LPSTR lpServiceStartName, + [in, string, unique] LPSTR lpServiceStartName, [in, unique, size_is(dwPwSize)] LPBYTE lpPassword, [in, range(0, SC_MAX_PWD_SIZE)] DWORD dwPwSize, [out] LPSC_RPC_HANDLE lpServiceHandle); @@ -531,15 +531,15 @@ interface svcctl /* Function 27 */ DWORD ROpenSCManagerA( - [in, string, unique, range(0, SC_MAX_COMPUTER_NAME_LENGTH)] SVCCTL_HANDLEA lpMachineName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpDatabaseName, + [in, string, unique] SVCCTL_HANDLEA lpMachineName, + [in, string, unique] LPSTR lpDatabaseName, [in] DWORD dwDesiredAccess, [out] LPSC_RPC_HANDLE lpScHandle); /* Function 28 */ DWORD ROpenServiceA( [in] SC_RPC_HANDLE hSCManager, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpServiceName, + [in, string] LPSTR lpServiceName, [in] DWORD dwDesiredAccess, [out] LPSC_RPC_HANDLE lpServiceHandle); @@ -567,21 +567,21 @@ interface svcctl /* Function 32 */ DWORD RGetServiceDisplayNameA( [in] SC_RPC_HANDLE hSCManager, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPCSTR lpServiceName, + [in, string] LPCSTR lpServiceName, [out, string, size_is(*lpcchBuffer)] LPSTR lpDisplayName, [in, out] LPBOUNDED_DWORD_4K lpcchBuffer); /* Function 33 */ DWORD RGetServiceKeyNameA( [in] SC_RPC_HANDLE hSCManager, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPCSTR lpDisplayName, + [in, string] LPCSTR lpDisplayName, [out, string, size_is(*lpcchBuffer)] LPSTR lpKeyName, [in, out] LPBOUNDED_DWORD_4K lpcchBuffer); /* Function 34 */ DWORD RI_ScGetCurrentGroupStateW( [in] SC_RPC_HANDLE hSCManager, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPWSTR lpLoadOrderGroup, + [in, string, unique] LPWSTR lpLoadOrderGroup, [out] LPDWORD lpState); /* Function 35 */ @@ -594,7 +594,7 @@ interface svcctl [out] LPBOUNDED_DWORD_256K pcbBytesNeeded, [out] LPBOUNDED_DWORD_256K lpServicesReturned, [in, out, unique] LPBOUNDED_DWORD_256K lpResumeIndex, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPCWSTR pszGroupName); + [in, string, unique] LPCWSTR pszGroupName); /* Function 36 */ DWORD RChangeServiceConfig2A( @@ -641,7 +641,7 @@ interface svcctl [out] LPBOUNDED_DWORD_256K pcbBytesNeeded, [out] LPBOUNDED_DWORD_256K lpServicesReturned, [in, out, unique] LPBOUNDED_DWORD_256K lpResumeIndex, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPCSTR pszGroupName); + [in, string, unique] LPCSTR pszGroupName); /* Function 42 */ DWORD REnumServicesStatusExW( @@ -654,7 +654,7 @@ interface svcctl [out] LPBOUNDED_DWORD_256K pcbBytesNeeded, [out] LPBOUNDED_DWORD_256K lpServicesReturned, [in, out, unique] LPBOUNDED_DWORD_256K lpResumeIndex, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPCWSTR pszGroupName); + [in, string, unique] LPCWSTR pszGroupName); /* Function 43 */ DWORD RSendTSMessage( @@ -663,18 +663,18 @@ interface svcctl /* Function 44 */ DWORD RCreateServiceWOW64A( [in] handle_t BindingHandle, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpServiceName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpDisplayName, + [in, string] LPSTR lpServiceName, + [in, string, unique] LPSTR lpDisplayName, [in] DWORD dwDesiredAccess, [in] DWORD dwServiceType, [in] DWORD dwStartType, [in] DWORD dwErrorControl, - [in, string, range(0, SC_MAX_PATH_LENGTH)] LPSTR lpBinaryPathName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPSTR lpLoadOrderGroup, + [in, string] LPSTR lpBinaryPathName, + [in, string, unique] LPSTR lpLoadOrderGroup, [in, out, unique] LPDWORD lpdwTagId, [in, unique, size_is(dwDependSize)] LPBYTE lpDependencies, [in, range(0, SC_MAX_DEPEND_SIZE)] DWORD dwDependSize, - [in, string, unique, range(0, SC_MAX_ACCOUNT_NAME_LENGTH)] LPSTR lpServiceStartName, + [in, string, unique] LPSTR lpServiceStartName, [in, unique, size_is(dwPwSize)] LPBYTE lpPassword, [in, range(0, SC_MAX_PWD_SIZE)] DWORD dwPwSize, [out] LPSC_RPC_HANDLE lpServiceHandle); @@ -682,18 +682,18 @@ interface svcctl /* Function 45 */ DWORD RCreateServiceWOW64W( [in] handle_t BindingHandle, - [in, string, range(0, SC_MAX_NAME_LENGTH)] LPWSTR lpServiceName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPWSTR lpDisplayName, + [in, string] LPWSTR lpServiceName, + [in, string, unique] LPWSTR lpDisplayName, [in] DWORD dwDesiredAccess, [in] DWORD dwServiceType, [in] DWORD dwStartType, [in] DWORD dwErrorControl, - [in, string, range(0, SC_MAX_PATH_LENGTH)] LPWSTR lpBinaryPathName, - [in, string, unique, range(0, SC_MAX_NAME_LENGTH)] LPWSTR lpLoadOrderGroup, + [in, string] LPWSTR lpBinaryPathName, + [in, string, unique] LPWSTR lpLoadOrderGroup, [in, out, unique] LPDWORD lpdwTagId, [in, unique, size_is(dwDependSize)] LPBYTE lpDependencies, [in, range(0, SC_MAX_DEPEND_SIZE)] DWORD dwDependSize, - [in, string, unique, range(0, SC_MAX_ACCOUNT_NAME_LENGTH)] LPWSTR lpServiceStartName, + [in, string, unique] LPWSTR lpServiceStartName, [in, unique, size_is(dwPwSize)] LPBYTE lpPassword, [in, range(0, SC_MAX_PWD_SIZE)] DWORD dwPwSize, [out] LPSC_RPC_HANDLE lpServiceHandle); From 5040fe13f1d28409484196cbbd087e8b71cf6ccb Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 24 Nov 2009 22:42:40 +0000 Subject: [PATCH 090/140] [WIDL] - Update widl to Wine-1.1.33. svn path=/trunk/; revision=44284 --- reactos/tools/widl/expr.c | 17 +- reactos/tools/widl/expr.h | 2 +- reactos/tools/widl/hash.c | 2 +- reactos/tools/widl/header.c | 103 +- reactos/tools/widl/parser.l | 3 + reactos/tools/widl/parser.tab.c | 3725 +++++++++++++++++-------------- reactos/tools/widl/parser.tab.h | 265 +-- reactos/tools/widl/parser.y | 339 ++- reactos/tools/widl/parser.yy.c | 334 +-- reactos/tools/widl/typegen.c | 344 +-- reactos/tools/widl/typegen.h | 2 + reactos/tools/widl/typelib.c | 19 + reactos/tools/widl/typelib.h | 3 + reactos/tools/widl/typetree.c | 106 +- reactos/tools/widl/typetree.h | 16 + reactos/tools/widl/widltypes.h | 11 + 16 files changed, 3065 insertions(+), 2226 deletions(-) diff --git a/reactos/tools/widl/expr.c b/reactos/tools/widl/expr.c index 405b5def1b6..b5283767288 100644 --- a/reactos/tools/widl/expr.c +++ b/reactos/tools/widl/expr.c @@ -101,9 +101,16 @@ expr_t *make_exprs(enum expr_type type, char *val) return e; } -expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) +expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr) { expr_t *e; + type_t *tref; + + if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER) + error_loc("invalid storage class for type expression\n"); + + tref = var->type; + e = xmalloc(sizeof(expr_t)); e->type = type; e->ref = expr; @@ -125,6 +132,7 @@ expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr) e->is_const = TRUE; e->cval = expr->cval; } + free(var); return e; } @@ -297,15 +305,19 @@ static int is_integer_type(const type_t *type) case TYPE_BASIC_INT32: case TYPE_BASIC_INT64: case TYPE_BASIC_INT: + case TYPE_BASIC_INT3264: case TYPE_BASIC_CHAR: case TYPE_BASIC_HYPER: case TYPE_BASIC_BYTE: case TYPE_BASIC_WCHAR: case TYPE_BASIC_ERROR_STATUS_T: return TRUE; - default: + case TYPE_BASIC_FLOAT: + case TYPE_BASIC_DOUBLE: + case TYPE_BASIC_HANDLE: return FALSE; } + return FALSE; default: return FALSE; } @@ -376,6 +388,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type, case TYPE_INTERFACE: case TYPE_POINTER: case TYPE_ARRAY: + case TYPE_BITFIELD: /* nothing to do */ break; case TYPE_ALIAS: diff --git a/reactos/tools/widl/expr.h b/reactos/tools/widl/expr.h index 31ce31d3e9e..e16975aec0f 100644 --- a/reactos/tools/widl/expr.h +++ b/reactos/tools/widl/expr.h @@ -29,7 +29,7 @@ extern expr_t *make_expr(enum expr_type type); extern expr_t *make_exprl(enum expr_type type, long val); extern expr_t *make_exprd(enum expr_type type, double val); extern expr_t *make_exprs(enum expr_type type, char *val); -extern expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr); +extern expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr); extern expr_t *make_expr1(enum expr_type type, expr_t *expr); extern expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2); extern expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3); diff --git a/reactos/tools/widl/hash.c b/reactos/tools/widl/hash.c index fb33d19e2b9..551039c2cfa 100644 --- a/reactos/tools/widl/hash.c +++ b/reactos/tools/widl/hash.c @@ -636,4 +636,4 @@ unsigned int lhash_val_of_name_sys( syskind_t skind, LCID lcid, LPCSTR lpStr) nLoWord = (nLoWord % 65599) & 0xffff; return nHiWord | nLoWord; -} \ No newline at end of file +} diff --git a/reactos/tools/widl/header.c b/reactos/tools/widl/header.c index b6b7be8eccd..e87a44e9077 100644 --- a/reactos/tools/widl/header.c +++ b/reactos/tools/widl/header.c @@ -265,6 +265,7 @@ void write_type_left(FILE *h, type_t *t, int declonly) case TYPE_BASIC_INT16: fprintf(h, "short"); break; case TYPE_BASIC_INT: fprintf(h, "int"); break; case TYPE_BASIC_INT64: fprintf(h, "__int64"); break; + case TYPE_BASIC_INT3264: fprintf(h, "__int3264"); break; case TYPE_BASIC_BYTE: fprintf(h, "byte"); break; case TYPE_BASIC_CHAR: fprintf(h, "char"); break; case TYPE_BASIC_WCHAR: fprintf(h, "wchar_t"); break; @@ -294,6 +295,9 @@ void write_type_left(FILE *h, type_t *t, int declonly) case TYPE_VOID: fprintf(h, "void"); break; + case TYPE_BITFIELD: + write_type_left(h, type_bitfield_get_field(t), declonly); + break; case TYPE_ALIAS: case TYPE_FUNCTION: /* handled elsewhere */ @@ -307,56 +311,83 @@ void write_type_right(FILE *h, type_t *t, int is_field) { if (!h) return; - if (type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t)) { - if (is_conformant_array(t)) { - fprintf(h, "[%s]", is_field ? "1" : ""); - t = type_array_get_element(t); + switch (type_get_type(t)) + { + case TYPE_ARRAY: + if (!type_array_is_decl_as_ptr(t)) + { + if (is_conformant_array(t)) + { + fprintf(h, "[%s]", is_field ? "1" : ""); + t = type_array_get_element(t); + } + for ( ; + type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t); + t = type_array_get_element(t)) + fprintf(h, "[%u]", type_array_get_dim(t)); } - for ( ; - type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t); - t = type_array_get_element(t)) - fprintf(h, "[%u]", type_array_get_dim(t)); + break; + case TYPE_BITFIELD: + fprintf(h, " : %lu", type_bitfield_get_bits(t)->cval); + break; + case TYPE_VOID: + case TYPE_BASIC: + case TYPE_ENUM: + case TYPE_STRUCT: + case TYPE_ENCAPSULATED_UNION: + case TYPE_UNION: + case TYPE_ALIAS: + case TYPE_MODULE: + case TYPE_COCLASS: + case TYPE_FUNCTION: + case TYPE_INTERFACE: + case TYPE_POINTER: + break; } } static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name) { - type_t *pt; + type_t *pt = NULL; int ptr_level = 0; if (!h) return; - for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++) - ; + if (t) { + for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++) + ; - if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) { - int i; - const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV); - if (!callconv) callconv = ""; - if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline "); - write_type_left(h, type_function_get_rettype(pt), declonly); - fputc(' ', h); - if (ptr_level) fputc('(', h); - fprintf(h, "%s ", callconv); - for (i = 0; i < ptr_level; i++) - fputc('*', h); - } else - write_type_left(h, t, declonly); + if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) { + int i; + const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV); + if (!callconv) callconv = ""; + if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline "); + write_type_left(h, type_function_get_rettype(pt), declonly); + fputc(' ', h); + if (ptr_level) fputc('(', h); + fprintf(h, "%s ", callconv); + for (i = 0; i < ptr_level; i++) + fputc('*', h); + } else + write_type_left(h, t, declonly); + } - if (name) fprintf(h, "%s%s", needs_space_after(t) ? " " : "", name ); + if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name ); - if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) { - const var_list_t *args = type_function_get_args(pt); + if (t) { + if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) { + const var_list_t *args = type_function_get_args(pt); - if (ptr_level) fputc(')', h); - fputc('(', h); - if (args) - write_args(h, args, NULL, 0, FALSE); - else - fprintf(h, "void"); - fputc(')', h); - } else - write_type_right(h, t, is_field); + if (ptr_level) fputc(')', h); + fputc('(', h); + if (args) + write_args(h, args, NULL, 0, FALSE); + else + fprintf(h, "void"); + fputc(')', h); + } else + write_type_right(h, t, is_field); + } } void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name) diff --git a/reactos/tools/widl/parser.l b/reactos/tools/widl/parser.l index 55a73c75be1..f509cb19eae 100644 --- a/reactos/tools/widl/parser.l +++ b/reactos/tools/widl/parser.l @@ -193,6 +193,7 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY; \<= return LESSEQUAL; \|\| return LOGICALOR; && return LOGICALAND; +\.\.\. return ELLIPSIS; . return yytext[0]; <> { if (import_stack_ptr) @@ -220,6 +221,7 @@ static const struct keyword keywords[] = { {"TRUE", tTRUE}, {"__cdecl", tCDECL}, {"__fastcall", tFASTCALL}, + {"__int3264", tINT3264}, {"__int64", tINT64}, {"__pascal", tPASCAL}, {"__stdcall", tSTDCALL}, @@ -279,6 +281,7 @@ static const struct keyword attr_keywords[] = { {"aggregatable", tAGGREGATABLE}, {"allocate", tALLOCATE}, + {"annotation", tANNOTATION}, {"appobject", tAPPOBJECT}, {"async", tASYNC}, {"async_uuid", tASYNCUUID}, diff --git a/reactos/tools/widl/parser.tab.c b/reactos/tools/widl/parser.tab.c index c5962dee85e..198575fba90 100644 --- a/reactos/tools/widl/parser.tab.c +++ b/reactos/tools/widl/parser.tab.c @@ -180,7 +180,7 @@ static attr_t *make_attrv(enum attr_type type, unsigned long val); static attr_t *make_attrp(enum attr_type type, void *val); static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); static array_dims_t *append_array(array_dims_t *list, expr_t *expr); -static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, int top); +static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, int top); static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls); static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_t *make_ifref(type_t *iface); @@ -200,7 +200,7 @@ static type_t *find_type_or_error2(char *name, int t); static var_t *reg_const(var_t *var); static char *gen_name(void); -static void check_arg(var_t *arg); +static void check_arg_attrs(const var_t *arg); static void check_statements(const statement_list_t *stmts, int is_inside_library); static void check_all_user_types(const statement_list_t *stmts); static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs); @@ -279,136 +279,139 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s LESSEQUAL = 273, LOGICALOR = 274, LOGICALAND = 275, - tAGGREGATABLE = 276, - tALLOCATE = 277, - tAPPOBJECT = 278, - tASYNC = 279, - tASYNCUUID = 280, - tAUTOHANDLE = 281, - tBINDABLE = 282, - tBOOLEAN = 283, - tBROADCAST = 284, - tBYTE = 285, - tBYTECOUNT = 286, - tCALLAS = 287, - tCALLBACK = 288, - tCASE = 289, - tCDECL = 290, - tCHAR = 291, - tCOCLASS = 292, - tCODE = 293, - tCOMMSTATUS = 294, - tCONST = 295, - tCONTEXTHANDLE = 296, - tCONTEXTHANDLENOSERIALIZE = 297, - tCONTEXTHANDLESERIALIZE = 298, - tCONTROL = 299, - tCPPQUOTE = 300, - tDEFAULT = 301, - tDEFAULTCOLLELEM = 302, - tDEFAULTVALUE = 303, - tDEFAULTVTABLE = 304, - tDISPLAYBIND = 305, - tDISPINTERFACE = 306, - tDLLNAME = 307, - tDOUBLE = 308, - tDUAL = 309, - tENDPOINT = 310, - tENTRY = 311, - tENUM = 312, - tERRORSTATUST = 313, - tEXPLICITHANDLE = 314, - tEXTERN = 315, - tFALSE = 316, - tFASTCALL = 317, - tFLOAT = 318, - tHANDLE = 319, - tHANDLET = 320, - tHELPCONTEXT = 321, - tHELPFILE = 322, - tHELPSTRING = 323, - tHELPSTRINGCONTEXT = 324, - tHELPSTRINGDLL = 325, - tHIDDEN = 326, - tHYPER = 327, - tID = 328, - tIDEMPOTENT = 329, - tIIDIS = 330, - tIMMEDIATEBIND = 331, - tIMPLICITHANDLE = 332, - tIMPORT = 333, - tIMPORTLIB = 334, - tIN = 335, - tIN_LINE = 336, - tINLINE = 337, - tINPUTSYNC = 338, - tINT = 339, - tINT64 = 340, - tINTERFACE = 341, - tLCID = 342, - tLENGTHIS = 343, - tLIBRARY = 344, - tLOCAL = 345, - tLONG = 346, - tMETHODS = 347, - tMODULE = 348, - tNONBROWSABLE = 349, - tNONCREATABLE = 350, - tNONEXTENSIBLE = 351, - tNULL = 352, - tOBJECT = 353, - tODL = 354, - tOLEAUTOMATION = 355, - tOPTIONAL = 356, - tOUT = 357, - tPASCAL = 358, - tPOINTERDEFAULT = 359, - tPROPERTIES = 360, - tPROPGET = 361, - tPROPPUT = 362, - tPROPPUTREF = 363, - tPTR = 364, - tPUBLIC = 365, - tRANGE = 366, - tREADONLY = 367, - tREF = 368, - tREGISTER = 369, - tREQUESTEDIT = 370, - tRESTRICTED = 371, - tRETVAL = 372, - tSAFEARRAY = 373, - tSHORT = 374, - tSIGNED = 375, - tSIZEIS = 376, - tSIZEOF = 377, - tSMALL = 378, - tSOURCE = 379, - tSTATIC = 380, - tSTDCALL = 381, - tSTRICTCONTEXTHANDLE = 382, - tSTRING = 383, - tSTRUCT = 384, - tSWITCH = 385, - tSWITCHIS = 386, - tSWITCHTYPE = 387, - tTRANSMITAS = 388, - tTRUE = 389, - tTYPEDEF = 390, - tUNION = 391, - tUNIQUE = 392, - tUNSIGNED = 393, - tUUID = 394, - tV1ENUM = 395, - tVARARG = 396, - tVERSION = 397, - tVOID = 398, - tWCHAR = 399, - tWIREMARSHAL = 400, - ADDRESSOF = 401, - NEG = 402, - POS = 403, - PPTR = 404, - CAST = 405 + ELLIPSIS = 276, + tAGGREGATABLE = 277, + tALLOCATE = 278, + tANNOTATION = 279, + tAPPOBJECT = 280, + tASYNC = 281, + tASYNCUUID = 282, + tAUTOHANDLE = 283, + tBINDABLE = 284, + tBOOLEAN = 285, + tBROADCAST = 286, + tBYTE = 287, + tBYTECOUNT = 288, + tCALLAS = 289, + tCALLBACK = 290, + tCASE = 291, + tCDECL = 292, + tCHAR = 293, + tCOCLASS = 294, + tCODE = 295, + tCOMMSTATUS = 296, + tCONST = 297, + tCONTEXTHANDLE = 298, + tCONTEXTHANDLENOSERIALIZE = 299, + tCONTEXTHANDLESERIALIZE = 300, + tCONTROL = 301, + tCPPQUOTE = 302, + tDEFAULT = 303, + tDEFAULTCOLLELEM = 304, + tDEFAULTVALUE = 305, + tDEFAULTVTABLE = 306, + tDISPLAYBIND = 307, + tDISPINTERFACE = 308, + tDLLNAME = 309, + tDOUBLE = 310, + tDUAL = 311, + tENDPOINT = 312, + tENTRY = 313, + tENUM = 314, + tERRORSTATUST = 315, + tEXPLICITHANDLE = 316, + tEXTERN = 317, + tFALSE = 318, + tFASTCALL = 319, + tFLOAT = 320, + tHANDLE = 321, + tHANDLET = 322, + tHELPCONTEXT = 323, + tHELPFILE = 324, + tHELPSTRING = 325, + tHELPSTRINGCONTEXT = 326, + tHELPSTRINGDLL = 327, + tHIDDEN = 328, + tHYPER = 329, + tID = 330, + tIDEMPOTENT = 331, + tIIDIS = 332, + tIMMEDIATEBIND = 333, + tIMPLICITHANDLE = 334, + tIMPORT = 335, + tIMPORTLIB = 336, + tIN = 337, + tIN_LINE = 338, + tINLINE = 339, + tINPUTSYNC = 340, + tINT = 341, + tINT3264 = 342, + tINT64 = 343, + tINTERFACE = 344, + tLCID = 345, + tLENGTHIS = 346, + tLIBRARY = 347, + tLOCAL = 348, + tLONG = 349, + tMETHODS = 350, + tMODULE = 351, + tNONBROWSABLE = 352, + tNONCREATABLE = 353, + tNONEXTENSIBLE = 354, + tNULL = 355, + tOBJECT = 356, + tODL = 357, + tOLEAUTOMATION = 358, + tOPTIONAL = 359, + tOUT = 360, + tPASCAL = 361, + tPOINTERDEFAULT = 362, + tPROPERTIES = 363, + tPROPGET = 364, + tPROPPUT = 365, + tPROPPUTREF = 366, + tPTR = 367, + tPUBLIC = 368, + tRANGE = 369, + tREADONLY = 370, + tREF = 371, + tREGISTER = 372, + tREQUESTEDIT = 373, + tRESTRICTED = 374, + tRETVAL = 375, + tSAFEARRAY = 376, + tSHORT = 377, + tSIGNED = 378, + tSIZEIS = 379, + tSIZEOF = 380, + tSMALL = 381, + tSOURCE = 382, + tSTATIC = 383, + tSTDCALL = 384, + tSTRICTCONTEXTHANDLE = 385, + tSTRING = 386, + tSTRUCT = 387, + tSWITCH = 388, + tSWITCHIS = 389, + tSWITCHTYPE = 390, + tTRANSMITAS = 391, + tTRUE = 392, + tTYPEDEF = 393, + tUNION = 394, + tUNIQUE = 395, + tUNSIGNED = 396, + tUUID = 397, + tV1ENUM = 398, + tVARARG = 399, + tVERSION = 400, + tVOID = 401, + tWCHAR = 402, + tWIREMARSHAL = 403, + ADDRESSOF = 404, + NEG = 405, + POS = 406, + PPTR = 407, + CAST = 408 }; #endif @@ -451,7 +454,7 @@ typedef union YYSTYPE /* Line 214 of yacc.c */ -#line 455 "parser.tab.c" +#line 458 "parser.tab.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -463,7 +466,7 @@ typedef union YYSTYPE /* Line 264 of yacc.c */ -#line 467 "parser.tab.c" +#line 470 "parser.tab.c" #ifdef short # undef short @@ -678,20 +681,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1996 +#define YYLAST 2392 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 175 +#define YYNTOKENS 178 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 88 +#define YYNNTS 99 /* YYNRULES -- Number of rules. */ -#define YYNRULES 312 +#define YYNRULES 344 /* YYNRULES -- Number of states. */ -#define YYNSTATES 547 +#define YYNSTATES 606 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 405 +#define YYMAXUTOK 408 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -702,16 +705,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 159, 2, 2, 2, 158, 151, 2, - 170, 171, 156, 155, 146, 154, 166, 157, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 148, 169, - 152, 174, 153, 147, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 162, 2, 2, 2, 161, 154, 2, + 173, 174, 159, 158, 149, 157, 169, 160, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 151, 172, + 155, 177, 156, 150, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 167, 2, 168, 150, 2, 2, 2, 2, 2, + 2, 170, 2, 171, 153, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 172, 149, 173, 160, 2, 2, 2, + 2, 2, 2, 175, 152, 176, 163, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -739,7 +742,7 @@ static const yytype_uint8 yytranslate[] = 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 161, 162, 163, 164, 165 + 145, 146, 147, 148, 164, 165, 166, 167, 168 }; #if YYDEBUG @@ -751,171 +754,187 @@ static const yytype_uint16 yyprhs[] = 25, 28, 29, 32, 35, 39, 42, 45, 48, 51, 54, 55, 58, 59, 61, 63, 66, 69, 71, 74, 76, 78, 80, 83, 86, 89, 94, 98, 102, 108, - 111, 115, 120, 121, 123, 125, 127, 131, 133, 137, - 140, 144, 148, 149, 151, 155, 157, 161, 166, 168, - 172, 173, 175, 177, 179, 181, 183, 185, 190, 195, - 197, 199, 201, 203, 205, 207, 212, 214, 216, 221, - 223, 228, 233, 235, 237, 242, 247, 252, 257, 262, - 264, 269, 271, 276, 278, 284, 286, 288, 293, 298, - 300, 302, 304, 306, 308, 310, 312, 314, 316, 318, - 323, 325, 327, 329, 331, 338, 340, 342, 344, 346, - 351, 353, 355, 357, 362, 367, 372, 377, 379, 381, - 386, 391, 393, 395, 397, 399, 401, 403, 405, 406, - 409, 414, 418, 419, 422, 424, 426, 430, 434, 436, - 442, 444, 448, 449, 451, 453, 455, 457, 459, 461, - 463, 465, 467, 469, 475, 479, 483, 487, 491, 495, - 499, 503, 507, 511, 515, 519, 523, 527, 531, 535, - 539, 543, 547, 550, 553, 556, 559, 562, 565, 569, - 573, 578, 583, 588, 592, 594, 598, 600, 602, 603, - 606, 611, 615, 618, 621, 622, 625, 628, 630, 634, - 638, 642, 645, 646, 648, 649, 651, 653, 655, 657, - 659, 661, 663, 666, 669, 671, 673, 675, 677, 679, - 681, 682, 684, 686, 689, 691, 694, 697, 699, 701, - 704, 707, 710, 716, 717, 720, 723, 726, 729, 732, - 735, 739, 742, 746, 752, 758, 759, 762, 765, 768, - 771, 778, 787, 790, 793, 796, 799, 802, 805, 811, - 813, 815, 817, 819, 821, 822, 825, 828, 832, 833, - 835, 838, 841, 844, 848, 851, 853, 855, 859, 862, - 867, 869, 873, 875, 879, 881, 883, 885, 891, 893, - 895, 897, 899, 902, 904, 907, 909, 912, 917, 922, - 928, 939, 941 + 111, 115, 120, 121, 123, 125, 129, 131, 135, 139, + 142, 146, 150, 151, 153, 157, 159, 163, 168, 170, + 174, 175, 177, 182, 184, 186, 188, 190, 192, 197, + 202, 204, 206, 208, 210, 212, 214, 219, 221, 223, + 228, 230, 235, 240, 242, 244, 249, 254, 259, 264, + 269, 271, 276, 278, 283, 285, 291, 293, 295, 300, + 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, + 325, 330, 332, 334, 336, 338, 345, 347, 349, 351, + 353, 358, 360, 362, 364, 369, 374, 379, 384, 386, + 388, 393, 398, 400, 402, 404, 406, 408, 410, 412, + 413, 416, 421, 425, 426, 429, 431, 433, 437, 441, + 443, 449, 451, 455, 456, 458, 460, 462, 464, 466, + 468, 470, 472, 474, 476, 482, 486, 490, 494, 498, + 502, 506, 510, 514, 518, 522, 526, 530, 534, 538, + 542, 546, 550, 554, 557, 560, 563, 566, 569, 572, + 576, 580, 586, 592, 597, 601, 603, 607, 609, 611, + 612, 615, 620, 624, 627, 630, 631, 634, 637, 639, + 643, 647, 651, 654, 655, 657, 658, 660, 662, 664, + 666, 668, 670, 672, 675, 678, 680, 682, 684, 686, + 688, 690, 691, 693, 695, 698, 700, 703, 706, 708, + 710, 712, 715, 718, 721, 727, 728, 731, 734, 737, + 740, 743, 746, 750, 753, 757, 763, 769, 770, 773, + 776, 779, 782, 789, 798, 801, 804, 807, 810, 813, + 816, 822, 824, 826, 828, 830, 832, 833, 836, 839, + 843, 844, 846, 849, 852, 855, 859, 862, 864, 866, + 870, 873, 878, 882, 885, 887, 891, 894, 895, 897, + 901, 904, 906, 910, 915, 919, 922, 924, 928, 931, + 932, 934, 936, 940, 943, 945, 949, 954, 956, 960, + 961, 964, 967, 969, 973, 975, 979, 981, 983, 985, + 991, 993, 995, 997, 999, 1002, 1004, 1007, 1009, 1012, + 1017, 1022, 1028, 1039, 1041 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 176, 0, -1, 177, -1, -1, 177, 242, -1, 177, - 241, -1, 177, 228, 169, -1, 177, 230, -1, 177, - 245, -1, 177, 189, -1, 177, 181, -1, -1, 178, - 242, -1, 178, 241, -1, 178, 228, 169, -1, 178, - 230, -1, 178, 245, -1, 178, 181, -1, 178, 186, - -1, 178, 189, -1, -1, 179, 181, -1, -1, 169, - -1, 183, -1, 182, 169, -1, 221, 169, -1, 185, - -1, 260, 169, -1, 207, -1, 258, -1, 261, -1, - 196, 207, -1, 196, 258, -1, 196, 261, -1, 45, - 170, 8, 171, -1, 78, 8, 169, -1, 184, 178, - 11, -1, 79, 170, 8, 171, 180, -1, 89, 3, - -1, 196, 187, 172, -1, 188, 178, 173, 180, -1, - -1, 192, -1, 143, -1, 193, -1, 192, 146, 193, - -1, 191, -1, 196, 250, 253, -1, 250, 253, -1, - 167, 209, 168, -1, 167, 156, 168, -1, -1, 196, - -1, 167, 197, 168, -1, 199, -1, 197, 146, 199, - -1, 197, 168, 167, 199, -1, 8, -1, 198, 146, - 8, -1, -1, 21, -1, 23, -1, 24, -1, 26, - -1, 27, -1, 29, -1, 32, 170, 224, 171, -1, - 34, 170, 211, 171, -1, 41, -1, 42, -1, 43, - -1, 44, -1, 46, -1, 47, -1, 48, 170, 213, - 171, -1, 49, -1, 50, -1, 52, 170, 8, 171, - -1, 54, -1, 55, 170, 198, 171, -1, 56, 170, - 213, 171, -1, 59, -1, 64, -1, 66, 170, 212, - 171, -1, 67, 170, 8, 171, -1, 68, 170, 8, - 171, -1, 69, 170, 212, 171, -1, 70, 170, 8, - 171, -1, 71, -1, 73, 170, 212, 171, -1, 74, - -1, 75, 170, 210, 171, -1, 76, -1, 77, 170, - 65, 3, 171, -1, 80, -1, 83, -1, 88, 170, - 208, 171, -1, 87, 170, 212, 171, -1, 87, -1, - 90, -1, 94, -1, 95, -1, 96, -1, 98, -1, - 99, -1, 100, -1, 101, -1, 102, -1, 104, 170, - 257, 171, -1, 106, -1, 107, -1, 108, -1, 110, - -1, 111, 170, 212, 146, 212, 171, -1, 112, -1, - 115, -1, 116, -1, 117, -1, 121, 170, 208, 171, - -1, 124, -1, 127, -1, 128, -1, 131, 170, 210, - 171, -1, 132, 170, 259, 171, -1, 133, 170, 259, - 171, -1, 139, 170, 200, 171, -1, 140, -1, 141, - -1, 142, 170, 262, 171, -1, 145, 170, 259, 171, - -1, 257, -1, 10, -1, 8, -1, 35, -1, 62, - -1, 103, -1, 126, -1, -1, 202, 203, -1, 34, - 212, 148, 218, -1, 46, 148, 218, -1, -1, 205, - 146, -1, 205, -1, 206, -1, 205, 146, 206, -1, - 224, 174, 212, -1, 224, -1, 57, 223, 172, 204, - 173, -1, 209, -1, 208, 146, 209, -1, -1, 210, - -1, 5, -1, 6, -1, 7, -1, 61, -1, 97, - -1, 134, -1, 8, -1, 9, -1, 3, -1, 210, - 147, 210, 148, 210, -1, 210, 19, 210, -1, 210, - 20, 210, -1, 210, 149, 210, -1, 210, 150, 210, - -1, 210, 151, 210, -1, 210, 15, 210, -1, 210, - 16, 210, -1, 210, 153, 210, -1, 210, 152, 210, - -1, 210, 17, 210, -1, 210, 18, 210, -1, 210, - 12, 210, -1, 210, 13, 210, -1, 210, 155, 210, - -1, 210, 154, 210, -1, 210, 158, 210, -1, 210, - 156, 210, -1, 210, 157, 210, -1, 159, 210, -1, - 160, 210, -1, 155, 210, -1, 154, 210, -1, 151, - 210, -1, 156, 210, -1, 210, 14, 3, -1, 210, - 166, 3, -1, 170, 259, 171, 210, -1, 122, 170, - 259, 171, -1, 210, 167, 210, 168, -1, 170, 210, - 171, -1, 212, -1, 211, 146, 212, -1, 210, -1, - 210, -1, -1, 214, 215, -1, 195, 250, 255, 169, - -1, 195, 261, 169, -1, 219, 169, -1, 196, 169, - -1, -1, 217, 216, -1, 219, 169, -1, 169, -1, - 195, 250, 253, -1, 195, 250, 253, -1, 196, 250, - 256, -1, 250, 256, -1, -1, 224, -1, -1, 3, - -1, 4, -1, 3, -1, 4, -1, 30, -1, 144, - -1, 227, -1, 120, 227, -1, 138, 227, -1, 138, - -1, 63, -1, 53, -1, 28, -1, 58, -1, 65, - -1, -1, 84, -1, 84, -1, 119, 226, -1, 123, - -1, 91, 226, -1, 72, 226, -1, 85, -1, 36, - -1, 37, 3, -1, 37, 4, -1, 196, 228, -1, - 229, 172, 231, 173, 180, -1, -1, 231, 232, -1, - 195, 242, -1, 51, 3, -1, 51, 4, -1, 196, - 233, -1, 105, 148, -1, 235, 219, 169, -1, 92, - 148, -1, 236, 220, 169, -1, 234, 172, 235, 236, - 173, -1, 234, 172, 239, 169, 173, -1, -1, 148, - 4, -1, 86, 3, -1, 86, 4, -1, 196, 239, - -1, 240, 238, 172, 179, 173, 180, -1, 240, 148, - 3, 172, 185, 179, 173, 180, -1, 237, 180, -1, - 239, 169, -1, 233, 169, -1, 93, 3, -1, 93, - 4, -1, 196, 243, -1, 244, 172, 179, 173, 180, - -1, 60, -1, 125, -1, 114, -1, 82, -1, 40, - -1, -1, 249, 248, -1, 259, 251, -1, 252, 259, - 251, -1, -1, 252, -1, 248, 251, -1, 247, 251, - -1, 246, 251, -1, 156, 249, 253, -1, 201, 253, - -1, 254, -1, 224, -1, 170, 253, 171, -1, 254, - 194, -1, 254, 170, 190, 171, -1, 253, -1, 255, - 146, 253, -1, 253, -1, 253, 174, 213, -1, 113, - -1, 137, -1, 109, -1, 129, 223, 172, 214, 173, - -1, 143, -1, 4, -1, 225, -1, 207, -1, 57, - 3, -1, 258, -1, 129, 3, -1, 261, -1, 136, - 3, -1, 118, 170, 259, 171, -1, 135, 195, 250, - 255, -1, 136, 223, 172, 217, 173, -1, 136, 223, - 130, 170, 219, 171, 222, 172, 202, 173, -1, 5, - -1, 5, 166, 5, -1 + 179, 0, -1, 180, -1, -1, 180, 245, -1, 180, + 244, -1, 180, 231, 172, -1, 180, 233, -1, 180, + 248, -1, 180, 192, -1, 180, 184, -1, -1, 181, + 245, -1, 181, 244, -1, 181, 231, 172, -1, 181, + 233, -1, 181, 248, -1, 181, 184, -1, 181, 189, + -1, 181, 192, -1, -1, 182, 184, -1, -1, 172, + -1, 186, -1, 185, 172, -1, 224, 172, -1, 188, + -1, 274, 172, -1, 210, -1, 272, -1, 275, -1, + 199, 210, -1, 199, 272, -1, 199, 275, -1, 47, + 173, 8, 174, -1, 80, 8, 172, -1, 187, 181, + 11, -1, 81, 173, 8, 174, 183, -1, 92, 3, + -1, 199, 190, 175, -1, 191, 181, 176, 183, -1, + -1, 195, -1, 196, -1, 194, 149, 196, -1, 194, + -1, 194, 149, 21, -1, 199, 253, 264, -1, 253, + 264, -1, 170, 212, 171, -1, 170, 159, 171, -1, + -1, 199, -1, 170, 200, 171, -1, 202, -1, 200, + 149, 202, -1, 200, 171, 170, 202, -1, 8, -1, + 201, 149, 8, -1, -1, 22, -1, 24, 173, 8, + 174, -1, 25, -1, 26, -1, 28, -1, 29, -1, + 31, -1, 34, 173, 227, 174, -1, 36, 173, 214, + 174, -1, 43, -1, 44, -1, 45, -1, 46, -1, + 48, -1, 49, -1, 50, 173, 216, 174, -1, 51, + -1, 52, -1, 54, 173, 8, 174, -1, 56, -1, + 57, 173, 201, 174, -1, 58, 173, 216, 174, -1, + 61, -1, 66, -1, 68, 173, 215, 174, -1, 69, + 173, 8, 174, -1, 70, 173, 8, 174, -1, 71, + 173, 215, 174, -1, 72, 173, 8, 174, -1, 73, + -1, 75, 173, 215, 174, -1, 76, -1, 77, 173, + 213, 174, -1, 78, -1, 79, 173, 67, 3, 174, + -1, 82, -1, 85, -1, 91, 173, 211, 174, -1, + 90, 173, 215, 174, -1, 90, -1, 93, -1, 97, + -1, 98, -1, 99, -1, 101, -1, 102, -1, 103, + -1, 104, -1, 105, -1, 107, 173, 271, 174, -1, + 109, -1, 110, -1, 111, -1, 113, -1, 114, 173, + 215, 149, 215, 174, -1, 115, -1, 118, -1, 119, + -1, 120, -1, 124, 173, 211, 174, -1, 127, -1, + 130, -1, 131, -1, 134, 173, 213, 174, -1, 135, + 173, 273, 174, -1, 136, 173, 273, 174, -1, 142, + 173, 203, 174, -1, 143, -1, 144, -1, 145, 173, + 276, 174, -1, 148, 173, 273, 174, -1, 271, -1, + 10, -1, 8, -1, 37, -1, 64, -1, 106, -1, + 129, -1, -1, 205, 206, -1, 36, 215, 151, 221, + -1, 48, 151, 221, -1, -1, 208, 149, -1, 208, + -1, 209, -1, 208, 149, 209, -1, 227, 177, 215, + -1, 227, -1, 59, 226, 175, 207, 176, -1, 212, + -1, 211, 149, 212, -1, -1, 213, -1, 5, -1, + 6, -1, 7, -1, 63, -1, 100, -1, 137, -1, + 8, -1, 9, -1, 3, -1, 213, 150, 213, 151, + 213, -1, 213, 19, 213, -1, 213, 20, 213, -1, + 213, 152, 213, -1, 213, 153, 213, -1, 213, 154, + 213, -1, 213, 15, 213, -1, 213, 16, 213, -1, + 213, 156, 213, -1, 213, 155, 213, -1, 213, 17, + 213, -1, 213, 18, 213, -1, 213, 12, 213, -1, + 213, 13, 213, -1, 213, 158, 213, -1, 213, 157, + 213, -1, 213, 161, 213, -1, 213, 159, 213, -1, + 213, 160, 213, -1, 162, 213, -1, 163, 213, -1, + 158, 213, -1, 157, 213, -1, 154, 213, -1, 159, + 213, -1, 213, 14, 3, -1, 213, 169, 3, -1, + 173, 253, 260, 174, 213, -1, 125, 173, 253, 260, + 174, -1, 213, 170, 213, 171, -1, 173, 213, 174, + -1, 215, -1, 214, 149, 215, -1, 213, -1, 213, + -1, -1, 217, 218, -1, 198, 253, 269, 172, -1, + 198, 275, 172, -1, 222, 172, -1, 199, 172, -1, + -1, 220, 219, -1, 222, 172, -1, 172, -1, 198, + 253, 256, -1, 198, 253, 256, -1, 199, 253, 270, + -1, 253, 270, -1, -1, 227, -1, -1, 3, -1, + 4, -1, 3, -1, 4, -1, 32, -1, 147, -1, + 230, -1, 123, 230, -1, 141, 230, -1, 141, -1, + 65, -1, 55, -1, 30, -1, 60, -1, 67, -1, + -1, 86, -1, 86, -1, 122, 229, -1, 126, -1, + 94, 229, -1, 74, 229, -1, 88, -1, 38, -1, + 87, -1, 39, 3, -1, 39, 4, -1, 199, 231, + -1, 232, 175, 234, 176, 183, -1, -1, 234, 235, + -1, 198, 245, -1, 53, 3, -1, 53, 4, -1, + 199, 236, -1, 108, 151, -1, 238, 222, 172, -1, + 95, 151, -1, 239, 223, 172, -1, 237, 175, 238, + 239, 176, -1, 237, 175, 242, 172, 176, -1, -1, + 151, 4, -1, 89, 3, -1, 89, 4, -1, 199, + 242, -1, 243, 241, 175, 182, 176, 183, -1, 243, + 151, 3, 175, 188, 182, 176, 183, -1, 240, 183, + -1, 242, 172, -1, 236, 172, -1, 96, 3, -1, + 96, 4, -1, 199, 246, -1, 247, 175, 182, 176, + 183, -1, 62, -1, 128, -1, 117, -1, 84, -1, + 42, -1, -1, 252, 251, -1, 273, 254, -1, 255, + 273, 254, -1, -1, 255, -1, 251, 254, -1, 250, + 254, -1, 249, 254, -1, 159, 252, 256, -1, 204, + 256, -1, 257, -1, 227, -1, 173, 256, 174, -1, + 257, 197, -1, 257, 173, 193, 174, -1, 159, 252, + 260, -1, 204, 260, -1, 261, -1, 159, 252, 264, + -1, 204, 264, -1, -1, 258, -1, 173, 259, 174, + -1, 261, 197, -1, 197, -1, 173, 193, 174, -1, + 261, 173, 193, 174, -1, 159, 252, 264, -1, 204, + 264, -1, 265, -1, 159, 252, 264, -1, 204, 264, + -1, -1, 262, -1, 227, -1, 173, 263, 174, -1, + 265, 197, -1, 197, -1, 173, 193, 174, -1, 265, + 173, 193, 174, -1, 256, -1, 266, 149, 256, -1, + -1, 151, 216, -1, 262, 267, -1, 268, -1, 269, + 149, 268, -1, 256, -1, 256, 177, 216, -1, 116, + -1, 140, -1, 112, -1, 132, 226, 175, 217, 176, + -1, 146, -1, 4, -1, 228, -1, 210, -1, 59, + 3, -1, 272, -1, 132, 3, -1, 275, -1, 139, + 3, -1, 121, 173, 273, 174, -1, 138, 198, 253, + 266, -1, 139, 226, 175, 220, 176, -1, 139, 226, + 133, 173, 222, 174, 225, 175, 205, 176, -1, 5, + -1, 5, 169, 5, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 326, 326, 339, 340, 341, 342, 345, 348, 349, - 350, 353, 354, 355, 356, 357, 360, 361, 362, 363, - 366, 367, 370, 371, 375, 376, 377, 378, 379, 383, - 384, 385, 386, 387, 388, 391, 393, 401, 407, 411, - 413, 417, 424, 425, 428, 431, 432, 433, 437, 444, - 452, 453, 456, 457, 461, 464, 465, 466, 469, 470, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, - 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, - 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, - 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 531, 532, 533, 534, 535, - 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, - 546, 547, 551, 552, 557, 558, 559, 560, 563, 564, - 567, 571, 577, 578, 579, 582, 586, 595, 599, 604, - 607, 608, 621, 622, 625, 626, 627, 628, 629, 630, - 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, - 661, 662, 663, 664, 667, 668, 671, 677, 683, 684, - 687, 692, 699, 700, 703, 704, 708, 709, 712, 720, - 729, 735, 741, 742, 745, 746, 747, 750, 752, 755, - 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, - 768, 769, 772, 773, 774, 775, 776, 777, 778, 781, - 782, 790, 796, 800, 801, 805, 808, 809, 812, 822, - 823, 826, 827, 830, 836, 842, 843, 846, 847, 850, - 861, 868, 874, 878, 879, 882, 883, 886, 891, 898, - 899, 900, 904, 908, 911, 912, 915, 916, 920, 921, - 925, 926, 927, 931, 933, 934, 938, 939, 940, 941, - 948, 949, 953, 954, 958, 959, 960, 963, 966, 967, - 968, 969, 970, 971, 972, 973, 974, 975, 978, 984, - 986, 992, 993 + 0, 330, 330, 343, 344, 345, 346, 349, 352, 353, + 354, 357, 358, 359, 360, 361, 364, 365, 366, 367, + 370, 371, 374, 375, 379, 380, 381, 382, 383, 387, + 388, 389, 390, 391, 392, 395, 397, 405, 411, 415, + 417, 421, 428, 429, 432, 433, 436, 437, 441, 446, + 453, 454, 457, 458, 462, 465, 466, 467, 470, 471, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, + 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, + 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, + 524, 525, 526, 527, 528, 529, 533, 534, 535, 536, + 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, + 547, 548, 549, 553, 554, 559, 560, 561, 562, 565, + 566, 569, 573, 579, 580, 581, 584, 588, 597, 601, + 606, 609, 610, 623, 624, 627, 628, 629, 630, 631, + 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, + 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, + 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, + 662, 663, 665, 667, 668, 671, 672, 675, 681, 687, + 688, 691, 696, 703, 704, 707, 708, 712, 713, 716, + 723, 732, 736, 741, 742, 745, 746, 747, 750, 752, + 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, + 765, 768, 769, 772, 773, 774, 775, 776, 777, 778, + 779, 782, 783, 791, 797, 801, 802, 806, 809, 810, + 813, 823, 824, 827, 828, 831, 837, 843, 844, 847, + 848, 851, 862, 869, 875, 879, 880, 883, 884, 887, + 892, 899, 900, 901, 905, 909, 912, 913, 916, 917, + 921, 922, 926, 927, 928, 932, 934, 935, 939, 940, + 941, 942, 950, 952, 953, 958, 960, 964, 965, 970, + 971, 972, 973, 978, 987, 989, 990, 995, 997, 1001, + 1002, 1009, 1010, 1011, 1012, 1013, 1018, 1026, 1027, 1030, + 1031, 1034, 1041, 1042, 1047, 1048, 1052, 1053, 1054, 1057, + 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, + 1072, 1078, 1080, 1086, 1087 }; #endif @@ -927,12 +946,13 @@ static const char *const yytname[] = "$end", "error", "$undefined", "aIDENTIFIER", "aKNOWNTYPE", "aNUM", "aHEXNUM", "aDOUBLE", "aSTRING", "aWSTRING", "aUUID", "aEOF", "SHL", "SHR", "MEMBERPTR", "EQUALITY", "INEQUALITY", "GREATEREQUAL", - "LESSEQUAL", "LOGICALOR", "LOGICALAND", "tAGGREGATABLE", "tALLOCATE", - "tAPPOBJECT", "tASYNC", "tASYNCUUID", "tAUTOHANDLE", "tBINDABLE", - "tBOOLEAN", "tBROADCAST", "tBYTE", "tBYTECOUNT", "tCALLAS", "tCALLBACK", - "tCASE", "tCDECL", "tCHAR", "tCOCLASS", "tCODE", "tCOMMSTATUS", "tCONST", - "tCONTEXTHANDLE", "tCONTEXTHANDLENOSERIALIZE", "tCONTEXTHANDLESERIALIZE", - "tCONTROL", "tCPPQUOTE", "tDEFAULT", "tDEFAULTCOLLELEM", "tDEFAULTVALUE", + "LESSEQUAL", "LOGICALOR", "LOGICALAND", "ELLIPSIS", "tAGGREGATABLE", + "tALLOCATE", "tANNOTATION", "tAPPOBJECT", "tASYNC", "tASYNCUUID", + "tAUTOHANDLE", "tBINDABLE", "tBOOLEAN", "tBROADCAST", "tBYTE", + "tBYTECOUNT", "tCALLAS", "tCALLBACK", "tCASE", "tCDECL", "tCHAR", + "tCOCLASS", "tCODE", "tCOMMSTATUS", "tCONST", "tCONTEXTHANDLE", + "tCONTEXTHANDLENOSERIALIZE", "tCONTEXTHANDLESERIALIZE", "tCONTROL", + "tCPPQUOTE", "tDEFAULT", "tDEFAULTCOLLELEM", "tDEFAULTVALUE", "tDEFAULTVTABLE", "tDISPLAYBIND", "tDISPINTERFACE", "tDLLNAME", "tDOUBLE", "tDUAL", "tENDPOINT", "tENTRY", "tENUM", "tERRORSTATUST", "tEXPLICITHANDLE", "tEXTERN", "tFALSE", "tFASTCALL", "tFLOAT", "tHANDLE", @@ -940,38 +960,42 @@ static const char *const yytname[] = "tHELPSTRINGCONTEXT", "tHELPSTRINGDLL", "tHIDDEN", "tHYPER", "tID", "tIDEMPOTENT", "tIIDIS", "tIMMEDIATEBIND", "tIMPLICITHANDLE", "tIMPORT", "tIMPORTLIB", "tIN", "tIN_LINE", "tINLINE", "tINPUTSYNC", "tINT", - "tINT64", "tINTERFACE", "tLCID", "tLENGTHIS", "tLIBRARY", "tLOCAL", - "tLONG", "tMETHODS", "tMODULE", "tNONBROWSABLE", "tNONCREATABLE", - "tNONEXTENSIBLE", "tNULL", "tOBJECT", "tODL", "tOLEAUTOMATION", - "tOPTIONAL", "tOUT", "tPASCAL", "tPOINTERDEFAULT", "tPROPERTIES", - "tPROPGET", "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", "tRANGE", - "tREADONLY", "tREF", "tREGISTER", "tREQUESTEDIT", "tRESTRICTED", - "tRETVAL", "tSAFEARRAY", "tSHORT", "tSIGNED", "tSIZEIS", "tSIZEOF", - "tSMALL", "tSOURCE", "tSTATIC", "tSTDCALL", "tSTRICTCONTEXTHANDLE", - "tSTRING", "tSTRUCT", "tSWITCH", "tSWITCHIS", "tSWITCHTYPE", - "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION", "tUNIQUE", "tUNSIGNED", - "tUUID", "tV1ENUM", "tVARARG", "tVERSION", "tVOID", "tWCHAR", - "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'^'", "'&'", "'<'", "'>'", - "'-'", "'+'", "'*'", "'/'", "'%'", "'!'", "'~'", "ADDRESSOF", "NEG", - "POS", "PPTR", "CAST", "'.'", "'['", "']'", "';'", "'('", "')'", "'{'", - "'}'", "'='", "$accept", "input", "gbl_statements", "imp_statements", - "int_statements", "semicolon_opt", "statement", "typedecl", "cppquote", - "import_start", "import", "importlib", "libraryhdr", "library_start", - "librarydef", "m_args", "no_args", "args", "arg", "array", - "m_attributes", "attributes", "attrib_list", "str_list", "attribute", - "uuid_string", "callconv", "cases", "case", "enums", "enum_list", "enum", - "enumdef", "m_exprs", "m_expr", "expr", "expr_list_int_const", - "expr_int_const", "expr_const", "fields", "field", "ne_union_field", - "ne_union_fields", "union_field", "s_field", "funcdef", "declaration", - "m_ident", "t_ident", "ident", "base_type", "m_int", "int_std", - "coclass", "coclasshdr", "coclassdef", "coclass_ints", "coclass_int", - "dispinterface", "dispinterfacehdr", "dispint_props", "dispint_meths", - "dispinterfacedef", "inherit", "interface", "interfacehdr", - "interfacedef", "interfacedec", "module", "modulehdr", "moduledef", - "storage_cls_spec", "function_specifier", "type_qualifier", + "tINT3264", "tINT64", "tINTERFACE", "tLCID", "tLENGTHIS", "tLIBRARY", + "tLOCAL", "tLONG", "tMETHODS", "tMODULE", "tNONBROWSABLE", + "tNONCREATABLE", "tNONEXTENSIBLE", "tNULL", "tOBJECT", "tODL", + "tOLEAUTOMATION", "tOPTIONAL", "tOUT", "tPASCAL", "tPOINTERDEFAULT", + "tPROPERTIES", "tPROPGET", "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", + "tRANGE", "tREADONLY", "tREF", "tREGISTER", "tREQUESTEDIT", + "tRESTRICTED", "tRETVAL", "tSAFEARRAY", "tSHORT", "tSIGNED", "tSIZEIS", + "tSIZEOF", "tSMALL", "tSOURCE", "tSTATIC", "tSTDCALL", + "tSTRICTCONTEXTHANDLE", "tSTRING", "tSTRUCT", "tSWITCH", "tSWITCHIS", + "tSWITCHTYPE", "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION", "tUNIQUE", + "tUNSIGNED", "tUUID", "tV1ENUM", "tVARARG", "tVERSION", "tVOID", + "tWCHAR", "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'^'", "'&'", + "'<'", "'>'", "'-'", "'+'", "'*'", "'/'", "'%'", "'!'", "'~'", + "ADDRESSOF", "NEG", "POS", "PPTR", "CAST", "'.'", "'['", "']'", "';'", + "'('", "')'", "'{'", "'}'", "'='", "$accept", "input", "gbl_statements", + "imp_statements", "int_statements", "semicolon_opt", "statement", + "typedecl", "cppquote", "import_start", "import", "importlib", + "libraryhdr", "library_start", "librarydef", "m_args", "arg_list", + "args", "arg", "array", "m_attributes", "attributes", "attrib_list", + "str_list", "attribute", "uuid_string", "callconv", "cases", "case", + "enums", "enum_list", "enum", "enumdef", "m_exprs", "m_expr", "expr", + "expr_list_int_const", "expr_int_const", "expr_const", "fields", "field", + "ne_union_field", "ne_union_fields", "union_field", "s_field", "funcdef", + "declaration", "m_ident", "t_ident", "ident", "base_type", "m_int", + "int_std", "coclass", "coclasshdr", "coclassdef", "coclass_ints", + "coclass_int", "dispinterface", "dispinterfacehdr", "dispint_props", + "dispint_meths", "dispinterfacedef", "inherit", "interface", + "interfacehdr", "interfacedef", "interfacedec", "module", "modulehdr", + "moduledef", "storage_cls_spec", "function_specifier", "type_qualifier", "m_type_qual_list", "decl_spec", "m_decl_spec_no_type", "decl_spec_no_type", "declarator", "direct_declarator", - "declarator_list", "init_declarator", "pointer_type", "structdef", + "abstract_declarator", "abstract_declarator_no_direct", + "m_abstract_declarator", "abstract_direct_declarator", "any_declarator", + "any_declarator_no_direct", "m_any_declarator", "any_direct_declarator", + "declarator_list", "m_bitfield", "struct_declarator", + "struct_declarator_list", "init_declarator", "pointer_type", "structdef", "type", "typedef", "uniondef", "version", 0 }; #endif @@ -995,48 +1019,51 @@ static const yytype_uint16 yytoknum[] = 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 44, 63, 58, 124, - 94, 38, 60, 62, 45, 43, 42, 47, 37, 33, - 126, 401, 402, 403, 404, 405, 46, 91, 93, 59, - 40, 41, 123, 125, 61 + 395, 396, 397, 398, 399, 400, 401, 402, 403, 44, + 63, 58, 124, 94, 38, 60, 62, 45, 43, 42, + 47, 37, 33, 126, 404, 405, 406, 407, 408, 46, + 91, 93, 59, 40, 41, 123, 125, 61 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 175, 176, 177, 177, 177, 177, 177, 177, 177, - 177, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 179, 179, 180, 180, 181, 181, 181, 181, 181, 182, - 182, 182, 182, 182, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 190, 191, 192, 192, 192, 193, 193, - 194, 194, 195, 195, 196, 197, 197, 197, 198, 198, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - 199, 199, 200, 200, 201, 201, 201, 201, 202, 202, - 203, 203, 204, 204, 204, 205, 205, 206, 206, 207, - 208, 208, 209, 209, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 211, 211, 212, 213, 214, 214, - 215, 215, 216, 216, 217, 217, 218, 218, 219, 220, - 221, 221, 222, 222, 223, 223, 223, 224, 224, 225, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 226, 226, 227, 227, 227, 227, 227, 227, 227, 228, - 228, 229, 230, 231, 231, 232, 233, 233, 234, 235, - 235, 236, 236, 237, 237, 238, 238, 239, 239, 240, - 241, 241, 241, 242, 242, 243, 243, 244, 245, 246, - 246, 246, 247, 248, 249, 249, 250, 250, 251, 251, - 252, 252, 252, 253, 253, 253, 254, 254, 254, 254, - 255, 255, 256, 256, 257, 257, 257, 258, 259, 259, - 259, 259, 259, 259, 259, 259, 259, 259, 260, 261, - 261, 262, 262 + 0, 178, 179, 180, 180, 180, 180, 180, 180, 180, + 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 182, 182, 183, 183, 184, 184, 184, 184, 184, 185, + 185, 185, 185, 185, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 193, 194, 194, 195, 195, 196, 196, + 197, 197, 198, 198, 199, 200, 200, 200, 201, 201, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 203, 203, 204, 204, 204, 204, 205, + 205, 206, 206, 207, 207, 207, 208, 208, 209, 209, + 210, 211, 211, 212, 212, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 214, 214, 215, 216, 217, + 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, + 223, 224, 224, 225, 225, 226, 226, 226, 227, 227, + 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, + 228, 229, 229, 230, 230, 230, 230, 230, 230, 230, + 230, 231, 231, 232, 233, 234, 234, 235, 236, 236, + 237, 238, 238, 239, 239, 240, 240, 241, 241, 242, + 242, 243, 244, 244, 244, 245, 245, 246, 246, 247, + 248, 249, 249, 249, 250, 251, 252, 252, 253, 253, + 254, 254, 255, 255, 255, 256, 256, 256, 257, 257, + 257, 257, 258, 258, 258, 259, 259, 260, 260, 261, + 261, 261, 261, 261, 262, 262, 262, 263, 263, 264, + 264, 265, 265, 265, 265, 265, 265, 266, 266, 267, + 267, 268, 269, 269, 270, 270, 271, 271, 271, 272, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, + 274, 275, 275, 276, 276 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -1046,34 +1073,37 @@ static const yytype_uint8 yyr2[] = 2, 0, 2, 2, 3, 2, 2, 2, 2, 2, 0, 2, 0, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 2, 2, 4, 3, 3, 5, 2, - 3, 4, 0, 1, 1, 1, 3, 1, 3, 2, + 3, 4, 0, 1, 1, 3, 1, 3, 3, 2, 3, 3, 0, 1, 3, 1, 3, 4, 1, 3, - 0, 1, 1, 1, 1, 1, 1, 4, 4, 1, - 1, 1, 1, 1, 1, 4, 1, 1, 4, 1, - 4, 4, 1, 1, 4, 4, 4, 4, 4, 1, - 4, 1, 4, 1, 5, 1, 1, 4, 4, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, - 1, 1, 1, 1, 6, 1, 1, 1, 1, 4, - 1, 1, 1, 4, 4, 4, 4, 1, 1, 4, - 4, 1, 1, 1, 1, 1, 1, 1, 0, 2, - 4, 3, 0, 2, 1, 1, 3, 3, 1, 5, - 1, 3, 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 5, 3, 3, 3, 3, 3, 3, + 0, 1, 4, 1, 1, 1, 1, 1, 4, 4, + 1, 1, 1, 1, 1, 1, 4, 1, 1, 4, + 1, 4, 4, 1, 1, 4, 4, 4, 4, 4, + 1, 4, 1, 4, 1, 5, 1, 1, 4, 4, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 1, 1, 1, 1, 6, 1, 1, 1, 1, + 4, 1, 1, 1, 4, 4, 4, 4, 1, 1, + 4, 4, 1, 1, 1, 1, 1, 1, 1, 0, + 2, 4, 3, 0, 2, 1, 1, 3, 3, 1, + 5, 1, 3, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, - 4, 4, 4, 3, 1, 3, 1, 1, 0, 2, - 4, 3, 2, 2, 0, 2, 2, 1, 3, 3, - 3, 2, 0, 1, 0, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 2, 1, 2, 2, 1, 1, 2, - 2, 2, 5, 0, 2, 2, 2, 2, 2, 2, - 3, 2, 3, 5, 5, 0, 2, 2, 2, 2, - 6, 8, 2, 2, 2, 2, 2, 2, 5, 1, - 1, 1, 1, 1, 0, 2, 2, 3, 0, 1, - 2, 2, 2, 3, 2, 1, 1, 3, 2, 4, - 1, 3, 1, 3, 1, 1, 1, 5, 1, 1, - 1, 1, 2, 1, 2, 1, 2, 4, 4, 5, - 10, 1, 3 + 3, 3, 3, 2, 2, 2, 2, 2, 2, 3, + 3, 5, 5, 4, 3, 1, 3, 1, 1, 0, + 2, 4, 3, 2, 2, 0, 2, 2, 1, 3, + 3, 3, 2, 0, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 2, 1, 2, 2, 1, 1, + 1, 2, 2, 2, 5, 0, 2, 2, 2, 2, + 2, 2, 3, 2, 3, 5, 5, 0, 2, 2, + 2, 2, 6, 8, 2, 2, 2, 2, 2, 2, + 5, 1, 1, 1, 1, 1, 0, 2, 2, 3, + 0, 1, 2, 2, 2, 3, 2, 1, 1, 3, + 2, 4, 3, 2, 1, 3, 2, 0, 1, 3, + 2, 1, 3, 4, 3, 2, 1, 3, 2, 0, + 1, 1, 3, 2, 1, 3, 4, 1, 3, 0, + 2, 2, 1, 3, 1, 3, 1, 1, 1, 5, + 1, 1, 1, 1, 2, 1, 2, 1, 2, 4, + 4, 5, 10, 1, 3 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -1081,625 +1111,725 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 3, 0, 2, 1, 299, 227, 219, 238, 0, 273, - 0, 0, 226, 214, 228, 269, 225, 229, 230, 0, - 272, 232, 237, 0, 230, 271, 0, 230, 0, 234, - 270, 214, 52, 214, 224, 298, 220, 60, 10, 0, - 24, 11, 27, 11, 9, 0, 301, 0, 300, 221, - 0, 0, 7, 0, 0, 22, 0, 255, 5, 4, - 0, 8, 278, 278, 278, 0, 0, 303, 278, 0, - 305, 239, 240, 0, 246, 247, 302, 216, 0, 231, - 236, 0, 257, 258, 235, 0, 233, 222, 304, 0, - 0, 53, 306, 0, 223, 61, 62, 63, 64, 65, - 66, 0, 0, 69, 70, 71, 72, 73, 74, 0, - 76, 77, 0, 79, 0, 0, 82, 83, 0, 0, - 0, 0, 0, 89, 0, 91, 0, 93, 0, 95, - 96, 99, 0, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 0, 110, 111, 112, 296, 113, 0, 115, - 294, 116, 117, 118, 0, 120, 121, 122, 0, 0, - 0, 295, 0, 127, 128, 0, 0, 0, 55, 131, - 25, 0, 0, 0, 0, 0, 301, 241, 248, 259, - 267, 0, 303, 305, 26, 6, 243, 264, 0, 23, - 262, 263, 0, 0, 20, 282, 279, 281, 280, 217, - 218, 134, 135, 136, 137, 274, 0, 0, 286, 292, - 285, 211, 301, 303, 278, 305, 276, 28, 0, 142, - 36, 0, 198, 0, 0, 204, 0, 0, 0, 0, + 3, 0, 2, 1, 331, 228, 220, 239, 0, 275, + 0, 0, 227, 215, 229, 271, 226, 230, 231, 0, + 274, 233, 240, 238, 0, 231, 273, 0, 231, 0, + 235, 272, 215, 52, 215, 225, 330, 221, 60, 10, + 0, 24, 11, 27, 11, 9, 0, 333, 0, 332, + 222, 0, 0, 7, 0, 0, 22, 0, 257, 5, + 4, 0, 8, 280, 280, 280, 0, 0, 335, 280, + 0, 337, 241, 242, 0, 248, 249, 334, 217, 0, + 232, 237, 0, 259, 260, 236, 0, 234, 223, 336, + 0, 0, 53, 338, 0, 224, 61, 0, 63, 64, + 65, 66, 67, 0, 0, 70, 71, 72, 73, 74, + 75, 0, 77, 78, 0, 80, 0, 0, 83, 84, + 0, 0, 0, 0, 0, 90, 0, 92, 0, 94, + 0, 96, 97, 100, 0, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 0, 111, 112, 113, 328, 114, + 0, 116, 326, 117, 118, 119, 0, 121, 122, 123, + 0, 0, 0, 327, 0, 128, 129, 0, 0, 0, + 55, 132, 25, 0, 0, 0, 0, 0, 333, 243, + 250, 261, 269, 0, 335, 337, 26, 6, 245, 266, + 0, 23, 264, 265, 0, 0, 20, 284, 281, 283, + 282, 218, 219, 135, 136, 137, 138, 276, 0, 0, + 288, 324, 287, 212, 333, 335, 280, 337, 278, 28, + 0, 143, 36, 0, 199, 0, 0, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 152, 0, 0, 152, 0, 0, 0, 0, 0, - 0, 60, 54, 37, 0, 17, 18, 19, 0, 15, - 13, 12, 16, 22, 39, 265, 266, 40, 210, 52, - 0, 52, 0, 0, 256, 20, 0, 0, 0, 284, - 0, 152, 42, 288, 277, 35, 0, 144, 145, 148, - 307, 52, 290, 308, 52, 52, 0, 162, 154, 155, - 156, 160, 161, 157, 158, 0, 159, 0, 0, 0, - 0, 0, 0, 0, 196, 0, 194, 197, 0, 0, - 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 150, 153, 0, 0, 0, 0, 0, - 0, 133, 132, 0, 311, 0, 0, 56, 60, 0, - 14, 41, 22, 0, 244, 249, 0, 0, 0, 52, - 0, 0, 0, 22, 21, 0, 275, 283, 287, 293, - 0, 0, 298, 0, 47, 43, 45, 0, 0, 149, - 143, 0, 297, 0, 199, 0, 0, 309, 53, 205, - 0, 67, 0, 186, 185, 184, 187, 182, 183, 0, + 0, 0, 0, 0, 153, 0, 0, 153, 0, 0, + 0, 0, 0, 0, 60, 54, 37, 0, 17, 18, + 19, 0, 15, 13, 12, 16, 22, 39, 267, 268, + 40, 211, 52, 0, 52, 0, 0, 258, 20, 0, + 0, 0, 286, 0, 153, 42, 290, 279, 35, 0, + 145, 146, 149, 339, 52, 317, 340, 52, 52, 0, + 0, 163, 155, 156, 157, 161, 162, 158, 159, 0, + 160, 0, 0, 0, 0, 0, 0, 0, 197, 0, + 195, 198, 0, 0, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 151, 154, 0, + 0, 0, 0, 0, 0, 134, 133, 0, 343, 0, + 0, 56, 60, 0, 14, 41, 22, 0, 246, 251, + 0, 0, 0, 52, 0, 0, 0, 22, 21, 0, + 277, 285, 289, 325, 0, 0, 0, 46, 43, 44, + 0, 309, 150, 144, 0, 329, 0, 200, 0, 0, + 341, 53, 206, 0, 62, 68, 0, 187, 186, 185, + 188, 183, 184, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 68, 75, 78, 0, 80, 81, - 84, 85, 86, 87, 88, 90, 92, 0, 98, 152, - 97, 109, 0, 119, 123, 124, 125, 126, 0, 129, - 130, 57, 0, 242, 245, 251, 0, 250, 253, 0, - 0, 254, 20, 22, 268, 51, 50, 289, 0, 0, - 49, 146, 147, 0, 305, 291, 212, 203, 202, 0, - 193, 0, 175, 176, 188, 169, 170, 173, 174, 164, - 165, 0, 166, 167, 168, 172, 171, 178, 177, 180, - 181, 179, 189, 0, 195, 59, 94, 151, 0, 312, - 22, 208, 0, 252, 0, 260, 46, 48, 0, 201, - 0, 213, 191, 190, 0, 192, 114, 38, 209, 22, - 200, 138, 163, 261, 0, 0, 0, 310, 139, 0, - 52, 52, 207, 141, 0, 140, 206 + 0, 0, 0, 0, 0, 0, 0, 0, 69, 76, + 79, 0, 81, 82, 85, 86, 87, 88, 89, 91, + 93, 0, 99, 153, 98, 110, 0, 120, 124, 125, + 126, 127, 0, 130, 131, 57, 0, 244, 247, 253, + 0, 252, 255, 0, 0, 256, 20, 22, 270, 51, + 50, 291, 0, 309, 276, 42, 314, 309, 311, 310, + 49, 306, 147, 148, 0, 337, 318, 213, 204, 203, + 297, 194, 276, 42, 301, 297, 298, 0, 294, 176, + 177, 189, 170, 171, 174, 175, 165, 166, 0, 167, + 168, 169, 173, 172, 179, 178, 181, 182, 180, 190, + 0, 196, 59, 95, 152, 0, 344, 22, 209, 0, + 254, 0, 262, 47, 45, 48, 309, 276, 0, 309, + 0, 305, 42, 313, 319, 322, 0, 202, 0, 214, + 0, 297, 276, 0, 309, 0, 293, 0, 42, 300, + 0, 193, 115, 38, 210, 22, 304, 309, 315, 308, + 312, 0, 0, 321, 0, 201, 139, 192, 292, 309, + 302, 296, 299, 191, 0, 164, 263, 307, 316, 320, + 323, 0, 295, 303, 0, 0, 342, 140, 0, 52, + 52, 208, 142, 0, 141, 207 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 1, 2, 171, 276, 190, 364, 39, 40, 41, - 42, 256, 175, 43, 257, 373, 374, 375, 376, 283, - 357, 91, 167, 321, 168, 343, 207, 534, 538, 286, - 287, 288, 212, 332, 333, 314, 315, 316, 318, 291, - 384, 389, 295, 543, 544, 460, 47, 520, 78, 208, - 48, 80, 49, 258, 51, 259, 269, 354, 53, 54, - 271, 359, 55, 193, 56, 57, 260, 261, 180, 60, - 262, 62, 63, 64, 277, 65, 195, 66, 209, 210, - 293, 211, 169, 213, 68, 69, 215, 345 + -1, 1, 2, 173, 279, 192, 368, 40, 41, 42, + 43, 259, 177, 44, 260, 376, 377, 378, 379, 476, + 361, 92, 169, 325, 170, 347, 477, 591, 597, 289, + 290, 291, 214, 336, 337, 318, 319, 320, 322, 294, + 387, 392, 298, 602, 603, 464, 48, 548, 79, 478, + 49, 81, 50, 261, 52, 262, 272, 358, 54, 55, + 274, 363, 56, 195, 57, 58, 263, 264, 182, 61, + 265, 63, 64, 65, 280, 66, 197, 67, 211, 212, + 496, 555, 497, 498, 479, 540, 480, 481, 296, 573, + 545, 546, 213, 171, 215, 69, 70, 217, 349 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -269 +#define YYPACT_NINF -472 static const yytype_int16 yypact[] = { - -269, 42, 1015, -269, -269, -269, -269, -269, 82, -269, - -118, 125, -269, 127, -269, -269, -269, -269, -14, 88, - -269, -269, -269, 129, -14, -269, -70, -14, 253, -269, - -269, 131, -64, 134, 253, -269, -269, 1851, -269, -22, - -269, -269, -269, -269, -269, 1607, -21, -20, -269, -269, - -19, -58, -269, -17, -18, -10, -8, 5, -269, -269, - -4, -269, -5, -5, -5, 255, 1727, -7, -5, 28, - 30, -269, -269, 147, -269, -269, 20, -269, 26, -269, - -269, 43, -269, -269, -269, 1727, -269, -269, 20, 31, - 1684, -269, -96, -94, -269, -269, -269, -269, -269, -269, - -269, 41, 46, -269, -269, -269, -269, -269, -269, 50, - -269, -269, 53, -269, 56, 59, -269, -269, 63, 64, - 65, 67, 73, -269, 76, -269, 77, -269, 84, -269, - -269, 95, 96, -269, -269, -269, -269, -269, -269, -269, - -269, -269, 99, -269, -269, -269, -269, -269, 100, -269, - -269, -269, -269, -269, 103, -269, -269, -269, 111, 113, - 114, -269, 115, -269, -269, 116, 117, -93, -269, -269, - -269, 921, 404, 161, 136, 58, 119, -269, -269, -269, - -269, 255, 122, 123, -269, -269, -269, -269, -6, -269, - -269, -269, 139, 91, -269, -269, -269, -269, -269, -269, - -269, -269, -269, -269, -269, -269, 255, 255, -269, 128, - -129, -269, -269, -269, -5, -269, -269, -269, -15, 141, - -269, 130, -269, 255, 133, -269, 141, 85, 85, 296, - 297, 85, 85, 298, 304, 85, 307, 85, 85, 251, - 85, 85, -55, 85, 85, 85, 1727, 1727, 102, 317, - 1727, 1851, 156, -269, 154, -269, -269, -269, 157, -269, - -269, -269, -269, -10, -269, -269, -269, -269, -269, -66, - 179, -69, 159, 158, -269, -269, 498, 101, 160, -269, - 85, 867, 1109, -269, -269, -269, 163, 183, -269, 166, - -269, -56, -269, 188, -64, -54, 170, -269, -269, -269, - -269, -269, -269, -269, -269, 172, -269, 85, 85, 85, - 85, 85, 85, 780, 1402, -106, -269, 1402, 174, 175, - -269, -102, 176, 177, 178, 180, 181, 182, 184, 1189, - 340, 185, -90, -269, 1402, 190, 204, -82, 1242, 192, - 195, -269, -269, 198, 193, 199, 202, -269, 1851, 366, - -269, -269, -10, -12, -269, -269, 227, 1684, 208, -51, - 205, 301, 592, -10, -269, 1684, -269, -269, -269, -269, - 54, 212, -74, 211, -269, 238, -269, 1684, 255, -269, - 141, 85, -269, 1684, -269, 255, 214, -269, 217, -269, - 218, -269, 1727, 34, 34, 34, 34, 34, 34, 1292, - 219, 85, 85, 407, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 409, 85, 85, -269, -269, -269, 405, -269, -269, - -269, -269, -269, -269, -269, -269, -269, 243, -269, 85, - -269, -269, 85, -269, -269, -269, -269, -269, 411, -269, - -269, -269, 246, -269, -269, -269, 255, -269, -269, 1684, - 249, -269, -269, -10, -269, -269, -269, -269, 1159, 255, - -269, -269, -269, 255, 250, -269, 141, -269, -269, 252, - -269, 85, 94, 94, -269, 1114, 1114, 153, 153, 1368, - 1439, 1349, 1420, 1462, 1496, 153, 153, 29, 29, 34, - 34, 34, -269, 1315, -269, -269, -269, -269, 256, -269, - -10, -269, 255, -269, 686, -269, -269, -269, -67, -269, - 248, -269, -269, 34, 85, -269, -269, -269, -269, -10, - -269, -269, 1402, -269, -16, 85, 273, -269, -269, 274, - -43, -43, -269, -269, 259, -269, -269 + -472, 38, 1206, -472, -472, -472, -472, -472, 75, -472, + -86, 228, -472, 238, -472, -472, -472, -472, 28, 101, + -472, -472, -472, -472, 265, 28, -472, -23, 28, 408, + -472, -472, 271, -3, 287, 408, -472, -472, 2244, -472, + 25, -472, -472, -472, -472, -472, 1982, 34, 47, -472, + -472, 52, 54, -472, 73, 61, 106, 110, 62, -472, + -472, 97, -472, 31, 31, 31, 114, 2135, 123, 31, + 133, 135, -472, -472, 218, -472, -472, 126, -472, 142, + -472, -472, 146, -472, -472, -472, 2135, -472, -472, 126, + 148, 2060, -472, -99, -89, -472, -472, 151, -472, -472, + -472, -472, -472, 153, 154, -472, -472, -472, -472, -472, + -472, 156, -472, -472, 157, -472, 159, 160, -472, -472, + 161, 162, 163, 165, 167, -472, 169, -472, 173, -472, + 174, -472, -472, 185, 187, -472, -472, -472, -472, -472, + -472, -472, -472, -472, 192, -472, -472, -472, -472, -472, + 194, -472, -472, -472, -472, -472, 201, -472, -472, -472, + 210, 212, 214, -472, 215, -472, -472, 216, 219, -79, + -472, -472, -472, 1111, 425, 334, 290, 224, 230, -472, + -472, -472, -472, 114, 233, 235, -472, -472, -472, -472, + 24, -472, -472, -472, 296, 225, -472, -472, -472, -472, + -472, -472, -472, -472, -472, -472, -472, -472, 114, 114, + -472, 229, -26, -472, -472, -472, 31, -472, -472, -472, + 236, 312, -472, 237, -472, 114, 242, -472, 400, 312, + 967, 967, 401, 409, 967, 967, 410, 411, 967, 413, + 967, 967, 349, 967, 967, -21, 967, 967, 967, 2135, + 2135, 129, 418, 2135, 2244, 254, -472, 260, -472, -472, + -472, 263, -472, -472, -472, -472, 106, -472, -472, -472, + -472, -472, -145, 285, -65, 266, 264, -472, -472, 520, + 64, 268, -472, 967, 974, 1552, -472, -472, -472, 269, + 292, -472, 272, -472, -54, -472, 294, -3, -36, 270, + 274, -472, -472, -472, -472, -472, -472, -472, -472, 277, + -472, 967, 967, 967, 967, 967, 967, 805, 1801, -125, + -472, 1801, 279, 280, -472, -110, 282, 284, 286, 288, + 291, 295, 297, 1557, 448, 300, -109, -472, 1801, 301, + 310, -72, 1615, 302, 303, -472, -472, 305, 299, 307, + 309, -472, 2244, 453, -472, -472, 106, 1, -472, -472, + 335, 2060, 321, -34, 322, 417, 615, 106, -472, 2060, + -472, -472, -472, -472, 895, 329, 330, 354, -472, -472, + 2060, 57, -472, 312, 967, -472, 2060, -472, 114, 333, + -472, 336, -472, 338, -472, -472, 2060, 18, 18, 18, + 18, 18, 18, 1638, 267, 967, 967, 512, 967, 967, + 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, + 967, 967, 967, 967, 967, 513, 967, 967, -472, -472, + -472, 510, -472, -472, -472, -472, -472, -472, -472, -472, + -472, 346, -472, 967, -472, -472, 967, -472, -472, -472, + -472, -472, 516, -472, -472, -472, 348, -472, -472, -472, + 114, -472, -472, 2060, 351, -472, -472, 106, -472, -472, + -472, -472, 1474, 57, -472, 1318, -472, 57, -472, -472, + -472, 41, -472, -472, 57, 353, -472, 312, -472, -472, + 267, -472, -472, 1396, -472, 267, -472, 352, 48, 193, + 193, -472, 221, 221, 152, 152, 1688, 1765, 1742, 1819, + 1838, 1870, 152, 152, 234, 234, 18, 18, 18, -472, + 1720, -472, -472, -472, -472, 358, -472, 106, -472, 114, + -472, 710, -472, -472, -472, -472, 32, -472, 361, 57, + 362, -472, 1552, -472, 376, -472, -45, -472, 363, -472, + 365, 255, -472, 367, 57, 369, -472, 967, 1552, -472, + 967, -472, -472, -472, -472, 106, -472, 32, -472, -472, + -472, 370, 967, -472, 57, -472, -472, -472, -472, 32, + -472, -472, -472, 18, 371, 1801, -472, -472, -472, -472, + -472, 23, -472, -472, 967, 377, -472, -472, 398, 20, + 20, -472, -472, 382, -472, -472 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -269, -269, -269, 386, -268, -257, 8, -269, -269, -269, - 69, -269, -269, -269, 429, -269, -269, -269, -35, -269, - -27, -2, -269, -269, -230, -269, -269, -269, -269, -269, - -269, 55, 2, 194, -264, -13, -269, -221, -207, -269, - -269, -269, -269, -105, -245, -269, -269, -269, 92, -199, - -269, 60, 93, 23, -269, 435, -269, -269, 394, -269, - -269, -269, -269, -269, -30, -269, 440, 1, -269, -269, - 441, -269, -269, 168, -269, -44, 3, -31, -194, -269, - -26, 265, 206, 6, -57, -269, 0, -269 + -472, -472, -472, 511, -271, -257, 10, -472, -472, -472, + 195, -472, -472, -472, 557, -409, -472, -472, 89, -192, + -6, -2, -472, -472, -244, -472, -63, -472, -472, -472, + -472, 182, 2, 323, -261, -159, -472, -224, -228, -472, + -472, -472, -472, -32, -167, -472, -472, -472, 164, -40, + -472, 200, 100, 51, -472, 567, -472, -472, 527, -472, + -472, -472, -472, -472, -13, -472, 572, -1, -472, -472, + 574, -472, -472, -265, -411, -41, -7, -22, -180, -472, + -472, -472, -439, -472, -471, -472, -456, -472, -472, -472, + 3, -472, 395, 339, 6, -49, -472, 0, -472 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -216 +#define YYTABLE_NINF -217 static const yytype_int16 yytable[] = { - 45, 181, 70, 59, 46, 90, 351, 362, 67, 214, - 38, 323, 278, 279, 326, 179, 328, 371, 535, 331, - 289, 347, 336, 356, 322, 50, 358, 296, 221, 292, - 536, 196, 196, 196, -215, 9, 224, 196, 281, 11, - 423, 282, 3, 403, 427, 183, 223, 176, 403, 386, - 390, 182, 73, 251, 146, 15, 439, 297, 150, 298, - 299, 300, 301, 302, 439, 424, 197, 198, 177, 428, - 79, 216, -44, 369, 23, 252, -215, 20, 225, 385, - 23, 440, 161, 367, 84, 71, 72, 86, 297, 443, - 298, 299, 300, 301, 302, 453, 81, -44, 37, 270, - 85, 37, 530, 37, 199, 200, 464, 352, 403, 25, - 341, 37, 342, 37, 186, 303, 37, 382, 451, 387, - 30, 87, 458, 89, 37, 93, 542, 94, 74, 75, - 76, 77, 82, 83, 88, 77, 201, 92, 77, 265, - 266, 9, 273, 274, 199, 200, 303, 170, -29, 184, - 185, 304, 187, 192, 188, 218, 285, 537, 272, 189, - 472, 191, -30, 202, 264, 401, 402, 403, 194, 45, - 45, 70, 70, 46, 46, 507, 305, 67, 67, 255, - 255, 289, 304, 196, 470, 418, 419, 420, 306, 339, - 340, 475, -215, 346, 514, 421, 422, 217, 219, -31, - 421, 422, 504, 222, 203, 307, 515, 305, 308, 309, - 310, 226, 220, 311, 312, 317, 227, 284, 317, 306, - 228, 508, 465, 229, 313, 329, 230, 204, 334, 231, - 267, 334, 338, 232, 233, 234, 307, 235, 378, 308, - 309, 310, 353, 236, 311, 312, 237, 238, 416, 417, - 418, 419, 420, 527, 239, 313, 400, 205, 199, 200, - 421, 422, 511, 275, 383, 240, 241, 317, 334, 242, - 243, 206, 533, 244, 365, 517, 70, 521, 46, 292, - 377, 245, 67, 246, 247, 248, 249, 250, -32, 7, - 201, -33, -34, 388, 393, 394, 395, 396, 397, 398, - 399, 290, 280, 294, 319, 320, 324, 416, 417, 418, - 419, 420, 325, 456, 539, 327, 330, 202, 528, 421, - 422, 181, 344, 348, 349, 18, 350, 355, 360, 380, - 361, 368, 459, 469, 385, 479, 379, 21, 22, 473, - 381, 391, 392, 437, 24, 425, 426, 429, 430, 431, - 442, 432, 433, 434, 454, 435, 438, 396, 203, 448, - 365, 441, 70, 445, 46, 183, 446, 176, 67, 447, - 449, 182, 27, 450, 452, 455, 29, 457, 461, 19, - 466, 204, 467, 474, 468, 476, 477, 478, 482, 483, - 481, 485, 486, 487, 488, 489, 490, 491, 492, 493, - 494, 495, 496, 497, 498, 499, 500, 501, 4, 503, - 484, 205, 502, 505, 506, 512, 509, 510, 513, 519, - 531, 540, 541, 522, 378, 206, 334, 526, 546, 172, - 462, 44, 5, 516, 6, 471, 545, 52, 337, 178, - 7, 8, 58, 61, 9, 366, 268, 518, 335, 10, - 0, 0, 0, 0, 0, 11, 0, 12, 0, 0, - 0, 13, 14, 0, 15, 0, 377, 16, 523, 17, - 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, - 0, 0, 19, 254, 0, 0, 20, 0, 21, 22, - 23, 0, 0, 0, 0, 24, 0, 0, 0, 0, - 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 532, 365, 0, 70, 0, 46, 0, 25, 0, - 67, 0, 26, 27, 28, 0, 5, 29, 6, 30, - 0, 0, 0, 31, 7, 0, 0, 0, 9, 32, - 33, 0, 34, 10, 0, 0, 0, 35, 36, 0, + 46, 60, 71, 209, 47, 183, 326, 366, 68, 355, + 351, 327, 39, 544, 330, 370, 332, 535, 216, 335, + 286, 541, 340, 375, 427, 38, 210, 91, 281, 282, + 360, 356, 407, 181, -216, 201, 202, 223, 3, 431, + 443, 198, 198, 198, 226, 295, 185, 198, 178, 428, + 225, 550, 184, 51, 11, 373, 556, 199, 200, 594, + 201, 202, 218, 536, 432, 444, 538, 201, 202, 203, + 254, 595, 321, 9, 9, 321, -216, 443, 72, 73, + 566, 551, 333, 569, 553, 338, 227, 74, 338, 342, + 24, 148, 255, 15, 203, 152, 204, 179, 581, 457, + 371, 203, 447, 544, 574, 38, 9, 362, 455, 82, + 468, 587, 578, 24, 80, 20, 38, 201, 202, 163, + 209, 204, 385, 592, 321, 338, 567, 575, 204, 88, + 389, 393, 273, 571, 38, 95, 38, 345, 205, 346, + 390, 579, 462, 210, 284, 209, 209, 285, 26, 584, + 86, 203, 397, 398, 399, 400, 401, 402, 403, 31, + 483, 206, 209, 205, 405, 406, 407, 38, 210, 210, + 205, 46, 46, 71, 71, 47, 47, 275, 204, 68, + 68, 292, 524, 258, 258, 210, 206, 425, 426, 300, + 38, 474, 601, 206, 198, 531, 90, 172, 94, 596, + 343, 344, 284, 521, 350, 475, -29, 407, 486, 287, + 532, 284, 494, 194, 542, 400, 474, 209, 284, 186, + 205, 558, 525, 207, 187, 85, 220, 284, 87, 188, + 475, 75, 76, 405, 406, 407, 190, 208, 410, 411, + 210, 77, 78, 206, 381, 189, 499, 500, 407, 502, + 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, + 513, 514, 515, 516, 517, 518, 357, 520, 83, 84, + 563, 370, 196, 207, 89, 78, 404, 369, 191, 71, + 528, 47, 193, 380, 338, 68, 370, 208, 386, 543, + 93, 78, 203, 268, 269, -30, 391, 9, 494, 276, + 277, -216, 370, 494, 203, 219, 559, -31, 586, 420, + 421, 422, 423, 424, 370, 201, 202, 221, 222, 204, + 460, 425, 426, 224, 228, 209, 229, 230, 183, 231, + 232, 204, 233, 234, 235, 236, 237, 267, 238, 473, + 239, 495, 240, 292, 589, 484, 241, 242, 210, 564, + 420, 421, 422, 423, 424, 490, 458, 463, 243, 494, + 244, 205, 425, 426, 369, 245, 71, 246, 47, 185, + 598, 178, 68, 205, 247, 184, 418, 419, 420, 421, + 422, 423, 424, 248, 206, 249, 485, 250, 251, 252, + 425, 426, 253, 422, 423, 424, 206, 209, 583, 270, + 278, 585, -32, 425, 426, -33, 283, -34, 299, 323, + 288, 293, 539, 321, 492, 297, 334, 324, 328, 329, + 210, 331, 529, 348, 352, 284, 492, 495, 493, 4, + 554, 381, 495, 353, 381, 354, 359, 284, 364, 365, + 493, 383, 372, 388, 394, 382, 7, 549, 395, 384, + 396, 441, 381, 429, 430, 5, 433, 6, 434, 446, + 435, 456, 436, 7, 8, 437, 209, 9, 452, 438, + 380, 439, 10, 380, 442, 445, 449, 450, 11, 451, + 12, 453, 18, 454, 13, 14, 459, 15, 495, 210, + 16, 380, 17, 461, 21, 22, 23, 19, 465, 18, + 470, 381, 25, 472, 471, 19, 257, 487, 488, 20, + 489, 21, 22, 23, 24, 501, 519, 381, 522, 25, + 523, 526, 527, 530, 4, 547, 557, 572, 599, 369, + 28, 71, 562, 47, 30, 568, 570, 68, 576, 577, + 380, 580, 26, 582, 588, 593, 27, 28, 29, 600, + 5, 30, 6, 31, 605, 174, 380, 32, 7, 45, + 466, 534, 9, 33, 34, 482, 35, 10, 604, 53, + 341, 36, 37, 180, 59, 12, 62, 590, 271, 13, + 14, 0, 15, 0, 339, 16, 0, 17, 0, 0, + 0, 0, 0, 0, 18, 38, 0, 0, 0, 0, + 19, 266, 0, 0, 20, 0, 21, 22, 23, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, + 0, 27, 28, 29, 0, 5, 30, 6, 31, 0, + 0, 0, 32, 7, 0, 0, 0, 9, 33, 34, + 0, 35, 10, 0, 0, 0, 36, 37, 0, 0, + 12, 0, 0, 0, 13, 14, 0, 15, 0, 0, + 16, 0, 17, 0, 0, 0, 0, 0, 0, 18, + 38, 0, 0, 0, 0, 19, 367, 0, 0, 20, + 0, 21, 22, 23, 0, 0, 0, 0, 0, 25, + 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 0, 0, 0, 27, 28, 29, 0, + 5, 30, 6, 31, 0, 0, 0, 32, 7, 0, + 0, 0, 9, 33, 34, 0, 35, 10, 0, 0, + 0, 36, 37, 0, 0, 12, 0, 0, 0, 13, + 14, 0, 15, 0, 0, 16, 0, 17, 0, 0, + 0, 0, 0, 0, 18, 38, 0, 0, 0, 0, + 19, 467, 0, 0, 20, 0, 21, 22, 23, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 301, 4, + 302, 303, 304, 305, 306, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, + 0, 27, 28, 29, 0, 5, 30, 6, 31, 0, + 0, 0, 32, 7, 0, 0, 0, 9, 33, 34, + 0, 35, 0, 0, 0, 0, 36, 37, 0, 0, + 12, 0, 0, 0, 13, 14, 0, 15, 307, 0, + 16, 0, 17, 0, 0, 0, 0, 0, 0, 18, + 38, 0, 0, 0, 0, 0, 565, 0, 0, 20, + 0, 21, 22, 23, 0, 0, 0, 0, 301, 25, + 302, 303, 304, 305, 306, 308, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 0, 0, 0, 27, 28, 29, 0, + 309, 30, 0, 31, 0, 0, 0, 32, 0, 0, + 0, 0, 310, 0, 34, 0, 35, 0, 0, 0, + 0, 36, 37, 0, 0, 0, 0, 0, 307, 311, + 0, 0, 312, 313, 314, 0, 0, 315, 316, 0, + 301, 0, 302, 303, 304, 305, 306, 301, 317, 302, + 303, 304, 305, 306, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 308, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 309, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 307, 0, 310, 0, 0, 0, 0, 307, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, + 0, 0, 312, 313, 314, 0, 0, 315, 316, 0, + 0, 0, 0, 0, 0, 0, 469, 308, 317, 0, + 0, 0, 0, 0, 308, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 309, 0, 0, 0, 0, 0, 0, 309, + 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, + 0, 310, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 311, 256, 0, 312, 313, 314, 0, 311, 315, + 316, 312, 313, 374, 0, 0, 315, 316, 0, 0, + 317, 5, 0, 6, 0, 0, 0, 317, 0, 7, + 8, 0, 0, 9, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 11, 0, 12, 0, 0, 0, + 13, 14, 0, 15, 0, 0, 16, 0, 17, 0, + 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, + 0, 19, 257, 0, 0, 20, 0, 21, 22, 23, + 24, 0, 0, 0, 0, 25, 0, 0, 0, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, + 0, 0, 27, 28, 29, 0, 5, 30, 6, 31, + 0, 0, 0, 32, 7, 8, 0, 0, 9, 33, + 34, 0, 35, 10, 0, 0, 0, 36, 37, 11, 0, 12, 0, 0, 0, 13, 14, 0, 15, 0, 0, 16, 0, 17, 0, 0, 0, 0, 0, 0, - 18, 37, 0, 0, 0, 0, 19, 263, 0, 0, - 20, 0, 21, 22, 0, 0, 0, 0, 0, 24, - 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 18, 38, 0, 0, 0, 0, 19, 0, 0, 0, + 20, 0, 21, 22, 23, 24, 0, 0, 0, 0, + 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 0, 0, 0, 26, 27, 28, 0, - 5, 29, 6, 30, 0, 0, 0, 31, 7, 0, - 0, 0, 9, 32, 33, 0, 34, 10, 0, 0, - 0, 35, 36, 0, 0, 12, 0, 0, 0, 13, - 14, 0, 15, 0, 0, 16, 0, 17, 0, 0, - 0, 0, 0, 0, 18, 37, 0, 0, 0, 0, - 19, 363, 0, 0, 20, 0, 21, 22, 0, 0, - 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, - 26, 27, 28, 0, 5, 29, 6, 30, 0, 0, - 0, 31, 7, 0, 0, 0, 9, 32, 33, 0, - 34, 10, 0, 0, 0, 35, 36, 0, 0, 12, - 0, 0, 0, 13, 14, 0, 15, 0, 0, 16, - 0, 17, 0, 0, 0, 0, 0, 0, 18, 37, - 0, 0, 0, 0, 19, 463, 0, 0, 20, 0, - 21, 22, 0, 0, 0, 0, 0, 24, 0, 0, - 0, 0, 0, 297, 4, 298, 299, 300, 301, 302, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 25, 0, 0, 0, 26, 27, 28, 0, 5, 29, - 6, 30, 0, 0, 0, 31, 7, 0, 0, 0, - 0, 32, 33, 0, 34, 0, 0, 0, 0, 35, - 36, 0, 0, 12, 0, 0, 0, 13, 14, 0, - 0, 303, 0, 16, 0, 17, 0, 0, 0, 0, - 0, 0, 18, 37, 0, 0, 0, 0, 0, 529, - 0, 0, 0, 0, 21, 22, 0, 0, 0, 0, - 297, 24, 298, 299, 300, 301, 302, 304, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, - 28, 0, 305, 29, 0, 0, 0, 0, 0, 31, - 0, 0, 0, 0, 306, 0, 33, 0, 34, 0, - 0, 0, 0, 35, 36, 4, 0, 0, 303, 0, - 0, 307, 253, 0, 308, 309, 310, 0, 0, 311, - 312, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 313, 6, 0, 0, 0, 0, 0, 7, 8, 0, - 0, 9, 0, 0, 304, 0, 10, 0, 0, 0, - 0, 0, 11, 0, 12, 0, 0, 0, 13, 14, - 0, 15, 0, 0, 16, 0, 17, 0, 0, 305, - 0, 0, 0, 18, 0, 0, 0, 0, 0, 19, - 254, 306, 0, 20, 0, 21, 22, 23, 0, 0, - 0, 0, 24, 0, 0, 0, 0, 0, 307, 4, - 0, 308, 309, 370, 0, 0, 311, 312, 0, 0, - 0, 0, 0, 0, 0, 25, 0, 313, 0, 26, - 27, 28, 0, 5, 29, 6, 30, 0, 0, 0, - 31, 7, 8, 0, 0, 9, 32, 33, 0, 34, - 10, 0, 0, 0, 35, 36, 11, 0, 12, 0, - 0, 0, 13, 14, 0, 15, 0, 0, 16, 0, - 17, 0, 0, 0, 0, 0, 0, 18, 37, 0, - 0, 0, 0, 19, 0, 0, 0, 20, 0, 21, - 22, 23, 0, 0, 0, 0, 24, 0, 0, 0, - 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 401, 402, 403, 25, - 0, 406, 407, 26, 27, 28, 0, 5, 29, 6, - 30, 0, 0, 0, 31, 7, 0, 0, 0, 9, - 32, 33, 0, 34, 0, 0, 0, 0, 35, 36, - 0, 0, 12, 4, 0, 0, 13, 14, 0, 15, - 0, 0, 16, 0, 17, 0, 0, 0, 0, 0, - 0, 18, 37, 0, 0, 0, 0, 5, 0, 6, - 0, 20, 0, 21, 22, 7, 0, 0, 0, 9, - 24, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 0, 0, 12, 0, 0, 0, 13, 14, 0, 15, - 0, 0, 16, 25, 17, 0, 0, 26, 27, 28, - 0, 18, 29, 0, 30, 0, 0, 0, 31, 0, - 0, 20, 0, 21, 22, 33, 0, 34, 0, 0, - 24, 0, 372, 36, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 0, 0, 0, 414, 415, 416, 417, - 418, 419, 420, 25, 0, 0, 37, 26, 27, 28, - 421, 422, 29, 0, 30, 0, 0, 0, 31, 0, - 0, 0, 0, 0, 0, 33, 0, 34, 0, 0, - 0, 0, 35, 36, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 37, 401, 402, 403, - 404, 405, 406, 407, 408, 409, 410, 0, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 0, 0, - 0, 0, 0, 0, 0, 421, 422, 0, 0, 0, - 436, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 401, 402, 403, 404, 405, 406, 407, 0, 409, 410, - 0, 411, 412, 413, 414, 415, 416, 417, 418, 419, - 420, 0, 0, 0, 0, 0, 0, 0, 421, 422, - 0, 0, 0, 444, 401, 402, 403, 404, 405, 406, - 407, 408, 409, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 401, 402, 403, 404, 405, 406, 407, 410, - 0, 411, 412, 413, 414, 415, 416, 417, 418, 419, - 420, 401, 402, 403, 404, 405, 406, 407, 421, 422, - 0, 0, 410, 480, 411, 412, 413, 414, 415, 416, - 417, 418, 419, 420, 401, 402, 403, 404, 405, 406, - 407, 421, 422, 525, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 410, 524, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 401, 402, - 403, 404, 405, 406, 407, 421, 422, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 0, 0, 0, - 0, 0, 0, 0, 421, 422, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, - 0, 411, 412, 413, 414, 415, 416, 417, 418, 419, - 420, 0, 0, 0, 0, 0, 0, 0, 421, 422, - 412, 413, 414, 415, 416, 417, 418, 419, 420, 0, - 0, 0, 0, 0, 0, 0, 421, 422, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 0, 0, - 0, 0, 0, 0, 0, 421, 422, 0, 0, 0, - 0, 4, 0, 413, 414, 415, 416, 417, 418, 419, - 420, 0, 0, 0, 0, 0, 0, 0, 421, 422, - 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, - 0, 0, 0, 7, 8, 0, 0, 9, 414, 415, - 416, 417, 418, 419, 420, 0, 0, 0, 11, 0, - 12, 0, 421, 422, 13, 14, 0, 15, 0, 0, - 16, 0, 17, 0, 0, 0, 0, 0, 0, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 4, 20, - 0, 21, 22, 23, 0, 0, 173, 0, 24, 0, - 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 26, 0, 0, 0, 27, 28, 29, + 0, 0, 30, 0, 31, 0, 0, 0, 32, 0, + 0, 0, 0, 0, 33, 34, 0, 35, 5, 0, + 6, 0, 36, 37, 0, 203, 7, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12, 0, 0, 38, 13, 14, 0, + 15, 0, 204, 16, 0, 17, 0, 0, 0, 0, + 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, + 4, 0, 20, 0, 21, 22, 23, 0, 0, 0, + 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 205, 0, 5, 0, 6, 0, + 0, 0, 0, 203, 7, 26, 0, 0, 9, 27, + 28, 29, 0, 0, 30, 0, 31, 206, 0, 0, + 32, 12, 0, 0, 0, 13, 14, 34, 15, 35, + 204, 16, 0, 17, 36, 37, 0, 0, 0, 0, + 18, 0, 0, 0, 0, 0, 0, 537, 4, 0, + 20, 0, 21, 22, 23, 0, 0, 0, 38, 0, + 25, 0, 0, 0, 0, 533, 0, 0, 0, 0, + 0, 0, 205, 0, 5, 0, 6, 0, 0, 0, + 0, 0, 7, 26, 0, 0, 9, 27, 28, 29, + 0, 0, 30, 0, 31, 206, 0, 0, 32, 12, + 0, 0, 0, 13, 14, 34, 15, 35, 0, 16, + 0, 17, 36, 37, 0, 0, 0, 0, 18, 0, + 0, 0, 0, 0, 0, 552, 4, 0, 20, 0, + 21, 22, 23, 0, 0, 0, 38, 0, 25, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, - 7, 25, 0, 0, 9, 26, 27, 28, 0, 0, - 29, 4, 30, 0, 0, 0, 31, 12, 0, 0, - 0, 13, 14, 33, 15, 34, 0, 16, 0, 17, - 35, 36, 0, 0, 0, 5, 18, 6, 0, 0, - 0, 0, 0, 7, 0, 0, 20, 0, 21, 22, - 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, - 12, 0, 0, 0, 13, 14, 0, 0, 0, 0, - 16, 0, 17, 0, 0, 0, 0, 0, 25, 18, - 0, 0, 26, 27, 28, 0, 0, 29, 0, 30, - 0, 21, 22, 31, 0, 0, 0, 0, 24, 0, - 33, 0, 34, 0, 0, 0, 0, 35, 36, 0, + 7, 26, 0, 0, 9, 27, 28, 29, 0, 0, + 30, 0, 31, 0, 0, 0, 32, 12, 0, 0, + 0, 13, 14, 34, 15, 35, 0, 16, 0, 17, + 36, 37, 0, 0, 0, 0, 18, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 20, 0, 21, 22, + 23, 0, 0, 0, 38, 0, 25, 0, 0, 0, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 0, 0, 0, 27, 28, 29, 0, 0, 30, 0, + 31, 0, 0, 0, 32, 0, 0, 0, 0, 0, + 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, + 405, 406, 407, 408, 409, 410, 411, 414, 413, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 0, + 0, 0, 38, 0, 0, 0, 425, 426, 0, 0, + 0, 440, 405, 406, 407, 408, 409, 410, 411, 412, + 413, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 0, 0, 414, 0, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 405, 406, 407, + 408, 409, 410, 411, 425, 426, 0, 0, 414, 448, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 0, 0, 0, 0, 0, 0, 0, 425, 426, 0, + 0, 0, 491, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 405, 406, 407, 408, 409, 410, 411, 0, 0, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 405, 406, 407, 408, 409, 410, 411, 425, 426, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 26, 27, 28, 0, 0, - 29, 0, 0, 0, 0, 0, 31, 0, 0, 0, - 0, 0, 0, 33, 0, 34, 0, 0, 0, 0, - 35, 36, 95, 0, 96, 97, 0, 98, 99, 0, - 100, 0, 0, 101, 0, 102, 0, 0, 0, 0, - 0, 0, 103, 104, 105, 106, 0, 107, 108, 109, - 110, 111, 0, 112, 0, 113, 114, 115, 0, 0, - 116, 0, 0, 0, 0, 117, 0, 118, 119, 120, - 121, 122, 123, 0, 124, 125, 126, 127, 128, 0, - 0, 129, 0, 0, 130, 0, 0, 0, 131, 132, - 0, 133, 0, 0, 0, 134, 135, 136, 0, 137, - 138, 139, 140, 141, 0, 142, 0, 143, 144, 145, - 146, 147, 148, 149, 150, 0, 151, 152, 153, 0, - 0, 0, 154, 0, 0, 155, 0, 0, 156, 157, - 0, 0, 158, 159, 160, 0, 0, 0, 161, 0, - 162, 163, 164, 165, 0, 0, 166 + 414, 0, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 405, 406, 407, 408, 409, 410, 411, 425, + 426, 561, 414, 560, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 0, 0, 0, 0, 0, 0, + 0, 425, 426, 0, 0, 0, 0, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 0, 0, 0, + 0, 0, 0, 0, 425, 426, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 414, 0, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 0, 0, 0, 0, 0, 0, 0, + 425, 426, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 0, 0, 0, 0, 0, 4, 0, 425, 426, + 0, 0, 417, 418, 419, 420, 421, 422, 423, 424, + 0, 0, 0, 0, 0, 0, 0, 425, 426, 0, + 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, + 7, 8, 0, 0, 9, 418, 419, 420, 421, 422, + 423, 424, 0, 0, 0, 11, 0, 12, 0, 425, + 426, 13, 14, 0, 15, 0, 0, 16, 0, 17, + 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 20, 0, 21, 22, + 23, 24, 0, 0, 175, 0, 25, 0, 176, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 6, 0, 0, 0, 0, 0, 7, 26, + 0, 0, 9, 27, 28, 29, 0, 0, 30, 0, + 31, 0, 0, 0, 32, 12, 0, 0, 0, 13, + 14, 34, 15, 35, 0, 16, 0, 17, 36, 37, + 0, 0, 0, 0, 18, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, + 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 26, 0, 0, + 0, 27, 28, 29, 0, 0, 30, 0, 31, 0, + 12, 0, 32, 0, 13, 14, 0, 0, 0, 34, + 16, 35, 17, 0, 0, 0, 36, 37, 0, 18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 21, 22, 23, 0, 0, 0, 0, 0, 25, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 27, 28, 29, 0, + 0, 30, 0, 0, 0, 0, 96, 32, 97, 98, + 99, 0, 100, 101, 34, 102, 35, 0, 103, 0, + 104, 36, 37, 0, 0, 0, 0, 105, 106, 107, + 108, 0, 109, 110, 111, 112, 113, 0, 114, 0, + 115, 116, 117, 0, 0, 118, 0, 0, 0, 0, + 119, 0, 120, 121, 122, 123, 124, 125, 0, 126, + 127, 128, 129, 130, 0, 0, 131, 0, 0, 132, + 0, 0, 0, 0, 133, 134, 0, 135, 0, 0, + 0, 136, 137, 138, 0, 139, 140, 141, 142, 143, + 0, 144, 0, 145, 146, 147, 148, 149, 150, 151, + 152, 0, 153, 154, 155, 0, 0, 0, 156, 0, + 0, 157, 0, 0, 158, 159, 0, 0, 160, 161, + 162, 0, 0, 0, 163, 0, 164, 165, 166, 167, + 0, 0, 168 }; static const yytype_int16 yycheck[] = { - 2, 45, 2, 2, 2, 32, 263, 275, 2, 66, - 2, 232, 206, 207, 235, 45, 237, 281, 34, 240, - 219, 251, 243, 92, 231, 2, 271, 226, 85, 223, - 46, 62, 63, 64, 130, 40, 130, 68, 167, 51, - 146, 170, 0, 14, 146, 45, 90, 45, 14, 294, - 295, 45, 170, 146, 109, 60, 146, 3, 113, 5, - 6, 7, 8, 9, 146, 171, 63, 64, 45, 171, - 84, 68, 146, 280, 86, 168, 172, 82, 172, 146, - 86, 171, 137, 277, 24, 3, 4, 27, 3, 171, - 5, 6, 7, 8, 9, 352, 8, 171, 167, 105, - 170, 167, 169, 167, 3, 4, 363, 173, 14, 114, - 8, 167, 10, 167, 172, 61, 167, 173, 348, 173, - 125, 28, 173, 31, 167, 33, 169, 34, 3, 4, - 3, 4, 3, 4, 3, 4, 35, 3, 4, 3, - 4, 40, 3, 4, 3, 4, 61, 169, 169, 169, - 169, 97, 169, 148, 172, 8, 171, 173, 188, 169, - 381, 169, 169, 62, 3, 12, 13, 14, 172, 171, - 172, 171, 172, 171, 172, 439, 122, 171, 172, 171, - 172, 380, 97, 214, 378, 156, 157, 158, 134, 246, - 247, 385, 172, 250, 462, 166, 167, 169, 172, 169, - 166, 167, 423, 172, 103, 151, 463, 122, 154, 155, - 156, 170, 169, 159, 160, 228, 170, 214, 231, 134, - 170, 442, 168, 170, 170, 238, 170, 126, 241, 170, - 172, 244, 245, 170, 170, 170, 151, 170, 282, 154, - 155, 156, 269, 170, 159, 160, 170, 170, 154, 155, - 156, 157, 158, 510, 170, 170, 313, 156, 3, 4, - 166, 167, 456, 172, 291, 170, 170, 280, 281, 170, - 170, 170, 529, 170, 276, 469, 276, 476, 276, 473, - 282, 170, 276, 170, 170, 170, 170, 170, 169, 36, - 35, 169, 169, 295, 307, 308, 309, 310, 311, 312, - 313, 171, 174, 170, 8, 8, 8, 154, 155, 156, - 157, 158, 8, 357, 535, 8, 65, 62, 512, 166, - 167, 365, 5, 167, 170, 72, 169, 148, 169, 146, - 172, 171, 359, 377, 146, 392, 173, 84, 85, 383, - 174, 171, 170, 3, 91, 171, 171, 171, 171, 171, - 146, 171, 171, 171, 353, 171, 171, 370, 103, 166, - 362, 171, 362, 171, 362, 365, 171, 365, 362, 171, - 171, 365, 119, 171, 8, 148, 123, 169, 173, 78, - 168, 126, 171, 383, 146, 171, 169, 169, 401, 402, - 171, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 4, 422, - 3, 156, 3, 8, 171, 459, 5, 171, 169, 169, - 172, 148, 148, 171, 468, 170, 439, 171, 169, 43, - 361, 2, 28, 468, 30, 380, 541, 2, 244, 45, - 36, 37, 2, 2, 40, 277, 181, 473, 242, 45, - -1, -1, -1, -1, -1, 51, -1, 53, -1, -1, - -1, 57, 58, -1, 60, -1, 468, 63, 481, 65, - -1, -1, -1, -1, -1, -1, 72, -1, -1, -1, - -1, -1, 78, 79, -1, -1, 82, -1, 84, 85, - 86, -1, -1, -1, -1, 91, -1, -1, -1, -1, - -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, - -1, 524, 514, -1, 514, -1, 514, -1, 114, -1, - 514, -1, 118, 119, 120, -1, 28, 123, 30, 125, - -1, -1, -1, 129, 36, -1, -1, -1, 40, 135, - 136, -1, 138, 45, -1, -1, -1, 143, 144, -1, - -1, 53, -1, -1, -1, 57, 58, -1, 60, -1, - -1, 63, -1, 65, -1, -1, -1, -1, -1, -1, - 72, 167, -1, -1, -1, -1, 78, 173, -1, -1, - 82, -1, 84, 85, -1, -1, -1, -1, -1, 91, - -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, + 2, 2, 2, 66, 2, 46, 234, 278, 2, 266, + 254, 235, 2, 484, 238, 280, 240, 473, 67, 243, + 212, 477, 246, 284, 149, 170, 66, 33, 208, 209, + 95, 176, 14, 46, 133, 3, 4, 86, 0, 149, + 149, 63, 64, 65, 133, 225, 46, 69, 46, 174, + 91, 490, 46, 2, 53, 283, 495, 64, 65, 36, + 3, 4, 69, 474, 174, 174, 475, 3, 4, 37, + 149, 48, 231, 42, 42, 234, 175, 149, 3, 4, + 536, 492, 241, 539, 493, 244, 175, 173, 247, 248, + 89, 112, 171, 62, 37, 116, 64, 46, 554, 356, + 280, 37, 174, 574, 149, 170, 42, 274, 352, 8, + 367, 567, 551, 89, 86, 84, 170, 3, 4, 140, + 183, 64, 176, 579, 283, 284, 537, 172, 64, 29, + 297, 298, 108, 542, 170, 35, 170, 8, 106, 10, + 176, 552, 176, 183, 170, 208, 209, 173, 117, 558, + 173, 37, 311, 312, 313, 314, 315, 316, 317, 128, + 384, 129, 225, 106, 12, 13, 14, 170, 208, 209, + 106, 173, 174, 173, 174, 173, 174, 190, 64, 173, + 174, 221, 443, 173, 174, 225, 129, 169, 170, 229, + 170, 159, 172, 129, 216, 466, 32, 172, 34, 176, + 249, 250, 170, 427, 253, 173, 172, 14, 388, 216, + 467, 170, 404, 151, 173, 374, 159, 280, 170, 172, + 106, 173, 446, 159, 172, 25, 8, 170, 28, 175, + 173, 3, 4, 12, 13, 14, 175, 173, 17, 18, + 280, 3, 4, 129, 285, 172, 405, 406, 14, 408, + 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 272, 426, 3, 4, + 527, 536, 175, 159, 3, 4, 317, 279, 172, 279, + 460, 279, 172, 285, 443, 279, 551, 173, 294, 481, + 3, 4, 37, 3, 4, 172, 298, 42, 490, 3, + 4, 175, 567, 495, 37, 172, 498, 172, 565, 157, + 158, 159, 160, 161, 579, 3, 4, 175, 172, 64, + 361, 169, 170, 175, 173, 388, 173, 173, 369, 173, + 173, 64, 173, 173, 173, 173, 173, 3, 173, 380, + 173, 404, 173, 383, 572, 386, 173, 173, 388, 529, + 157, 158, 159, 160, 161, 396, 357, 363, 173, 551, + 173, 106, 169, 170, 366, 173, 366, 173, 366, 369, + 594, 369, 366, 106, 173, 369, 155, 156, 157, 158, + 159, 160, 161, 173, 129, 173, 386, 173, 173, 173, + 169, 170, 173, 159, 160, 161, 129, 460, 557, 175, + 175, 560, 172, 169, 170, 172, 177, 172, 8, 8, + 174, 174, 475, 572, 159, 173, 67, 8, 8, 8, + 460, 8, 463, 5, 170, 170, 159, 490, 173, 4, + 493, 472, 495, 173, 475, 172, 151, 170, 172, 175, + 173, 149, 174, 149, 174, 176, 38, 487, 174, 177, + 173, 3, 493, 174, 174, 30, 174, 32, 174, 149, + 174, 8, 174, 38, 39, 174, 529, 42, 169, 174, + 472, 174, 47, 475, 174, 174, 174, 174, 53, 174, + 55, 174, 74, 174, 59, 60, 151, 62, 551, 529, + 65, 493, 67, 172, 86, 87, 88, 80, 176, 74, + 171, 542, 94, 149, 174, 80, 81, 174, 172, 84, + 172, 86, 87, 88, 89, 3, 3, 558, 8, 94, + 174, 5, 174, 172, 4, 172, 174, 151, 151, 531, + 122, 531, 174, 531, 126, 174, 174, 531, 175, 174, + 542, 174, 117, 174, 174, 174, 121, 122, 123, 151, + 30, 126, 32, 128, 172, 44, 558, 132, 38, 2, + 365, 472, 42, 138, 139, 383, 141, 47, 600, 2, + 247, 146, 147, 46, 2, 55, 2, 574, 183, 59, + 60, -1, 62, -1, 245, 65, -1, 67, -1, -1, + -1, -1, -1, -1, 74, 170, -1, -1, -1, -1, + 80, 176, -1, -1, 84, -1, 86, 87, 88, -1, + -1, -1, -1, -1, 94, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 114, -1, -1, -1, 118, 119, 120, -1, - 28, 123, 30, 125, -1, -1, -1, 129, 36, -1, - -1, -1, 40, 135, 136, -1, 138, 45, -1, -1, - -1, 143, 144, -1, -1, 53, -1, -1, -1, 57, - 58, -1, 60, -1, -1, 63, -1, 65, -1, -1, - -1, -1, -1, -1, 72, 167, -1, -1, -1, -1, - 78, 173, -1, -1, 82, -1, 84, 85, -1, -1, - -1, -1, -1, 91, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 117, -1, -1, + -1, 121, 122, 123, -1, 30, 126, 32, 128, -1, + -1, -1, 132, 38, -1, -1, -1, 42, 138, 139, + -1, 141, 47, -1, -1, -1, 146, 147, -1, -1, + 55, -1, -1, -1, 59, 60, -1, 62, -1, -1, + 65, -1, 67, -1, -1, -1, -1, -1, -1, 74, + 170, -1, -1, -1, -1, 80, 176, -1, -1, 84, + -1, 86, 87, 88, -1, -1, -1, -1, -1, 94, + -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 117, -1, -1, -1, 121, 122, 123, -1, + 30, 126, 32, 128, -1, -1, -1, 132, 38, -1, + -1, -1, 42, 138, 139, -1, 141, 47, -1, -1, + -1, 146, 147, -1, -1, 55, -1, -1, -1, 59, + 60, -1, 62, -1, -1, 65, -1, 67, -1, -1, + -1, -1, -1, -1, 74, 170, -1, -1, -1, -1, + 80, 176, -1, -1, 84, -1, 86, 87, 88, -1, + -1, -1, -1, -1, 94, -1, -1, -1, 3, 4, + 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 117, -1, -1, + -1, 121, 122, 123, -1, 30, 126, 32, 128, -1, + -1, -1, 132, 38, -1, -1, -1, 42, 138, 139, + -1, 141, -1, -1, -1, -1, 146, 147, -1, -1, + 55, -1, -1, -1, 59, 60, -1, 62, 63, -1, + 65, -1, 67, -1, -1, -1, -1, -1, -1, 74, + 170, -1, -1, -1, -1, -1, 176, -1, -1, 84, + -1, 86, 87, 88, -1, -1, -1, -1, 3, 94, + 5, 6, 7, 8, 9, 100, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 117, -1, -1, -1, 121, 122, 123, -1, + 125, 126, -1, 128, -1, -1, -1, 132, -1, -1, + -1, -1, 137, -1, 139, -1, 141, -1, -1, -1, + -1, 146, 147, -1, -1, -1, -1, -1, 63, 154, + -1, -1, 157, 158, 159, -1, -1, 162, 163, -1, + 3, -1, 5, 6, 7, 8, 9, 3, 173, 5, + 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 125, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 63, -1, 137, -1, -1, -1, -1, 63, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 154, + -1, -1, 157, 158, 159, -1, -1, 162, 163, -1, + -1, -1, -1, -1, -1, -1, 171, 100, 173, -1, + -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 125, -1, -1, -1, -1, -1, -1, 125, + -1, -1, -1, -1, 137, -1, -1, -1, -1, -1, + -1, 137, -1, -1, -1, 4, -1, -1, -1, -1, + -1, 154, 11, -1, 157, 158, 159, -1, 154, 162, + 163, 157, 158, 159, -1, -1, 162, 163, -1, -1, + 173, 30, -1, 32, -1, -1, -1, 173, -1, 38, + 39, -1, -1, 42, -1, -1, -1, -1, 47, -1, + -1, -1, -1, -1, 53, -1, 55, -1, -1, -1, + 59, 60, -1, 62, -1, -1, 65, -1, 67, -1, + -1, -1, -1, -1, -1, 74, -1, -1, -1, -1, + -1, 80, 81, -1, -1, 84, -1, 86, 87, 88, + 89, -1, -1, -1, -1, 94, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 114, -1, -1, -1, - 118, 119, 120, -1, 28, 123, 30, 125, -1, -1, - -1, 129, 36, -1, -1, -1, 40, 135, 136, -1, - 138, 45, -1, -1, -1, 143, 144, -1, -1, 53, - -1, -1, -1, 57, 58, -1, 60, -1, -1, 63, - -1, 65, -1, -1, -1, -1, -1, -1, 72, 167, - -1, -1, -1, -1, 78, 173, -1, -1, 82, -1, - 84, 85, -1, -1, -1, -1, -1, 91, -1, -1, - -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, + -1, -1, -1, -1, -1, -1, -1, -1, 117, -1, + -1, -1, 121, 122, 123, -1, 30, 126, 32, 128, + -1, -1, -1, 132, 38, 39, -1, -1, 42, 138, + 139, -1, 141, 47, -1, -1, -1, 146, 147, 53, + -1, 55, -1, -1, -1, 59, 60, -1, 62, -1, + -1, 65, -1, 67, -1, -1, -1, -1, -1, -1, + 74, 170, -1, -1, -1, -1, 80, -1, -1, -1, + 84, -1, 86, 87, 88, 89, -1, -1, -1, -1, + 94, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 114, -1, -1, -1, 118, 119, 120, -1, 28, 123, - 30, 125, -1, -1, -1, 129, 36, -1, -1, -1, - -1, 135, 136, -1, 138, -1, -1, -1, -1, 143, - 144, -1, -1, 53, -1, -1, -1, 57, 58, -1, - -1, 61, -1, 63, -1, 65, -1, -1, -1, -1, - -1, -1, 72, 167, -1, -1, -1, -1, -1, 173, - -1, -1, -1, -1, 84, 85, -1, -1, -1, -1, - 3, 91, 5, 6, 7, 8, 9, 97, -1, -1, + -1, -1, 4, 117, -1, -1, -1, 121, 122, 123, + -1, -1, 126, -1, 128, -1, -1, -1, 132, -1, + -1, -1, -1, -1, 138, 139, -1, 141, 30, -1, + 32, -1, 146, 147, -1, 37, 38, -1, -1, -1, + 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 55, -1, -1, 170, 59, 60, -1, + 62, -1, 64, 65, -1, 67, -1, -1, -1, -1, + -1, -1, 74, -1, -1, -1, -1, -1, -1, -1, + 4, -1, 84, -1, 86, 87, 88, -1, -1, -1, + -1, -1, 94, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 106, -1, 30, -1, 32, -1, + -1, -1, -1, 37, 38, 117, -1, -1, 42, 121, + 122, 123, -1, -1, 126, -1, 128, 129, -1, -1, + 132, 55, -1, -1, -1, 59, 60, 139, 62, 141, + 64, 65, -1, 67, 146, 147, -1, -1, -1, -1, + 74, -1, -1, -1, -1, -1, -1, 159, 4, -1, + 84, -1, 86, 87, 88, -1, -1, -1, 170, -1, + 94, -1, -1, -1, -1, 21, -1, -1, -1, -1, + -1, -1, 106, -1, 30, -1, 32, -1, -1, -1, + -1, -1, 38, 117, -1, -1, 42, 121, 122, 123, + -1, -1, 126, -1, 128, 129, -1, -1, 132, 55, + -1, -1, -1, 59, 60, 139, 62, 141, -1, 65, + -1, 67, 146, 147, -1, -1, -1, -1, 74, -1, + -1, -1, -1, -1, -1, 159, 4, -1, 84, -1, + 86, 87, 88, -1, -1, -1, 170, -1, 94, 12, + 13, 14, 15, 16, 17, 18, 19, 20, -1, -1, + -1, -1, 30, -1, 32, -1, -1, -1, -1, -1, + 38, 117, -1, -1, 42, 121, 122, 123, -1, -1, + 126, -1, 128, -1, -1, -1, 132, 55, -1, -1, + -1, 59, 60, 139, 62, 141, -1, 65, -1, 67, + 146, 147, -1, -1, -1, -1, 74, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 84, -1, 86, 87, + 88, -1, -1, -1, 170, -1, 94, -1, -1, -1, + 12, 13, 14, 15, 16, 17, 18, 19, 20, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 117, + -1, -1, -1, 121, 122, 123, -1, -1, 126, -1, + 128, -1, -1, -1, 132, -1, -1, -1, -1, -1, + -1, 139, -1, 141, -1, -1, -1, -1, 146, 147, + 12, 13, 14, 15, 16, 17, 18, 150, 20, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, -1, + -1, -1, 170, -1, -1, -1, 169, 170, -1, -1, + -1, 174, 12, 13, 14, 15, 16, 17, 18, 19, + 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 12, 13, 14, 15, 16, 17, + 18, 19, 20, -1, -1, 150, -1, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 12, 13, 14, + 15, 16, 17, 18, 169, 170, -1, -1, 150, 174, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + -1, -1, -1, -1, -1, -1, -1, 169, 170, -1, + -1, -1, 174, 12, 13, 14, 15, 16, 17, 18, + 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 12, 13, 14, 15, 16, 17, 18, -1, -1, + 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 12, 13, 14, 15, 16, 17, 18, 169, 170, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 118, 119, - 120, -1, 122, 123, -1, -1, -1, -1, -1, 129, - -1, -1, -1, -1, 134, -1, 136, -1, 138, -1, - -1, -1, -1, 143, 144, 4, -1, -1, 61, -1, - -1, 151, 11, -1, 154, 155, 156, -1, -1, 159, - 160, -1, -1, -1, -1, -1, -1, -1, -1, 28, - 170, 30, -1, -1, -1, -1, -1, 36, 37, -1, - -1, 40, -1, -1, 97, -1, 45, -1, -1, -1, - -1, -1, 51, -1, 53, -1, -1, -1, 57, 58, - -1, 60, -1, -1, 63, -1, 65, -1, -1, 122, - -1, -1, -1, 72, -1, -1, -1, -1, -1, 78, - 79, 134, -1, 82, -1, 84, 85, 86, -1, -1, - -1, -1, 91, -1, -1, -1, -1, -1, 151, 4, - -1, 154, 155, 156, -1, -1, 159, 160, -1, -1, - -1, -1, -1, -1, -1, 114, -1, 170, -1, 118, - 119, 120, -1, 28, 123, 30, 125, -1, -1, -1, - 129, 36, 37, -1, -1, 40, 135, 136, -1, 138, - 45, -1, -1, -1, 143, 144, 51, -1, 53, -1, - -1, -1, 57, 58, -1, 60, -1, -1, 63, -1, - 65, -1, -1, -1, -1, -1, -1, 72, 167, -1, - -1, -1, -1, 78, -1, -1, -1, 82, -1, 84, - 85, 86, -1, -1, -1, -1, 91, -1, -1, -1, - -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 12, 13, 14, 114, - -1, 17, 18, 118, 119, 120, -1, 28, 123, 30, - 125, -1, -1, -1, 129, 36, -1, -1, -1, 40, - 135, 136, -1, 138, -1, -1, -1, -1, 143, 144, - -1, -1, 53, 4, -1, -1, 57, 58, -1, 60, - -1, -1, 63, -1, 65, -1, -1, -1, -1, -1, - -1, 72, 167, -1, -1, -1, -1, 28, -1, 30, - -1, 82, -1, 84, 85, 36, -1, -1, -1, 40, - 91, 12, 13, 14, 15, 16, 17, 18, 19, 20, - -1, -1, 53, -1, -1, -1, 57, 58, -1, 60, - -1, -1, 63, 114, 65, -1, -1, 118, 119, 120, - -1, 72, 123, -1, 125, -1, -1, -1, 129, -1, - -1, 82, -1, 84, 85, 136, -1, 138, -1, -1, - 91, -1, 143, 144, 12, 13, 14, 15, 16, 17, - 18, 19, 20, -1, -1, -1, 152, 153, 154, 155, - 156, 157, 158, 114, -1, -1, 167, 118, 119, 120, - 166, 167, 123, -1, 125, -1, -1, -1, 129, -1, - -1, -1, -1, -1, -1, 136, -1, 138, -1, -1, - -1, -1, 143, 144, 12, 13, 14, 15, 16, 17, - 18, 19, 20, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 167, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 147, -1, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, -1, -1, - -1, -1, -1, -1, -1, 166, 167, -1, -1, -1, - 171, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 150, -1, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 12, 13, 14, 15, 16, 17, 18, 169, + 170, 171, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, -1, -1, -1, -1, -1, -1, + -1, 169, 170, -1, -1, -1, -1, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, -1, -1, -1, + -1, -1, -1, -1, 169, 170, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 12, 13, 14, 15, 16, 17, 18, -1, 20, 147, - -1, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, -1, -1, -1, -1, -1, -1, -1, 166, 167, - -1, -1, -1, 171, 12, 13, 14, 15, 16, 17, - 18, 19, 20, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 12, 13, 14, 15, 16, 17, 18, 147, - -1, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 12, 13, 14, 15, 16, 17, 18, 166, 167, - -1, -1, 147, 171, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 12, 13, 14, 15, 16, 17, - 18, 166, 167, 168, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 12, 13, - 14, 15, 16, 17, 18, 166, 167, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, -1, -1, -1, - -1, -1, -1, -1, 166, 167, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 147, - -1, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, -1, -1, -1, -1, -1, -1, -1, 166, 167, - 150, 151, 152, 153, 154, 155, 156, 157, 158, -1, - -1, -1, -1, -1, -1, -1, 166, 167, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, -1, -1, - -1, -1, -1, -1, -1, 166, 167, -1, -1, -1, - -1, 4, -1, 151, 152, 153, 154, 155, 156, 157, - 158, -1, -1, -1, -1, -1, -1, -1, 166, 167, - -1, -1, -1, -1, -1, 28, -1, 30, -1, -1, - -1, -1, -1, 36, 37, -1, -1, 40, 152, 153, - 154, 155, 156, 157, 158, -1, -1, -1, 51, -1, - 53, -1, 166, 167, 57, 58, -1, 60, -1, -1, - 63, -1, 65, -1, -1, -1, -1, -1, -1, 72, - -1, -1, -1, -1, -1, -1, -1, -1, 4, 82, - -1, 84, 85, 86, -1, -1, 89, -1, 91, -1, - 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 28, -1, 30, -1, -1, -1, -1, -1, - 36, 114, -1, -1, 40, 118, 119, 120, -1, -1, - 123, 4, 125, -1, -1, -1, 129, 53, -1, -1, - -1, 57, 58, 136, 60, 138, -1, 63, -1, 65, - 143, 144, -1, -1, -1, 28, 72, 30, -1, -1, - -1, -1, -1, 36, -1, -1, 82, -1, 84, 85, - -1, -1, -1, -1, -1, 91, -1, -1, -1, -1, - 53, -1, -1, -1, 57, 58, -1, -1, -1, -1, - 63, -1, 65, -1, -1, -1, -1, -1, 114, 72, - -1, -1, 118, 119, 120, -1, -1, 123, -1, 125, - -1, 84, 85, 129, -1, -1, -1, -1, 91, -1, - 136, -1, 138, -1, -1, -1, -1, 143, 144, -1, + -1, 150, -1, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, -1, -1, -1, -1, -1, -1, -1, + 169, 170, 153, 154, 155, 156, 157, 158, 159, 160, + 161, -1, -1, -1, -1, -1, 4, -1, 169, 170, + -1, -1, 154, 155, 156, 157, 158, 159, 160, 161, + -1, -1, -1, -1, -1, -1, -1, 169, 170, -1, + -1, -1, 30, -1, 32, -1, -1, -1, -1, -1, + 38, 39, -1, -1, 42, 155, 156, 157, 158, 159, + 160, 161, -1, -1, -1, 53, -1, 55, -1, 169, + 170, 59, 60, -1, 62, -1, -1, 65, -1, 67, + -1, -1, -1, -1, -1, -1, 74, -1, -1, -1, + -1, -1, -1, -1, 4, -1, 84, -1, 86, 87, + 88, 89, -1, -1, 92, -1, 94, -1, 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 118, 119, 120, -1, -1, - 123, -1, -1, -1, -1, -1, 129, -1, -1, -1, - -1, -1, -1, 136, -1, 138, -1, -1, -1, -1, - 143, 144, 21, -1, 23, 24, -1, 26, 27, -1, - 29, -1, -1, 32, -1, 34, -1, -1, -1, -1, - -1, -1, 41, 42, 43, 44, -1, 46, 47, 48, - 49, 50, -1, 52, -1, 54, 55, 56, -1, -1, - 59, -1, -1, -1, -1, 64, -1, 66, 67, 68, - 69, 70, 71, -1, 73, 74, 75, 76, 77, -1, - -1, 80, -1, -1, 83, -1, -1, -1, 87, 88, - -1, 90, -1, -1, -1, 94, 95, 96, -1, 98, - 99, 100, 101, 102, -1, 104, -1, 106, 107, 108, - 109, 110, 111, 112, 113, -1, 115, 116, 117, -1, - -1, -1, 121, -1, -1, 124, -1, -1, 127, 128, - -1, -1, 131, 132, 133, -1, -1, -1, 137, -1, - 139, 140, 141, 142, -1, -1, 145 + 30, -1, 32, -1, -1, -1, -1, -1, 38, 117, + -1, -1, 42, 121, 122, 123, -1, -1, 126, -1, + 128, -1, -1, -1, 132, 55, -1, -1, -1, 59, + 60, 139, 62, 141, -1, 65, -1, 67, 146, 147, + -1, -1, -1, -1, 74, -1, -1, -1, -1, 4, + -1, -1, -1, -1, 84, -1, 86, 87, 88, -1, + -1, -1, -1, -1, 94, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 30, -1, 32, -1, -1, + -1, -1, -1, 38, -1, -1, -1, 117, -1, -1, + -1, 121, 122, 123, -1, -1, 126, -1, 128, -1, + 55, -1, 132, -1, 59, 60, -1, -1, -1, 139, + 65, 141, 67, -1, -1, -1, 146, 147, -1, 74, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 86, 87, 88, -1, -1, -1, -1, -1, 94, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 121, 122, 123, -1, + -1, 126, -1, -1, -1, -1, 22, 132, 24, 25, + 26, -1, 28, 29, 139, 31, 141, -1, 34, -1, + 36, 146, 147, -1, -1, -1, -1, 43, 44, 45, + 46, -1, 48, 49, 50, 51, 52, -1, 54, -1, + 56, 57, 58, -1, -1, 61, -1, -1, -1, -1, + 66, -1, 68, 69, 70, 71, 72, 73, -1, 75, + 76, 77, 78, 79, -1, -1, 82, -1, -1, 85, + -1, -1, -1, -1, 90, 91, -1, 93, -1, -1, + -1, 97, 98, 99, -1, 101, 102, 103, 104, 105, + -1, 107, -1, 109, 110, 111, 112, 113, 114, 115, + 116, -1, 118, 119, 120, -1, -1, -1, 124, -1, + -1, 127, -1, -1, 130, 131, -1, -1, 134, 135, + 136, -1, -1, -1, 140, -1, 142, 143, 144, 145, + -1, -1, 148 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint16 yystos[] = { - 0, 176, 177, 0, 4, 28, 30, 36, 37, 40, - 45, 51, 53, 57, 58, 60, 63, 65, 72, 78, - 82, 84, 85, 86, 91, 114, 118, 119, 120, 123, - 125, 129, 135, 136, 138, 143, 144, 167, 181, 182, - 183, 184, 185, 188, 189, 196, 207, 221, 225, 227, - 228, 229, 230, 233, 234, 237, 239, 240, 241, 242, - 244, 245, 246, 247, 248, 250, 252, 258, 259, 260, - 261, 3, 4, 170, 3, 4, 3, 4, 223, 84, - 226, 8, 3, 4, 226, 170, 226, 227, 3, 223, - 195, 196, 3, 223, 227, 21, 23, 24, 26, 27, - 29, 32, 34, 41, 42, 43, 44, 46, 47, 48, - 49, 50, 52, 54, 55, 56, 59, 64, 66, 67, - 68, 69, 70, 71, 73, 74, 75, 76, 77, 80, - 83, 87, 88, 90, 94, 95, 96, 98, 99, 100, - 101, 102, 104, 106, 107, 108, 109, 110, 111, 112, - 113, 115, 116, 117, 121, 124, 127, 128, 131, 132, - 133, 137, 139, 140, 141, 142, 145, 197, 199, 257, - 169, 178, 178, 89, 93, 187, 207, 228, 233, 239, - 243, 250, 258, 261, 169, 169, 172, 169, 172, 169, - 180, 169, 148, 238, 172, 251, 252, 251, 251, 3, - 4, 35, 62, 103, 126, 156, 170, 201, 224, 253, - 254, 256, 207, 258, 259, 261, 251, 169, 8, 172, - 169, 259, 172, 250, 130, 172, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 146, 168, 11, 79, 181, 186, 189, 228, 230, - 241, 242, 245, 173, 3, 3, 4, 172, 256, 231, - 105, 235, 239, 3, 4, 172, 179, 249, 253, 253, - 174, 167, 170, 194, 251, 171, 204, 205, 206, 224, - 171, 214, 253, 255, 170, 217, 224, 3, 5, 6, - 7, 8, 9, 61, 97, 122, 134, 151, 154, 155, - 156, 159, 160, 170, 210, 211, 212, 210, 213, 8, - 8, 198, 213, 212, 8, 8, 212, 8, 212, 210, - 65, 212, 208, 209, 210, 257, 212, 208, 210, 259, - 259, 8, 10, 200, 5, 262, 259, 199, 167, 170, - 169, 180, 173, 195, 232, 148, 92, 195, 219, 236, - 169, 172, 179, 173, 181, 196, 248, 253, 171, 213, - 156, 209, 143, 190, 191, 192, 193, 196, 250, 173, - 146, 174, 173, 195, 215, 146, 219, 173, 196, 216, - 219, 171, 170, 210, 210, 210, 210, 210, 210, 210, - 259, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 147, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 166, 167, 146, 171, 171, 171, 146, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 3, 171, 146, - 171, 171, 146, 171, 171, 171, 171, 171, 166, 171, - 171, 199, 8, 180, 242, 148, 250, 169, 173, 195, - 220, 173, 185, 173, 180, 168, 168, 171, 146, 250, - 253, 206, 212, 250, 261, 253, 171, 169, 169, 259, - 171, 171, 210, 210, 3, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 3, 210, 212, 8, 171, 209, 212, 5, - 171, 253, 250, 169, 179, 180, 193, 253, 255, 169, - 222, 224, 171, 210, 148, 168, 171, 180, 253, 173, - 169, 172, 210, 180, 202, 34, 46, 173, 203, 212, - 148, 148, 169, 218, 219, 218, 169 + 0, 179, 180, 0, 4, 30, 32, 38, 39, 42, + 47, 53, 55, 59, 60, 62, 65, 67, 74, 80, + 84, 86, 87, 88, 89, 94, 117, 121, 122, 123, + 126, 128, 132, 138, 139, 141, 146, 147, 170, 184, + 185, 186, 187, 188, 191, 192, 199, 210, 224, 228, + 230, 231, 232, 233, 236, 237, 240, 242, 243, 244, + 245, 247, 248, 249, 250, 251, 253, 255, 272, 273, + 274, 275, 3, 4, 173, 3, 4, 3, 4, 226, + 86, 229, 8, 3, 4, 229, 173, 229, 230, 3, + 226, 198, 199, 3, 226, 230, 22, 24, 25, 26, + 28, 29, 31, 34, 36, 43, 44, 45, 46, 48, + 49, 50, 51, 52, 54, 56, 57, 58, 61, 66, + 68, 69, 70, 71, 72, 73, 75, 76, 77, 78, + 79, 82, 85, 90, 91, 93, 97, 98, 99, 101, + 102, 103, 104, 105, 107, 109, 110, 111, 112, 113, + 114, 115, 116, 118, 119, 120, 124, 127, 130, 131, + 134, 135, 136, 140, 142, 143, 144, 145, 148, 200, + 202, 271, 172, 181, 181, 92, 96, 190, 210, 231, + 236, 242, 246, 253, 272, 275, 172, 172, 175, 172, + 175, 172, 183, 172, 151, 241, 175, 254, 255, 254, + 254, 3, 4, 37, 64, 106, 129, 159, 173, 204, + 227, 256, 257, 270, 210, 272, 273, 275, 254, 172, + 8, 175, 172, 273, 175, 253, 133, 175, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 149, 171, 11, 81, 184, 189, + 192, 231, 233, 244, 245, 248, 176, 3, 3, 4, + 175, 270, 234, 108, 238, 242, 3, 4, 175, 182, + 252, 256, 256, 177, 170, 173, 197, 254, 174, 207, + 208, 209, 227, 174, 217, 256, 266, 173, 220, 8, + 227, 3, 5, 6, 7, 8, 9, 63, 100, 125, + 137, 154, 157, 158, 159, 162, 163, 173, 213, 214, + 215, 213, 216, 8, 8, 201, 216, 215, 8, 8, + 215, 8, 215, 213, 67, 215, 211, 212, 213, 271, + 215, 211, 213, 273, 273, 8, 10, 203, 5, 276, + 273, 202, 170, 173, 172, 183, 176, 198, 235, 151, + 95, 198, 222, 239, 172, 175, 182, 176, 184, 199, + 251, 256, 174, 216, 159, 212, 193, 194, 195, 196, + 199, 253, 176, 149, 177, 176, 198, 218, 149, 222, + 176, 199, 219, 222, 174, 174, 173, 213, 213, 213, + 213, 213, 213, 213, 253, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 150, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 169, 170, 149, 174, 174, + 174, 149, 174, 174, 174, 174, 174, 174, 174, 174, + 174, 3, 174, 149, 174, 174, 149, 174, 174, 174, + 174, 174, 169, 174, 174, 202, 8, 183, 245, 151, + 253, 172, 176, 198, 223, 176, 188, 176, 183, 171, + 171, 174, 149, 253, 159, 173, 197, 204, 227, 262, + 264, 265, 209, 215, 253, 275, 256, 174, 172, 172, + 253, 174, 159, 173, 197, 204, 258, 260, 261, 213, + 213, 3, 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, 213, 3, + 213, 215, 8, 174, 212, 215, 5, 174, 256, 253, + 172, 182, 183, 21, 196, 264, 252, 159, 193, 204, + 263, 264, 173, 197, 262, 268, 269, 172, 225, 227, + 260, 252, 159, 193, 204, 259, 260, 174, 173, 197, + 151, 171, 174, 183, 256, 176, 264, 252, 174, 264, + 174, 193, 151, 267, 149, 172, 175, 174, 260, 252, + 174, 264, 174, 213, 193, 213, 183, 264, 174, 216, + 268, 205, 264, 174, 36, 48, 176, 206, 215, 151, + 151, 172, 221, 222, 221, 172 }; #define yyerrok (yyerrstatus = 0) @@ -2513,7 +2643,7 @@ yyreduce: case 2: /* Line 1455 of yacc.c */ -#line 326 "parser.y" +#line 330 "parser.y" { fix_incomplete(); check_statements((yyvsp[(1) - (1)].stmt_list), FALSE); check_all_user_types((yyvsp[(1) - (1)].stmt_list)); @@ -2530,28 +2660,28 @@ yyreduce: case 3: /* Line 1455 of yacc.c */ -#line 339 "parser.y" +#line 343 "parser.y" { (yyval.stmt_list) = NULL; ;} break; case 4: /* Line 1455 of yacc.c */ -#line 340 "parser.y" +#line 344 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_reference((yyvsp[(2) - (2)].type))); ;} break; case 5: /* Line 1455 of yacc.c */ -#line 341 "parser.y" +#line 345 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_type_decl((yyvsp[(2) - (2)].type))); ;} break; case 6: /* Line 1455 of yacc.c */ -#line 342 "parser.y" +#line 346 "parser.y" { (yyval.stmt_list) = (yyvsp[(1) - (3)].stmt_list); reg_type((yyvsp[(2) - (3)].type), (yyvsp[(2) - (3)].type)->name, 0); ;} @@ -2560,7 +2690,7 @@ yyreduce: case 7: /* Line 1455 of yacc.c */ -#line 345 "parser.y" +#line 349 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_type_decl((yyvsp[(2) - (2)].type))); reg_type((yyvsp[(2) - (2)].type), (yyvsp[(2) - (2)].type)->name, 0); ;} @@ -2569,56 +2699,56 @@ yyreduce: case 8: /* Line 1455 of yacc.c */ -#line 348 "parser.y" +#line 352 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_module((yyvsp[(2) - (2)].type))); ;} break; case 9: /* Line 1455 of yacc.c */ -#line 349 "parser.y" +#line 353 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_library((yyvsp[(2) - (2)].typelib))); ;} break; case 10: /* Line 1455 of yacc.c */ -#line 350 "parser.y" +#line 354 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), (yyvsp[(2) - (2)].statement)); ;} break; case 11: /* Line 1455 of yacc.c */ -#line 353 "parser.y" +#line 357 "parser.y" { (yyval.stmt_list) = NULL; ;} break; case 12: /* Line 1455 of yacc.c */ -#line 354 "parser.y" +#line 358 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_reference((yyvsp[(2) - (2)].type))); ;} break; case 13: /* Line 1455 of yacc.c */ -#line 355 "parser.y" +#line 359 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_type_decl((yyvsp[(2) - (2)].type))); ;} break; case 14: /* Line 1455 of yacc.c */ -#line 356 "parser.y" +#line 360 "parser.y" { (yyval.stmt_list) = (yyvsp[(1) - (3)].stmt_list); reg_type((yyvsp[(2) - (3)].type), (yyvsp[(2) - (3)].type)->name, 0); ;} break; case 15: /* Line 1455 of yacc.c */ -#line 357 "parser.y" +#line 361 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_type_decl((yyvsp[(2) - (2)].type))); reg_type((yyvsp[(2) - (2)].type), (yyvsp[(2) - (2)].type)->name, 0); ;} @@ -2627,112 +2757,112 @@ yyreduce: case 16: /* Line 1455 of yacc.c */ -#line 360 "parser.y" +#line 364 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_module((yyvsp[(2) - (2)].type))); ;} break; case 17: /* Line 1455 of yacc.c */ -#line 361 "parser.y" +#line 365 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), (yyvsp[(2) - (2)].statement)); ;} break; case 18: /* Line 1455 of yacc.c */ -#line 362 "parser.y" +#line 366 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_importlib((yyvsp[(2) - (2)].str))); ;} break; case 19: /* Line 1455 of yacc.c */ -#line 363 "parser.y" +#line 367 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), make_statement_library((yyvsp[(2) - (2)].typelib))); ;} break; case 20: /* Line 1455 of yacc.c */ -#line 366 "parser.y" +#line 370 "parser.y" { (yyval.stmt_list) = NULL; ;} break; case 21: /* Line 1455 of yacc.c */ -#line 367 "parser.y" +#line 371 "parser.y" { (yyval.stmt_list) = append_statement((yyvsp[(1) - (2)].stmt_list), (yyvsp[(2) - (2)].statement)); ;} break; case 24: /* Line 1455 of yacc.c */ -#line 375 "parser.y" +#line 379 "parser.y" { (yyval.statement) = make_statement_cppquote((yyvsp[(1) - (1)].str)); ;} break; case 25: /* Line 1455 of yacc.c */ -#line 376 "parser.y" +#line 380 "parser.y" { (yyval.statement) = make_statement_type_decl((yyvsp[(1) - (2)].type)); ;} break; case 26: /* Line 1455 of yacc.c */ -#line 377 "parser.y" +#line 381 "parser.y" { (yyval.statement) = make_statement_declaration((yyvsp[(1) - (2)].var)); ;} break; case 27: /* Line 1455 of yacc.c */ -#line 378 "parser.y" +#line 382 "parser.y" { (yyval.statement) = make_statement_import((yyvsp[(1) - (1)].str)); ;} break; case 28: /* Line 1455 of yacc.c */ -#line 379 "parser.y" +#line 383 "parser.y" { (yyval.statement) = (yyvsp[(1) - (2)].statement); ;} break; case 32: /* Line 1455 of yacc.c */ -#line 386 "parser.y" +#line 390 "parser.y" { (yyval.type) = (yyvsp[(2) - (2)].type); (yyval.type)->attrs = check_enum_attrs((yyvsp[(1) - (2)].attr_list)); ;} break; case 33: /* Line 1455 of yacc.c */ -#line 387 "parser.y" +#line 391 "parser.y" { (yyval.type) = (yyvsp[(2) - (2)].type); (yyval.type)->attrs = check_struct_attrs((yyvsp[(1) - (2)].attr_list)); ;} break; case 34: /* Line 1455 of yacc.c */ -#line 388 "parser.y" +#line 392 "parser.y" { (yyval.type) = (yyvsp[(2) - (2)].type); (yyval.type)->attrs = check_union_attrs((yyvsp[(1) - (2)].attr_list)); ;} break; case 35: /* Line 1455 of yacc.c */ -#line 391 "parser.y" +#line 395 "parser.y" { (yyval.str) = (yyvsp[(3) - (4)].str); ;} break; case 36: /* Line 1455 of yacc.c */ -#line 393 "parser.y" +#line 397 "parser.y" { assert(yychar == YYEMPTY); (yyval.import) = xmalloc(sizeof(struct _import_t)); (yyval.import)->name = (yyvsp[(2) - (3)].str); @@ -2744,7 +2874,7 @@ yyreduce: case 37: /* Line 1455 of yacc.c */ -#line 401 "parser.y" +#line 405 "parser.y" { (yyval.str) = (yyvsp[(1) - (3)].import)->name; if ((yyvsp[(1) - (3)].import)->import_performed) pop_import(); free((yyvsp[(1) - (3)].import)); @@ -2754,21 +2884,21 @@ yyreduce: case 38: /* Line 1455 of yacc.c */ -#line 408 "parser.y" +#line 412 "parser.y" { (yyval.str) = (yyvsp[(3) - (5)].str); if(!parse_only) add_importlib((yyvsp[(3) - (5)].str)); ;} break; case 39: /* Line 1455 of yacc.c */ -#line 411 "parser.y" +#line 415 "parser.y" { (yyval.str) = (yyvsp[(2) - (2)].str); ;} break; case 40: /* Line 1455 of yacc.c */ -#line 413 "parser.y" +#line 417 "parser.y" { (yyval.typelib) = make_library((yyvsp[(2) - (3)].str), check_library_attrs((yyvsp[(2) - (3)].str), (yyvsp[(1) - (3)].attr_list))); if (!parse_only) start_typelib((yyval.typelib)); ;} @@ -2777,7 +2907,7 @@ yyreduce: case 41: /* Line 1455 of yacc.c */ -#line 418 "parser.y" +#line 422 "parser.y" { (yyval.typelib) = (yyvsp[(1) - (4)].typelib); (yyval.typelib)->stmts = (yyvsp[(2) - (4)].stmt_list); if (!parse_only) end_typelib(); @@ -2787,692 +2917,686 @@ yyreduce: case 42: /* Line 1455 of yacc.c */ -#line 424 "parser.y" +#line 428 "parser.y" { (yyval.var_list) = NULL; ;} break; case 44: /* Line 1455 of yacc.c */ -#line 428 "parser.y" - { (yyval.var_list) = NULL; ;} +#line 432 "parser.y" + { check_arg_attrs((yyvsp[(1) - (1)].var)); (yyval.var_list) = append_var( NULL, (yyvsp[(1) - (1)].var) ); ;} break; case 45: /* Line 1455 of yacc.c */ -#line 431 "parser.y" - { check_arg((yyvsp[(1) - (1)].var)); (yyval.var_list) = append_var( NULL, (yyvsp[(1) - (1)].var) ); ;} +#line 433 "parser.y" + { check_arg_attrs((yyvsp[(3) - (3)].var)); (yyval.var_list) = append_var( (yyvsp[(1) - (3)].var_list), (yyvsp[(3) - (3)].var) ); ;} break; - case 46: + case 47: /* Line 1455 of yacc.c */ -#line 432 "parser.y" - { check_arg((yyvsp[(3) - (3)].var)); (yyval.var_list) = append_var( (yyvsp[(1) - (3)].var_list), (yyvsp[(3) - (3)].var)); ;} +#line 437 "parser.y" + { (yyval.var_list) = append_var( (yyvsp[(1) - (3)].var_list), make_var(strdup("...")) ); ;} break; case 48: /* Line 1455 of yacc.c */ -#line 437 "parser.y" - { (yyval.var) = (yyvsp[(3) - (3)].declarator)->var; - (yyval.var)->attrs = (yyvsp[(1) - (3)].attr_list); - if ((yyvsp[(2) - (3)].declspec)->stgclass != STG_NONE && (yyvsp[(2) - (3)].declspec)->stgclass != STG_REGISTER) +#line 441 "parser.y" + { if ((yyvsp[(2) - (3)].declspec)->stgclass != STG_NONE && (yyvsp[(2) - (3)].declspec)->stgclass != STG_REGISTER) error_loc("invalid storage class for function parameter\n"); - set_type((yyval.var), (yyvsp[(2) - (3)].declspec), (yyvsp[(3) - (3)].declarator), TRUE); - free((yyvsp[(3) - (3)].declarator)); + (yyval.var) = declare_var((yyvsp[(1) - (3)].attr_list), (yyvsp[(2) - (3)].declspec), (yyvsp[(3) - (3)].declarator), TRUE); + free((yyvsp[(2) - (3)].declspec)); free((yyvsp[(3) - (3)].declarator)); ;} break; case 49: /* Line 1455 of yacc.c */ -#line 444 "parser.y" - { (yyval.var) = (yyvsp[(2) - (2)].declarator)->var; - if ((yyvsp[(1) - (2)].declspec)->stgclass != STG_NONE && (yyvsp[(1) - (2)].declspec)->stgclass != STG_REGISTER) +#line 446 "parser.y" + { if ((yyvsp[(1) - (2)].declspec)->stgclass != STG_NONE && (yyvsp[(1) - (2)].declspec)->stgclass != STG_REGISTER) error_loc("invalid storage class for function parameter\n"); - set_type((yyval.var), (yyvsp[(1) - (2)].declspec), (yyvsp[(2) - (2)].declarator), TRUE); - free((yyvsp[(2) - (2)].declarator)); + (yyval.var) = declare_var(NULL, (yyvsp[(1) - (2)].declspec), (yyvsp[(2) - (2)].declarator), TRUE); + free((yyvsp[(1) - (2)].declspec)); free((yyvsp[(2) - (2)].declarator)); ;} break; case 50: /* Line 1455 of yacc.c */ -#line 452 "parser.y" +#line 453 "parser.y" { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} break; case 51: /* Line 1455 of yacc.c */ -#line 453 "parser.y" +#line 454 "parser.y" { (yyval.expr) = make_expr(EXPR_VOID); ;} break; case 52: /* Line 1455 of yacc.c */ -#line 456 "parser.y" +#line 457 "parser.y" { (yyval.attr_list) = NULL; ;} break; case 54: /* Line 1455 of yacc.c */ -#line 461 "parser.y" +#line 462 "parser.y" { (yyval.attr_list) = (yyvsp[(2) - (3)].attr_list); ;} break; case 55: /* Line 1455 of yacc.c */ -#line 464 "parser.y" +#line 465 "parser.y" { (yyval.attr_list) = append_attr( NULL, (yyvsp[(1) - (1)].attr) ); ;} break; case 56: /* Line 1455 of yacc.c */ -#line 465 "parser.y" +#line 466 "parser.y" { (yyval.attr_list) = append_attr( (yyvsp[(1) - (3)].attr_list), (yyvsp[(3) - (3)].attr) ); ;} break; case 57: /* Line 1455 of yacc.c */ -#line 466 "parser.y" +#line 467 "parser.y" { (yyval.attr_list) = append_attr( (yyvsp[(1) - (4)].attr_list), (yyvsp[(4) - (4)].attr) ); ;} break; case 58: /* Line 1455 of yacc.c */ -#line 469 "parser.y" +#line 470 "parser.y" { (yyval.str_list) = append_str( NULL, (yyvsp[(1) - (1)].str) ); ;} break; case 59: /* Line 1455 of yacc.c */ -#line 470 "parser.y" +#line 471 "parser.y" { (yyval.str_list) = append_str( (yyvsp[(1) - (3)].str_list), (yyvsp[(3) - (3)].str) ); ;} break; case 60: /* Line 1455 of yacc.c */ -#line 473 "parser.y" +#line 474 "parser.y" { (yyval.attr) = NULL; ;} break; case 61: /* Line 1455 of yacc.c */ -#line 474 "parser.y" +#line 475 "parser.y" { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); ;} break; case 62: /* Line 1455 of yacc.c */ -#line 475 "parser.y" - { (yyval.attr) = make_attr(ATTR_APPOBJECT); ;} +#line 476 "parser.y" + { (yyval.attr) = make_attrp(ATTR_ANNOTATION, (yyvsp[(3) - (4)].str)); ;} break; case 63: /* Line 1455 of yacc.c */ -#line 476 "parser.y" - { (yyval.attr) = make_attr(ATTR_ASYNC); ;} +#line 477 "parser.y" + { (yyval.attr) = make_attr(ATTR_APPOBJECT); ;} break; case 64: /* Line 1455 of yacc.c */ -#line 477 "parser.y" - { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); ;} +#line 478 "parser.y" + { (yyval.attr) = make_attr(ATTR_ASYNC); ;} break; case 65: /* Line 1455 of yacc.c */ -#line 478 "parser.y" - { (yyval.attr) = make_attr(ATTR_BINDABLE); ;} +#line 479 "parser.y" + { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); ;} break; case 66: /* Line 1455 of yacc.c */ -#line 479 "parser.y" - { (yyval.attr) = make_attr(ATTR_BROADCAST); ;} +#line 480 "parser.y" + { (yyval.attr) = make_attr(ATTR_BINDABLE); ;} break; case 67: /* Line 1455 of yacc.c */ -#line 480 "parser.y" - { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[(3) - (4)].var)); ;} +#line 481 "parser.y" + { (yyval.attr) = make_attr(ATTR_BROADCAST); ;} break; case 68: /* Line 1455 of yacc.c */ -#line 481 "parser.y" - { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[(3) - (4)].expr_list)); ;} +#line 482 "parser.y" + { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[(3) - (4)].var)); ;} break; case 69: /* Line 1455 of yacc.c */ -#line 482 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); ;} +#line 483 "parser.y" + { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[(3) - (4)].expr_list)); ;} break; case 70: /* Line 1455 of yacc.c */ -#line 483 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;} +#line 484 "parser.y" + { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); ;} break; case 71: /* Line 1455 of yacc.c */ -#line 484 "parser.y" - { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;} +#line 485 "parser.y" + { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;} break; case 72: /* Line 1455 of yacc.c */ -#line 485 "parser.y" - { (yyval.attr) = make_attr(ATTR_CONTROL); ;} +#line 486 "parser.y" + { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;} break; case 73: /* Line 1455 of yacc.c */ -#line 486 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULT); ;} +#line 487 "parser.y" + { (yyval.attr) = make_attr(ATTR_CONTROL); ;} break; case 74: /* Line 1455 of yacc.c */ -#line 487 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); ;} +#line 488 "parser.y" + { (yyval.attr) = make_attr(ATTR_DEFAULT); ;} break; case 75: /* Line 1455 of yacc.c */ -#line 488 "parser.y" - { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE, (yyvsp[(3) - (4)].expr)); ;} +#line 489 "parser.y" + { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); ;} break; case 76: /* Line 1455 of yacc.c */ -#line 489 "parser.y" - { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); ;} +#line 490 "parser.y" + { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE, (yyvsp[(3) - (4)].expr)); ;} break; case 77: /* Line 1455 of yacc.c */ -#line 490 "parser.y" - { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); ;} +#line 491 "parser.y" + { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); ;} break; case 78: /* Line 1455 of yacc.c */ -#line 491 "parser.y" - { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[(3) - (4)].str)); ;} +#line 492 "parser.y" + { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); ;} break; case 79: /* Line 1455 of yacc.c */ -#line 492 "parser.y" - { (yyval.attr) = make_attr(ATTR_DUAL); ;} +#line 493 "parser.y" + { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[(3) - (4)].str)); ;} break; case 80: /* Line 1455 of yacc.c */ -#line 493 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[(3) - (4)].str_list)); ;} +#line 494 "parser.y" + { (yyval.attr) = make_attr(ATTR_DUAL); ;} break; case 81: /* Line 1455 of yacc.c */ -#line 494 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ENTRY, (yyvsp[(3) - (4)].expr)); ;} +#line 495 "parser.y" + { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[(3) - (4)].str_list)); ;} break; case 82: /* Line 1455 of yacc.c */ -#line 495 "parser.y" - { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); ;} +#line 496 "parser.y" + { (yyval.attr) = make_attrp(ATTR_ENTRY, (yyvsp[(3) - (4)].expr)); ;} break; case 83: /* Line 1455 of yacc.c */ -#line 496 "parser.y" - { (yyval.attr) = make_attr(ATTR_HANDLE); ;} +#line 497 "parser.y" + { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); ;} break; case 84: /* Line 1455 of yacc.c */ -#line 497 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[(3) - (4)].expr)); ;} +#line 498 "parser.y" + { (yyval.attr) = make_attr(ATTR_HANDLE); ;} break; case 85: /* Line 1455 of yacc.c */ -#line 498 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[(3) - (4)].str)); ;} +#line 499 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[(3) - (4)].expr)); ;} break; case 86: /* Line 1455 of yacc.c */ -#line 499 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[(3) - (4)].str)); ;} +#line 500 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[(3) - (4)].str)); ;} break; case 87: /* Line 1455 of yacc.c */ -#line 500 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[(3) - (4)].expr)); ;} +#line 501 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[(3) - (4)].str)); ;} break; case 88: /* Line 1455 of yacc.c */ -#line 501 "parser.y" - { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[(3) - (4)].str)); ;} +#line 502 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[(3) - (4)].expr)); ;} break; case 89: /* Line 1455 of yacc.c */ -#line 502 "parser.y" - { (yyval.attr) = make_attr(ATTR_HIDDEN); ;} +#line 503 "parser.y" + { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[(3) - (4)].str)); ;} break; case 90: /* Line 1455 of yacc.c */ -#line 503 "parser.y" - { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[(3) - (4)].expr)); ;} +#line 504 "parser.y" + { (yyval.attr) = make_attr(ATTR_HIDDEN); ;} break; case 91: /* Line 1455 of yacc.c */ -#line 504 "parser.y" - { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); ;} +#line 505 "parser.y" + { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[(3) - (4)].expr)); ;} break; case 92: /* Line 1455 of yacc.c */ -#line 505 "parser.y" - { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[(3) - (4)].expr)); ;} +#line 506 "parser.y" + { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); ;} break; case 93: /* Line 1455 of yacc.c */ -#line 506 "parser.y" - { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); ;} +#line 507 "parser.y" + { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[(3) - (4)].expr)); ;} break; case 94: /* Line 1455 of yacc.c */ -#line 507 "parser.y" - { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[(4) - (5)].str)); ;} +#line 508 "parser.y" + { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); ;} break; case 95: /* Line 1455 of yacc.c */ -#line 508 "parser.y" - { (yyval.attr) = make_attr(ATTR_IN); ;} +#line 509 "parser.y" + { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[(4) - (5)].str)); ;} break; case 96: /* Line 1455 of yacc.c */ -#line 509 "parser.y" - { (yyval.attr) = make_attr(ATTR_INPUTSYNC); ;} +#line 510 "parser.y" + { (yyval.attr) = make_attr(ATTR_IN); ;} break; case 97: /* Line 1455 of yacc.c */ -#line 510 "parser.y" - { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[(3) - (4)].expr_list)); ;} +#line 511 "parser.y" + { (yyval.attr) = make_attr(ATTR_INPUTSYNC); ;} break; case 98: /* Line 1455 of yacc.c */ -#line 511 "parser.y" - { (yyval.attr) = make_attrp(ATTR_LIBLCID, (yyvsp[(3) - (4)].expr)); ;} +#line 512 "parser.y" + { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[(3) - (4)].expr_list)); ;} break; case 99: /* Line 1455 of yacc.c */ -#line 512 "parser.y" - { (yyval.attr) = make_attr(ATTR_PARAMLCID); ;} +#line 513 "parser.y" + { (yyval.attr) = make_attrp(ATTR_LIBLCID, (yyvsp[(3) - (4)].expr)); ;} break; case 100: /* Line 1455 of yacc.c */ -#line 513 "parser.y" - { (yyval.attr) = make_attr(ATTR_LOCAL); ;} +#line 514 "parser.y" + { (yyval.attr) = make_attr(ATTR_PARAMLCID); ;} break; case 101: /* Line 1455 of yacc.c */ -#line 514 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); ;} +#line 515 "parser.y" + { (yyval.attr) = make_attr(ATTR_LOCAL); ;} break; case 102: /* Line 1455 of yacc.c */ -#line 515 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONCREATABLE); ;} +#line 516 "parser.y" + { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); ;} break; case 103: /* Line 1455 of yacc.c */ -#line 516 "parser.y" - { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); ;} +#line 517 "parser.y" + { (yyval.attr) = make_attr(ATTR_NONCREATABLE); ;} break; case 104: /* Line 1455 of yacc.c */ -#line 517 "parser.y" - { (yyval.attr) = make_attr(ATTR_OBJECT); ;} +#line 518 "parser.y" + { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); ;} break; case 105: /* Line 1455 of yacc.c */ -#line 518 "parser.y" - { (yyval.attr) = make_attr(ATTR_ODL); ;} +#line 519 "parser.y" + { (yyval.attr) = make_attr(ATTR_OBJECT); ;} break; case 106: /* Line 1455 of yacc.c */ -#line 519 "parser.y" - { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); ;} +#line 520 "parser.y" + { (yyval.attr) = make_attr(ATTR_ODL); ;} break; case 107: /* Line 1455 of yacc.c */ -#line 520 "parser.y" - { (yyval.attr) = make_attr(ATTR_OPTIONAL); ;} +#line 521 "parser.y" + { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); ;} break; case 108: /* Line 1455 of yacc.c */ -#line 521 "parser.y" - { (yyval.attr) = make_attr(ATTR_OUT); ;} +#line 522 "parser.y" + { (yyval.attr) = make_attr(ATTR_OPTIONAL); ;} break; case 109: /* Line 1455 of yacc.c */ -#line 522 "parser.y" - { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[(3) - (4)].num)); ;} +#line 523 "parser.y" + { (yyval.attr) = make_attr(ATTR_OUT); ;} break; case 110: /* Line 1455 of yacc.c */ -#line 523 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPGET); ;} +#line 524 "parser.y" + { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[(3) - (4)].num)); ;} break; case 111: /* Line 1455 of yacc.c */ -#line 524 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPPUT); ;} +#line 525 "parser.y" + { (yyval.attr) = make_attr(ATTR_PROPGET); ;} break; case 112: /* Line 1455 of yacc.c */ -#line 525 "parser.y" - { (yyval.attr) = make_attr(ATTR_PROPPUTREF); ;} +#line 526 "parser.y" + { (yyval.attr) = make_attr(ATTR_PROPPUT); ;} break; case 113: /* Line 1455 of yacc.c */ -#line 526 "parser.y" - { (yyval.attr) = make_attr(ATTR_PUBLIC); ;} +#line 527 "parser.y" + { (yyval.attr) = make_attr(ATTR_PROPPUTREF); ;} break; case 114: /* Line 1455 of yacc.c */ #line 528 "parser.y" - { expr_list_t *list = append_expr( NULL, (yyvsp[(3) - (6)].expr) ); - list = append_expr( list, (yyvsp[(5) - (6)].expr) ); - (yyval.attr) = make_attrp(ATTR_RANGE, list); ;} + { (yyval.attr) = make_attr(ATTR_PUBLIC); ;} break; case 115: /* Line 1455 of yacc.c */ -#line 531 "parser.y" - { (yyval.attr) = make_attr(ATTR_READONLY); ;} +#line 530 "parser.y" + { expr_list_t *list = append_expr( NULL, (yyvsp[(3) - (6)].expr) ); + list = append_expr( list, (yyvsp[(5) - (6)].expr) ); + (yyval.attr) = make_attrp(ATTR_RANGE, list); ;} break; case 116: /* Line 1455 of yacc.c */ -#line 532 "parser.y" - { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); ;} +#line 533 "parser.y" + { (yyval.attr) = make_attr(ATTR_READONLY); ;} break; case 117: /* Line 1455 of yacc.c */ -#line 533 "parser.y" - { (yyval.attr) = make_attr(ATTR_RESTRICTED); ;} +#line 534 "parser.y" + { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); ;} break; case 118: /* Line 1455 of yacc.c */ -#line 534 "parser.y" - { (yyval.attr) = make_attr(ATTR_RETVAL); ;} +#line 535 "parser.y" + { (yyval.attr) = make_attr(ATTR_RESTRICTED); ;} break; case 119: /* Line 1455 of yacc.c */ -#line 535 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[(3) - (4)].expr_list)); ;} +#line 536 "parser.y" + { (yyval.attr) = make_attr(ATTR_RETVAL); ;} break; case 120: /* Line 1455 of yacc.c */ -#line 536 "parser.y" - { (yyval.attr) = make_attr(ATTR_SOURCE); ;} +#line 537 "parser.y" + { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[(3) - (4)].expr_list)); ;} break; case 121: /* Line 1455 of yacc.c */ -#line 537 "parser.y" - { (yyval.attr) = make_attr(ATTR_STRICTCONTEXTHANDLE); ;} +#line 538 "parser.y" + { (yyval.attr) = make_attr(ATTR_SOURCE); ;} break; case 122: /* Line 1455 of yacc.c */ -#line 538 "parser.y" - { (yyval.attr) = make_attr(ATTR_STRING); ;} +#line 539 "parser.y" + { (yyval.attr) = make_attr(ATTR_STRICTCONTEXTHANDLE); ;} break; case 123: /* Line 1455 of yacc.c */ -#line 539 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[(3) - (4)].expr)); ;} +#line 540 "parser.y" + { (yyval.attr) = make_attr(ATTR_STRING); ;} break; case 124: /* Line 1455 of yacc.c */ -#line 540 "parser.y" - { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[(3) - (4)].type)); ;} +#line 541 "parser.y" + { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[(3) - (4)].expr)); ;} break; case 125: /* Line 1455 of yacc.c */ -#line 541 "parser.y" - { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[(3) - (4)].type)); ;} +#line 542 "parser.y" + { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[(3) - (4)].type)); ;} break; case 126: /* Line 1455 of yacc.c */ -#line 542 "parser.y" - { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[(3) - (4)].uuid)); ;} +#line 543 "parser.y" + { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[(3) - (4)].type)); ;} break; case 127: /* Line 1455 of yacc.c */ -#line 543 "parser.y" - { (yyval.attr) = make_attr(ATTR_V1ENUM); ;} +#line 544 "parser.y" + { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[(3) - (4)].uuid)); ;} break; case 128: /* Line 1455 of yacc.c */ -#line 544 "parser.y" - { (yyval.attr) = make_attr(ATTR_VARARG); ;} +#line 545 "parser.y" + { (yyval.attr) = make_attr(ATTR_V1ENUM); ;} break; case 129: /* Line 1455 of yacc.c */ -#line 545 "parser.y" - { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[(3) - (4)].num)); ;} +#line 546 "parser.y" + { (yyval.attr) = make_attr(ATTR_VARARG); ;} break; case 130: /* Line 1455 of yacc.c */ -#line 546 "parser.y" - { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[(3) - (4)].type)); ;} +#line 547 "parser.y" + { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[(3) - (4)].num)); ;} break; case 131: /* Line 1455 of yacc.c */ -#line 547 "parser.y" - { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[(1) - (1)].num)); ;} +#line 548 "parser.y" + { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[(3) - (4)].type)); ;} break; - case 133: + case 132: /* Line 1455 of yacc.c */ -#line 552 "parser.y" - { if (!is_valid_uuid((yyvsp[(1) - (1)].str))) - error_loc("invalid UUID: %s\n", (yyvsp[(1) - (1)].str)); - (yyval.uuid) = parse_uuid((yyvsp[(1) - (1)].str)); ;} +#line 549 "parser.y" + { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[(1) - (1)].num)); ;} break; case 134: /* Line 1455 of yacc.c */ -#line 557 "parser.y" - { (yyval.str) = (yyvsp[(1) - (1)].str); ;} +#line 554 "parser.y" + { if (!is_valid_uuid((yyvsp[(1) - (1)].str))) + error_loc("invalid UUID: %s\n", (yyvsp[(1) - (1)].str)); + (yyval.uuid) = parse_uuid((yyvsp[(1) - (1)].str)); ;} break; case 135: -/* Line 1455 of yacc.c */ -#line 558 "parser.y" - { (yyval.str) = (yyvsp[(1) - (1)].str); ;} - break; - - case 136: - /* Line 1455 of yacc.c */ #line 559 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 137: + case 136: /* Line 1455 of yacc.c */ #line 560 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; + case 137: + +/* Line 1455 of yacc.c */ +#line 561 "parser.y" + { (yyval.str) = (yyvsp[(1) - (1)].str); ;} + break; + case 138: /* Line 1455 of yacc.c */ -#line 563 "parser.y" - { (yyval.var_list) = NULL; ;} +#line 562 "parser.y" + { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; case 139: /* Line 1455 of yacc.c */ -#line 564 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[(1) - (2)].var_list), (yyvsp[(2) - (2)].var) ); ;} +#line 565 "parser.y" + { (yyval.var_list) = NULL; ;} break; case 140: /* Line 1455 of yacc.c */ -#line 567 "parser.y" - { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[(2) - (4)].expr) )); - (yyval.var) = (yyvsp[(4) - (4)].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); - (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); - ;} +#line 566 "parser.y" + { (yyval.var_list) = append_var( (yyvsp[(1) - (2)].var_list), (yyvsp[(2) - (2)].var) ); ;} break; case 141: /* Line 1455 of yacc.c */ -#line 571 "parser.y" - { attr_t *a = make_attr(ATTR_DEFAULT); - (yyval.var) = (yyvsp[(3) - (3)].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); +#line 569 "parser.y" + { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[(2) - (4)].expr) )); + (yyval.var) = (yyvsp[(4) - (4)].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); ;} break; @@ -3480,31 +3604,41 @@ yyreduce: case 142: /* Line 1455 of yacc.c */ -#line 577 "parser.y" - { (yyval.var_list) = NULL; ;} +#line 573 "parser.y" + { attr_t *a = make_attr(ATTR_DEFAULT); + (yyval.var) = (yyvsp[(3) - (3)].var); if (!(yyval.var)) (yyval.var) = make_var(NULL); + (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a ); + ;} break; case 143: /* Line 1455 of yacc.c */ -#line 578 "parser.y" +#line 579 "parser.y" + { (yyval.var_list) = NULL; ;} + break; + + case 144: + +/* Line 1455 of yacc.c */ +#line 580 "parser.y" { (yyval.var_list) = (yyvsp[(1) - (2)].var_list); ;} break; - case 145: + case 146: /* Line 1455 of yacc.c */ -#line 582 "parser.y" +#line 584 "parser.y" { if (!(yyvsp[(1) - (1)].var)->eval) (yyvsp[(1) - (1)].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); (yyval.var_list) = append_var( NULL, (yyvsp[(1) - (1)].var) ); ;} break; - case 146: + case 147: /* Line 1455 of yacc.c */ -#line 586 "parser.y" +#line 588 "parser.y" { if (!(yyvsp[(3) - (3)].var)->eval) { var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry ); @@ -3514,21 +3648,12 @@ yyreduce: ;} break; - case 147: - -/* Line 1455 of yacc.c */ -#line 595 "parser.y" - { (yyval.var) = reg_const((yyvsp[(1) - (3)].var)); - (yyval.var)->eval = (yyvsp[(3) - (3)].expr); - (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0); - ;} - break; - case 148: /* Line 1455 of yacc.c */ -#line 599 "parser.y" - { (yyval.var) = reg_const((yyvsp[(1) - (1)].var)); +#line 597 "parser.y" + { (yyval.var) = reg_const((yyvsp[(1) - (3)].var)); + (yyval.var)->eval = (yyvsp[(3) - (3)].expr); (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0); ;} break; @@ -3536,637 +3661,649 @@ yyreduce: case 149: /* Line 1455 of yacc.c */ -#line 604 "parser.y" - { (yyval.type) = type_new_enum((yyvsp[(2) - (5)].str), TRUE, (yyvsp[(4) - (5)].var_list)); ;} +#line 601 "parser.y" + { (yyval.var) = reg_const((yyvsp[(1) - (1)].var)); + (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0); + ;} break; case 150: /* Line 1455 of yacc.c */ -#line 607 "parser.y" - { (yyval.expr_list) = append_expr( NULL, (yyvsp[(1) - (1)].expr) ); ;} +#line 606 "parser.y" + { (yyval.type) = type_new_enum((yyvsp[(2) - (5)].str), TRUE, (yyvsp[(4) - (5)].var_list)); ;} break; case 151: /* Line 1455 of yacc.c */ -#line 608 "parser.y" - { (yyval.expr_list) = append_expr( (yyvsp[(1) - (3)].expr_list), (yyvsp[(3) - (3)].expr) ); ;} +#line 609 "parser.y" + { (yyval.expr_list) = append_expr( NULL, (yyvsp[(1) - (1)].expr) ); ;} break; case 152: /* Line 1455 of yacc.c */ -#line 621 "parser.y" - { (yyval.expr) = make_expr(EXPR_VOID); ;} +#line 610 "parser.y" + { (yyval.expr_list) = append_expr( (yyvsp[(1) - (3)].expr_list), (yyvsp[(3) - (3)].expr) ); ;} break; - case 154: + case 153: /* Line 1455 of yacc.c */ -#line 625 "parser.y" - { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[(1) - (1)].num)); ;} +#line 623 "parser.y" + { (yyval.expr) = make_expr(EXPR_VOID); ;} break; case 155: /* Line 1455 of yacc.c */ -#line 626 "parser.y" - { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[(1) - (1)].num)); ;} +#line 627 "parser.y" + { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[(1) - (1)].num)); ;} break; case 156: /* Line 1455 of yacc.c */ -#line 627 "parser.y" - { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[(1) - (1)].dbl)); ;} +#line 628 "parser.y" + { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[(1) - (1)].num)); ;} break; case 157: /* Line 1455 of yacc.c */ -#line 628 "parser.y" - { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); ;} +#line 629 "parser.y" + { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[(1) - (1)].dbl)); ;} break; case 158: /* Line 1455 of yacc.c */ -#line 629 "parser.y" - { (yyval.expr) = make_exprl(EXPR_NUM, 0); ;} +#line 630 "parser.y" + { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); ;} break; case 159: /* Line 1455 of yacc.c */ -#line 630 "parser.y" - { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); ;} +#line 631 "parser.y" + { (yyval.expr) = make_exprl(EXPR_NUM, 0); ;} break; case 160: /* Line 1455 of yacc.c */ -#line 631 "parser.y" - { (yyval.expr) = make_exprs(EXPR_STRLIT, (yyvsp[(1) - (1)].str)); ;} +#line 632 "parser.y" + { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); ;} break; case 161: /* Line 1455 of yacc.c */ -#line 632 "parser.y" - { (yyval.expr) = make_exprs(EXPR_WSTRLIT, (yyvsp[(1) - (1)].str)); ;} +#line 633 "parser.y" + { (yyval.expr) = make_exprs(EXPR_STRLIT, (yyvsp[(1) - (1)].str)); ;} break; case 162: /* Line 1455 of yacc.c */ -#line 633 "parser.y" - { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[(1) - (1)].str)); ;} +#line 634 "parser.y" + { (yyval.expr) = make_exprs(EXPR_WSTRLIT, (yyvsp[(1) - (1)].str)); ;} break; case 163: /* Line 1455 of yacc.c */ -#line 634 "parser.y" - { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[(1) - (5)].expr), (yyvsp[(3) - (5)].expr), (yyvsp[(5) - (5)].expr)); ;} +#line 635 "parser.y" + { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[(1) - (1)].str)); ;} break; case 164: /* Line 1455 of yacc.c */ -#line 635 "parser.y" - { (yyval.expr) = make_expr2(EXPR_LOGOR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 636 "parser.y" + { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[(1) - (5)].expr), (yyvsp[(3) - (5)].expr), (yyvsp[(5) - (5)].expr)); ;} break; case 165: /* Line 1455 of yacc.c */ -#line 636 "parser.y" - { (yyval.expr) = make_expr2(EXPR_LOGAND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 637 "parser.y" + { (yyval.expr) = make_expr2(EXPR_LOGOR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 166: /* Line 1455 of yacc.c */ -#line 637 "parser.y" - { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 638 "parser.y" + { (yyval.expr) = make_expr2(EXPR_LOGAND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 167: /* Line 1455 of yacc.c */ -#line 638 "parser.y" - { (yyval.expr) = make_expr2(EXPR_XOR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 639 "parser.y" + { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 168: /* Line 1455 of yacc.c */ -#line 639 "parser.y" - { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 640 "parser.y" + { (yyval.expr) = make_expr2(EXPR_XOR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 169: /* Line 1455 of yacc.c */ -#line 640 "parser.y" - { (yyval.expr) = make_expr2(EXPR_EQUALITY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 641 "parser.y" + { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 170: /* Line 1455 of yacc.c */ -#line 641 "parser.y" - { (yyval.expr) = make_expr2(EXPR_INEQUALITY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 642 "parser.y" + { (yyval.expr) = make_expr2(EXPR_EQUALITY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 171: /* Line 1455 of yacc.c */ -#line 642 "parser.y" - { (yyval.expr) = make_expr2(EXPR_GTR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 643 "parser.y" + { (yyval.expr) = make_expr2(EXPR_INEQUALITY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 172: /* Line 1455 of yacc.c */ -#line 643 "parser.y" - { (yyval.expr) = make_expr2(EXPR_LESS, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 644 "parser.y" + { (yyval.expr) = make_expr2(EXPR_GTR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 173: /* Line 1455 of yacc.c */ -#line 644 "parser.y" - { (yyval.expr) = make_expr2(EXPR_GTREQL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 645 "parser.y" + { (yyval.expr) = make_expr2(EXPR_LESS, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 174: /* Line 1455 of yacc.c */ -#line 645 "parser.y" - { (yyval.expr) = make_expr2(EXPR_LESSEQL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 646 "parser.y" + { (yyval.expr) = make_expr2(EXPR_GTREQL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 175: /* Line 1455 of yacc.c */ -#line 646 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 647 "parser.y" + { (yyval.expr) = make_expr2(EXPR_LESSEQL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 176: /* Line 1455 of yacc.c */ -#line 647 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 648 "parser.y" + { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 177: /* Line 1455 of yacc.c */ -#line 648 "parser.y" - { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 649 "parser.y" + { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 178: /* Line 1455 of yacc.c */ -#line 649 "parser.y" - { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 650 "parser.y" + { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 179: /* Line 1455 of yacc.c */ -#line 650 "parser.y" - { (yyval.expr) = make_expr2(EXPR_MOD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 651 "parser.y" + { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 180: /* Line 1455 of yacc.c */ -#line 651 "parser.y" - { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 652 "parser.y" + { (yyval.expr) = make_expr2(EXPR_MOD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 181: /* Line 1455 of yacc.c */ -#line 652 "parser.y" - { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} +#line 653 "parser.y" + { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 182: /* Line 1455 of yacc.c */ -#line 653 "parser.y" - { (yyval.expr) = make_expr1(EXPR_LOGNOT, (yyvsp[(2) - (2)].expr)); ;} +#line 654 "parser.y" + { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); ;} break; case 183: /* Line 1455 of yacc.c */ -#line 654 "parser.y" - { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[(2) - (2)].expr)); ;} +#line 655 "parser.y" + { (yyval.expr) = make_expr1(EXPR_LOGNOT, (yyvsp[(2) - (2)].expr)); ;} break; case 184: /* Line 1455 of yacc.c */ -#line 655 "parser.y" - { (yyval.expr) = make_expr1(EXPR_POS, (yyvsp[(2) - (2)].expr)); ;} +#line 656 "parser.y" + { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[(2) - (2)].expr)); ;} break; case 185: /* Line 1455 of yacc.c */ -#line 656 "parser.y" - { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[(2) - (2)].expr)); ;} +#line 657 "parser.y" + { (yyval.expr) = make_expr1(EXPR_POS, (yyvsp[(2) - (2)].expr)); ;} break; case 186: /* Line 1455 of yacc.c */ -#line 657 "parser.y" - { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[(2) - (2)].expr)); ;} +#line 658 "parser.y" + { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[(2) - (2)].expr)); ;} break; case 187: /* Line 1455 of yacc.c */ -#line 658 "parser.y" - { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[(2) - (2)].expr)); ;} +#line 659 "parser.y" + { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[(2) - (2)].expr)); ;} break; case 188: /* Line 1455 of yacc.c */ -#line 659 "parser.y" - { (yyval.expr) = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, (yyvsp[(1) - (3)].expr)), make_exprs(EXPR_IDENTIFIER, (yyvsp[(3) - (3)].str))); ;} +#line 660 "parser.y" + { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[(2) - (2)].expr)); ;} break; case 189: /* Line 1455 of yacc.c */ -#line 660 "parser.y" - { (yyval.expr) = make_expr2(EXPR_MEMBER, (yyvsp[(1) - (3)].expr), make_exprs(EXPR_IDENTIFIER, (yyvsp[(3) - (3)].str))); ;} +#line 661 "parser.y" + { (yyval.expr) = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, (yyvsp[(1) - (3)].expr)), make_exprs(EXPR_IDENTIFIER, (yyvsp[(3) - (3)].str))); ;} break; case 190: /* Line 1455 of yacc.c */ -#line 661 "parser.y" - { (yyval.expr) = make_exprt(EXPR_CAST, (yyvsp[(2) - (4)].type), (yyvsp[(4) - (4)].expr)); ;} +#line 662 "parser.y" + { (yyval.expr) = make_expr2(EXPR_MEMBER, (yyvsp[(1) - (3)].expr), make_exprs(EXPR_IDENTIFIER, (yyvsp[(3) - (3)].str))); ;} break; case 191: /* Line 1455 of yacc.c */ -#line 662 "parser.y" - { (yyval.expr) = make_exprt(EXPR_SIZEOF, (yyvsp[(3) - (4)].type), NULL); ;} +#line 664 "parser.y" + { (yyval.expr) = make_exprt(EXPR_CAST, declare_var(NULL, (yyvsp[(2) - (5)].declspec), (yyvsp[(3) - (5)].declarator), 0), (yyvsp[(5) - (5)].expr)); free((yyvsp[(2) - (5)].declspec)); free((yyvsp[(3) - (5)].declarator)); ;} break; case 192: /* Line 1455 of yacc.c */ -#line 663 "parser.y" - { (yyval.expr) = make_expr2(EXPR_ARRAY, (yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr)); ;} +#line 666 "parser.y" + { (yyval.expr) = make_exprt(EXPR_SIZEOF, declare_var(NULL, (yyvsp[(3) - (5)].declspec), (yyvsp[(4) - (5)].declarator), 0), NULL); free((yyvsp[(3) - (5)].declspec)); free((yyvsp[(4) - (5)].declarator)); ;} break; case 193: /* Line 1455 of yacc.c */ -#line 664 "parser.y" - { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} +#line 667 "parser.y" + { (yyval.expr) = make_expr2(EXPR_ARRAY, (yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr)); ;} break; case 194: /* Line 1455 of yacc.c */ -#line 667 "parser.y" - { (yyval.expr_list) = append_expr( NULL, (yyvsp[(1) - (1)].expr) ); ;} +#line 668 "parser.y" + { (yyval.expr) = (yyvsp[(2) - (3)].expr); ;} break; case 195: /* Line 1455 of yacc.c */ -#line 668 "parser.y" - { (yyval.expr_list) = append_expr( (yyvsp[(1) - (3)].expr_list), (yyvsp[(3) - (3)].expr) ); ;} +#line 671 "parser.y" + { (yyval.expr_list) = append_expr( NULL, (yyvsp[(1) - (1)].expr) ); ;} break; case 196: /* Line 1455 of yacc.c */ -#line 671 "parser.y" +#line 672 "parser.y" + { (yyval.expr_list) = append_expr( (yyvsp[(1) - (3)].expr_list), (yyvsp[(3) - (3)].expr) ); ;} + break; + + case 197: + +/* Line 1455 of yacc.c */ +#line 675 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); if (!(yyval.expr)->is_const) error_loc("expression is not an integer constant\n"); ;} break; - case 197: + case 198: /* Line 1455 of yacc.c */ -#line 677 "parser.y" +#line 681 "parser.y" { (yyval.expr) = (yyvsp[(1) - (1)].expr); if (!(yyval.expr)->is_const && (yyval.expr)->type != EXPR_STRLIT && (yyval.expr)->type != EXPR_WSTRLIT) error_loc("expression is not constant\n"); ;} break; - case 198: - -/* Line 1455 of yacc.c */ -#line 683 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - case 199: /* Line 1455 of yacc.c */ -#line 684 "parser.y" - { (yyval.var_list) = append_var_list((yyvsp[(1) - (2)].var_list), (yyvsp[(2) - (2)].var_list)); ;} +#line 687 "parser.y" + { (yyval.var_list) = NULL; ;} break; case 200: /* Line 1455 of yacc.c */ #line 688 "parser.y" - { const char *first = LIST_ENTRY(list_head((yyvsp[(3) - (4)].declarator_list)), declarator_t, entry)->var->name; - check_field_attrs(first, (yyvsp[(1) - (4)].attr_list)); - (yyval.var_list) = set_var_types((yyvsp[(1) - (4)].attr_list), (yyvsp[(2) - (4)].declspec), (yyvsp[(3) - (4)].declarator_list)); - ;} + { (yyval.var_list) = append_var_list((yyvsp[(1) - (2)].var_list), (yyvsp[(2) - (2)].var_list)); ;} break; case 201: /* Line 1455 of yacc.c */ #line 692 "parser.y" - { var_t *v = make_var(NULL); - v->type = (yyvsp[(2) - (3)].type); v->attrs = (yyvsp[(1) - (3)].attr_list); - (yyval.var_list) = append_var(NULL, v); + { const char *first = LIST_ENTRY(list_head((yyvsp[(3) - (4)].declarator_list)), declarator_t, entry)->var->name; + check_field_attrs(first, (yyvsp[(1) - (4)].attr_list)); + (yyval.var_list) = set_var_types((yyvsp[(1) - (4)].attr_list), (yyvsp[(2) - (4)].declspec), (yyvsp[(3) - (4)].declarator_list)); ;} break; case 202: /* Line 1455 of yacc.c */ -#line 699 "parser.y" - { (yyval.var) = (yyvsp[(1) - (2)].var); ;} +#line 696 "parser.y" + { var_t *v = make_var(NULL); + v->type = (yyvsp[(2) - (3)].type); v->attrs = (yyvsp[(1) - (3)].attr_list); + (yyval.var_list) = append_var(NULL, v); + ;} break; case 203: /* Line 1455 of yacc.c */ -#line 700 "parser.y" - { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[(1) - (2)].attr_list); ;} +#line 703 "parser.y" + { (yyval.var) = (yyvsp[(1) - (2)].var); ;} break; case 204: /* Line 1455 of yacc.c */ -#line 703 "parser.y" - { (yyval.var_list) = NULL; ;} +#line 704 "parser.y" + { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[(1) - (2)].attr_list); ;} break; case 205: /* Line 1455 of yacc.c */ -#line 704 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[(1) - (2)].var_list), (yyvsp[(2) - (2)].var) ); ;} +#line 707 "parser.y" + { (yyval.var_list) = NULL; ;} break; case 206: /* Line 1455 of yacc.c */ #line 708 "parser.y" - { (yyval.var) = (yyvsp[(1) - (2)].var); ;} + { (yyval.var_list) = append_var( (yyvsp[(1) - (2)].var_list), (yyvsp[(2) - (2)].var) ); ;} break; case 207: /* Line 1455 of yacc.c */ -#line 709 "parser.y" - { (yyval.var) = NULL; ;} +#line 712 "parser.y" + { (yyval.var) = (yyvsp[(1) - (2)].var); ;} break; case 208: /* Line 1455 of yacc.c */ -#line 712 "parser.y" - { (yyval.var) = (yyvsp[(3) - (3)].declarator)->var; - (yyval.var)->attrs = check_field_attrs((yyval.var)->name, (yyvsp[(1) - (3)].attr_list)); - set_type((yyval.var), (yyvsp[(2) - (3)].declspec), (yyvsp[(3) - (3)].declarator), FALSE); - free((yyvsp[(3) - (3)].declarator)); - ;} +#line 713 "parser.y" + { (yyval.var) = NULL; ;} break; case 209: /* Line 1455 of yacc.c */ -#line 720 "parser.y" - { var_t *v = (yyvsp[(3) - (3)].declarator)->var; - v->attrs = check_function_attrs(v->name, (yyvsp[(1) - (3)].attr_list)); - set_type(v, (yyvsp[(2) - (3)].declspec), (yyvsp[(3) - (3)].declarator), FALSE); +#line 716 "parser.y" + { (yyval.var) = declare_var(check_field_attrs((yyvsp[(3) - (3)].declarator)->var->name, (yyvsp[(1) - (3)].attr_list)), + (yyvsp[(2) - (3)].declspec), (yyvsp[(3) - (3)].declarator), FALSE); free((yyvsp[(3) - (3)].declarator)); - (yyval.func) = make_func(v); ;} break; case 210: /* Line 1455 of yacc.c */ -#line 730 "parser.y" - { (yyval.var) = (yyvsp[(3) - (3)].declarator)->var; - (yyval.var)->attrs = (yyvsp[(1) - (3)].attr_list); - set_type((yyval.var), (yyvsp[(2) - (3)].declspec), (yyvsp[(3) - (3)].declarator), FALSE); +#line 723 "parser.y" + { var_t *v; + v = declare_var(check_function_attrs((yyvsp[(3) - (3)].declarator)->var->name, (yyvsp[(1) - (3)].attr_list)), + (yyvsp[(2) - (3)].declspec), (yyvsp[(3) - (3)].declarator), FALSE); free((yyvsp[(3) - (3)].declarator)); + (yyval.func) = make_func(v); ;} break; case 211: /* Line 1455 of yacc.c */ -#line 735 "parser.y" - { (yyval.var) = (yyvsp[(2) - (2)].declarator)->var; - set_type((yyval.var), (yyvsp[(1) - (2)].declspec), (yyvsp[(2) - (2)].declarator), FALSE); - free((yyvsp[(2) - (2)].declarator)); +#line 733 "parser.y" + { (yyval.var) = declare_var((yyvsp[(1) - (3)].attr_list), (yyvsp[(2) - (3)].declspec), (yyvsp[(3) - (3)].declarator), FALSE); + free((yyvsp[(3) - (3)].declarator)); ;} break; case 212: +/* Line 1455 of yacc.c */ +#line 736 "parser.y" + { (yyval.var) = declare_var(NULL, (yyvsp[(1) - (2)].declspec), (yyvsp[(2) - (2)].declarator), FALSE); + free((yyvsp[(2) - (2)].declarator)); + ;} + break; + + case 213: + /* Line 1455 of yacc.c */ #line 741 "parser.y" { (yyval.var) = NULL; ;} break; - case 214: + case 215: /* Line 1455 of yacc.c */ #line 745 "parser.y" { (yyval.str) = NULL; ;} break; - case 215: + case 216: /* Line 1455 of yacc.c */ #line 746 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 216: + case 217: /* Line 1455 of yacc.c */ #line 747 "parser.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 217: + case 218: /* Line 1455 of yacc.c */ #line 750 "parser.y" { (yyval.var) = make_var((yyvsp[(1) - (1)].str)); ;} break; - case 218: + case 219: /* Line 1455 of yacc.c */ #line 752 "parser.y" { (yyval.var) = make_var((yyvsp[(1) - (1)].str)); ;} break; - case 219: + case 220: /* Line 1455 of yacc.c */ #line 755 "parser.y" { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} break; - case 220: + case 221: /* Line 1455 of yacc.c */ #line 756 "parser.y" { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} break; - case 222: + case 223: /* Line 1455 of yacc.c */ #line 758 "parser.y" { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[(2) - (2)].type)), -1); ;} break; - case 223: + case 224: /* Line 1455 of yacc.c */ #line 759 "parser.y" { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[(2) - (2)].type)), 1); ;} break; - case 224: + case 225: /* Line 1455 of yacc.c */ #line 760 "parser.y" { (yyval.type) = type_new_int(TYPE_BASIC_INT, 1); ;} break; - case 225: + case 226: /* Line 1455 of yacc.c */ #line 761 "parser.y" { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} break; - case 226: + case 227: /* Line 1455 of yacc.c */ #line 762 "parser.y" { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} break; - case 227: + case 228: /* Line 1455 of yacc.c */ #line 763 "parser.y" { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} break; - case 228: + case 229: /* Line 1455 of yacc.c */ #line 764 "parser.y" { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} break; - case 229: + case 230: /* Line 1455 of yacc.c */ #line 765 "parser.y" { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} break; - case 232: + case 233: /* Line 1455 of yacc.c */ #line 772 "parser.y" { (yyval.type) = type_new_int(TYPE_BASIC_INT, 0); ;} break; - case 233: + case 234: /* Line 1455 of yacc.c */ #line 773 "parser.y" { (yyval.type) = type_new_int(TYPE_BASIC_INT16, 0); ;} break; - case 234: + case 235: /* Line 1455 of yacc.c */ #line 774 "parser.y" { (yyval.type) = type_new_int(TYPE_BASIC_INT8, 0); ;} break; - case 235: + case 236: /* Line 1455 of yacc.c */ #line 775 "parser.y" { (yyval.type) = type_new_int(TYPE_BASIC_INT32, 0); ;} break; - case 236: + case 237: /* Line 1455 of yacc.c */ #line 776 "parser.y" { (yyval.type) = type_new_int(TYPE_BASIC_HYPER, 0); ;} break; - case 237: + case 238: /* Line 1455 of yacc.c */ #line 777 "parser.y" { (yyval.type) = type_new_int(TYPE_BASIC_INT64, 0); ;} break; - case 238: + case 239: /* Line 1455 of yacc.c */ #line 778 "parser.y" { (yyval.type) = type_new_int(TYPE_BASIC_CHAR, 0); ;} break; - case 239: - -/* Line 1455 of yacc.c */ -#line 781 "parser.y" - { (yyval.type) = type_new_coclass((yyvsp[(2) - (2)].str)); ;} - break; - case 240: +/* Line 1455 of yacc.c */ +#line 779 "parser.y" + { (yyval.type) = type_new_int(TYPE_BASIC_INT3264, 0); ;} + break; + + case 241: + /* Line 1455 of yacc.c */ #line 782 "parser.y" + { (yyval.type) = type_new_coclass((yyvsp[(2) - (2)].str)); ;} + break; + + case 242: + +/* Line 1455 of yacc.c */ +#line 783 "parser.y" { (yyval.type) = find_type((yyvsp[(2) - (2)].str), 0); if (type_get_type_detect_alias((yyval.type)) != TYPE_COCLASS) error_loc("%s was not declared a coclass at %s:%d\n", @@ -4175,62 +4312,62 @@ yyreduce: ;} break; - case 241: + case 243: /* Line 1455 of yacc.c */ -#line 790 "parser.y" +#line 791 "parser.y" { (yyval.type) = (yyvsp[(2) - (2)].type); check_def((yyval.type)); (yyval.type)->attrs = check_coclass_attrs((yyvsp[(2) - (2)].type)->name, (yyvsp[(1) - (2)].attr_list)); ;} break; - case 242: - -/* Line 1455 of yacc.c */ -#line 797 "parser.y" - { (yyval.type) = type_coclass_define((yyvsp[(1) - (5)].type), (yyvsp[(3) - (5)].ifref_list)); ;} - break; - - case 243: - -/* Line 1455 of yacc.c */ -#line 800 "parser.y" - { (yyval.ifref_list) = NULL; ;} - break; - case 244: /* Line 1455 of yacc.c */ -#line 801 "parser.y" - { (yyval.ifref_list) = append_ifref( (yyvsp[(1) - (2)].ifref_list), (yyvsp[(2) - (2)].ifref) ); ;} +#line 798 "parser.y" + { (yyval.type) = type_coclass_define((yyvsp[(1) - (5)].type), (yyvsp[(3) - (5)].ifref_list)); ;} break; case 245: /* Line 1455 of yacc.c */ -#line 805 "parser.y" - { (yyval.ifref) = make_ifref((yyvsp[(2) - (2)].type)); (yyval.ifref)->attrs = (yyvsp[(1) - (2)].attr_list); ;} +#line 801 "parser.y" + { (yyval.ifref_list) = NULL; ;} break; case 246: /* Line 1455 of yacc.c */ -#line 808 "parser.y" - { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[(2) - (2)].str), 0); ;} +#line 802 "parser.y" + { (yyval.ifref_list) = append_ifref( (yyvsp[(1) - (2)].ifref_list), (yyvsp[(2) - (2)].ifref) ); ;} break; case 247: +/* Line 1455 of yacc.c */ +#line 806 "parser.y" + { (yyval.ifref) = make_ifref((yyvsp[(2) - (2)].type)); (yyval.ifref)->attrs = (yyvsp[(1) - (2)].attr_list); ;} + break; + + case 248: + /* Line 1455 of yacc.c */ #line 809 "parser.y" { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[(2) - (2)].str), 0); ;} break; - case 248: + case 249: /* Line 1455 of yacc.c */ -#line 812 "parser.y" +#line 810 "parser.y" + { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[(2) - (2)].str), 0); ;} + break; + + case 250: + +/* Line 1455 of yacc.c */ +#line 813 "parser.y" { attr_t *attrs; is_object_interface = TRUE; (yyval.type) = (yyvsp[(2) - (2)].type); @@ -4241,84 +4378,84 @@ yyreduce: ;} break; - case 249: - -/* Line 1455 of yacc.c */ -#line 822 "parser.y" - { (yyval.var_list) = NULL; ;} - break; - - case 250: - -/* Line 1455 of yacc.c */ -#line 823 "parser.y" - { (yyval.var_list) = append_var( (yyvsp[(1) - (3)].var_list), (yyvsp[(2) - (3)].var) ); ;} - break; - case 251: /* Line 1455 of yacc.c */ -#line 826 "parser.y" - { (yyval.stmt_list) = NULL; ;} +#line 823 "parser.y" + { (yyval.var_list) = NULL; ;} break; case 252: /* Line 1455 of yacc.c */ -#line 827 "parser.y" - { (yyval.stmt_list) = append_func( (yyvsp[(1) - (3)].stmt_list), (yyvsp[(2) - (3)].func) ); ;} +#line 824 "parser.y" + { (yyval.var_list) = append_var( (yyvsp[(1) - (3)].var_list), (yyvsp[(2) - (3)].var) ); ;} break; case 253: /* Line 1455 of yacc.c */ -#line 833 "parser.y" - { (yyval.type) = (yyvsp[(1) - (5)].type); - type_dispinterface_define((yyval.type), (yyvsp[(3) - (5)].var_list), (yyvsp[(4) - (5)].stmt_list)); - ;} +#line 827 "parser.y" + { (yyval.stmt_list) = NULL; ;} break; case 254: /* Line 1455 of yacc.c */ -#line 837 "parser.y" - { (yyval.type) = (yyvsp[(1) - (5)].type); - type_dispinterface_define_from_iface((yyval.type), (yyvsp[(3) - (5)].type)); - ;} +#line 828 "parser.y" + { (yyval.stmt_list) = append_func( (yyvsp[(1) - (3)].stmt_list), (yyvsp[(2) - (3)].func) ); ;} break; case 255: /* Line 1455 of yacc.c */ -#line 842 "parser.y" - { (yyval.type) = NULL; ;} +#line 834 "parser.y" + { (yyval.type) = (yyvsp[(1) - (5)].type); + type_dispinterface_define((yyval.type), (yyvsp[(3) - (5)].var_list), (yyvsp[(4) - (5)].stmt_list)); + ;} break; case 256: /* Line 1455 of yacc.c */ -#line 843 "parser.y" - { (yyval.type) = find_type_or_error2((yyvsp[(2) - (2)].str), 0); ;} +#line 838 "parser.y" + { (yyval.type) = (yyvsp[(1) - (5)].type); + type_dispinterface_define_from_iface((yyval.type), (yyvsp[(3) - (5)].type)); + ;} break; case 257: /* Line 1455 of yacc.c */ -#line 846 "parser.y" - { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[(2) - (2)].str), 0); ;} +#line 843 "parser.y" + { (yyval.type) = NULL; ;} break; case 258: +/* Line 1455 of yacc.c */ +#line 844 "parser.y" + { (yyval.type) = find_type_or_error2((yyvsp[(2) - (2)].str), 0); ;} + break; + + case 259: + /* Line 1455 of yacc.c */ #line 847 "parser.y" { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[(2) - (2)].str), 0); ;} break; - case 259: + case 260: /* Line 1455 of yacc.c */ -#line 850 "parser.y" +#line 848 "parser.y" + { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[(2) - (2)].str), 0); ;} + break; + + case 261: + +/* Line 1455 of yacc.c */ +#line 851 "parser.y" { (yyval.ifinfo).interface = (yyvsp[(2) - (2)].type); (yyval.ifinfo).old_pointer_default = pointer_default; if (is_attr((yyvsp[(1) - (2)].attr_list), ATTR_POINTERDEFAULT)) @@ -4330,382 +4467,579 @@ yyreduce: ;} break; - case 260: + case 262: /* Line 1455 of yacc.c */ -#line 862 "parser.y" +#line 863 "parser.y" { (yyval.type) = (yyvsp[(1) - (6)].ifinfo).interface; type_interface_define((yyval.type), (yyvsp[(2) - (6)].type), (yyvsp[(4) - (6)].stmt_list)); pointer_default = (yyvsp[(1) - (6)].ifinfo).old_pointer_default; ;} break; - case 261: + case 263: /* Line 1455 of yacc.c */ -#line 870 "parser.y" +#line 871 "parser.y" { (yyval.type) = (yyvsp[(1) - (8)].ifinfo).interface; type_interface_define((yyval.type), find_type_or_error2((yyvsp[(3) - (8)].str), 0), (yyvsp[(6) - (8)].stmt_list)); pointer_default = (yyvsp[(1) - (8)].ifinfo).old_pointer_default; ;} break; - case 262: - -/* Line 1455 of yacc.c */ -#line 874 "parser.y" - { (yyval.type) = (yyvsp[(1) - (2)].type); ;} - break; - - case 263: - -/* Line 1455 of yacc.c */ -#line 878 "parser.y" - { (yyval.type) = (yyvsp[(1) - (2)].type); ;} - break; - case 264: /* Line 1455 of yacc.c */ -#line 879 "parser.y" +#line 875 "parser.y" { (yyval.type) = (yyvsp[(1) - (2)].type); ;} break; case 265: /* Line 1455 of yacc.c */ -#line 882 "parser.y" - { (yyval.type) = type_new_module((yyvsp[(2) - (2)].str)); ;} +#line 879 "parser.y" + { (yyval.type) = (yyvsp[(1) - (2)].type); ;} break; case 266: +/* Line 1455 of yacc.c */ +#line 880 "parser.y" + { (yyval.type) = (yyvsp[(1) - (2)].type); ;} + break; + + case 267: + /* Line 1455 of yacc.c */ #line 883 "parser.y" { (yyval.type) = type_new_module((yyvsp[(2) - (2)].str)); ;} break; - case 267: - -/* Line 1455 of yacc.c */ -#line 886 "parser.y" - { (yyval.type) = (yyvsp[(2) - (2)].type); - (yyval.type)->attrs = check_module_attrs((yyvsp[(2) - (2)].type)->name, (yyvsp[(1) - (2)].attr_list)); - ;} - break; - case 268: /* Line 1455 of yacc.c */ -#line 892 "parser.y" - { (yyval.type) = (yyvsp[(1) - (5)].type); - type_module_define((yyval.type), (yyvsp[(3) - (5)].stmt_list)); - ;} +#line 884 "parser.y" + { (yyval.type) = type_new_module((yyvsp[(2) - (2)].str)); ;} break; case 269: /* Line 1455 of yacc.c */ -#line 898 "parser.y" - { (yyval.stgclass) = STG_EXTERN; ;} +#line 887 "parser.y" + { (yyval.type) = (yyvsp[(2) - (2)].type); + (yyval.type)->attrs = check_module_attrs((yyvsp[(2) - (2)].type)->name, (yyvsp[(1) - (2)].attr_list)); + ;} break; case 270: /* Line 1455 of yacc.c */ -#line 899 "parser.y" - { (yyval.stgclass) = STG_STATIC; ;} +#line 893 "parser.y" + { (yyval.type) = (yyvsp[(1) - (5)].type); + type_module_define((yyval.type), (yyvsp[(3) - (5)].stmt_list)); + ;} break; case 271: /* Line 1455 of yacc.c */ -#line 900 "parser.y" - { (yyval.stgclass) = STG_REGISTER; ;} +#line 899 "parser.y" + { (yyval.stgclass) = STG_EXTERN; ;} break; case 272: /* Line 1455 of yacc.c */ -#line 904 "parser.y" - { (yyval.attr) = make_attr(ATTR_INLINE); ;} +#line 900 "parser.y" + { (yyval.stgclass) = STG_STATIC; ;} break; case 273: /* Line 1455 of yacc.c */ -#line 908 "parser.y" - { (yyval.attr) = make_attr(ATTR_CONST); ;} +#line 901 "parser.y" + { (yyval.stgclass) = STG_REGISTER; ;} break; case 274: /* Line 1455 of yacc.c */ -#line 911 "parser.y" - { (yyval.attr_list) = NULL; ;} +#line 905 "parser.y" + { (yyval.attr) = make_attr(ATTR_INLINE); ;} break; case 275: /* Line 1455 of yacc.c */ -#line 912 "parser.y" - { (yyval.attr_list) = append_attr((yyvsp[(1) - (2)].attr_list), (yyvsp[(2) - (2)].attr)); ;} +#line 909 "parser.y" + { (yyval.attr) = make_attr(ATTR_CONST); ;} break; case 276: /* Line 1455 of yacc.c */ -#line 915 "parser.y" - { (yyval.declspec) = make_decl_spec((yyvsp[(1) - (2)].type), (yyvsp[(2) - (2)].declspec), NULL, NULL, STG_NONE); ;} +#line 912 "parser.y" + { (yyval.attr_list) = NULL; ;} break; case 277: /* Line 1455 of yacc.c */ -#line 917 "parser.y" - { (yyval.declspec) = make_decl_spec((yyvsp[(2) - (3)].type), (yyvsp[(1) - (3)].declspec), (yyvsp[(3) - (3)].declspec), NULL, STG_NONE); ;} +#line 913 "parser.y" + { (yyval.attr_list) = append_attr((yyvsp[(1) - (2)].attr_list), (yyvsp[(2) - (2)].attr)); ;} break; case 278: /* Line 1455 of yacc.c */ -#line 920 "parser.y" - { (yyval.declspec) = NULL; ;} +#line 916 "parser.y" + { (yyval.declspec) = make_decl_spec((yyvsp[(1) - (2)].type), (yyvsp[(2) - (2)].declspec), NULL, NULL, STG_NONE); ;} + break; + + case 279: + +/* Line 1455 of yacc.c */ +#line 918 "parser.y" + { (yyval.declspec) = make_decl_spec((yyvsp[(2) - (3)].type), (yyvsp[(1) - (3)].declspec), (yyvsp[(3) - (3)].declspec), NULL, STG_NONE); ;} break; case 280: /* Line 1455 of yacc.c */ -#line 925 "parser.y" - { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[(2) - (2)].declspec), NULL, (yyvsp[(1) - (2)].attr), STG_NONE); ;} +#line 921 "parser.y" + { (yyval.declspec) = NULL; ;} break; - case 281: + case 282: /* Line 1455 of yacc.c */ #line 926 "parser.y" { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[(2) - (2)].declspec), NULL, (yyvsp[(1) - (2)].attr), STG_NONE); ;} break; - case 282: - -/* Line 1455 of yacc.c */ -#line 927 "parser.y" - { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[(2) - (2)].declspec), NULL, NULL, (yyvsp[(1) - (2)].stgclass)); ;} - break; - case 283: /* Line 1455 of yacc.c */ -#line 932 "parser.y" - { (yyval.declarator) = (yyvsp[(3) - (3)].declarator); (yyval.declarator)->type = append_ptrchain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[(2) - (3)].attr_list))); ;} +#line 927 "parser.y" + { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[(2) - (2)].declspec), NULL, (yyvsp[(1) - (2)].attr), STG_NONE); ;} break; case 284: +/* Line 1455 of yacc.c */ +#line 928 "parser.y" + { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[(2) - (2)].declspec), NULL, NULL, (yyvsp[(1) - (2)].stgclass)); ;} + break; + + case 285: + /* Line 1455 of yacc.c */ #line 933 "parser.y" - { (yyval.declarator) = (yyvsp[(2) - (2)].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[(1) - (2)].str))); ;} + { (yyval.declarator) = (yyvsp[(3) - (3)].declarator); (yyval.declarator)->type = append_ptrchain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[(2) - (3)].attr_list))); ;} break; case 286: /* Line 1455 of yacc.c */ -#line 938 "parser.y" - { (yyval.declarator) = make_declarator((yyvsp[(1) - (1)].var)); ;} - break; - - case 287: - -/* Line 1455 of yacc.c */ -#line 939 "parser.y" - { (yyval.declarator) = (yyvsp[(2) - (3)].declarator); ;} +#line 934 "parser.y" + { (yyval.declarator) = (yyvsp[(2) - (2)].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[(1) - (2)].str))); ;} break; case 288: /* Line 1455 of yacc.c */ -#line 940 "parser.y" - { (yyval.declarator) = (yyvsp[(1) - (2)].declarator); (yyval.declarator)->array = append_array((yyval.declarator)->array, (yyvsp[(2) - (2)].expr)); ;} +#line 939 "parser.y" + { (yyval.declarator) = make_declarator((yyvsp[(1) - (1)].var)); ;} break; case 289: +/* Line 1455 of yacc.c */ +#line 940 "parser.y" + { (yyval.declarator) = (yyvsp[(2) - (3)].declarator); ;} + break; + + case 290: + /* Line 1455 of yacc.c */ #line 941 "parser.y" + { (yyval.declarator) = (yyvsp[(1) - (2)].declarator); (yyval.declarator)->array = append_array((yyval.declarator)->array, (yyvsp[(2) - (2)].expr)); ;} + break; + + case 291: + +/* Line 1455 of yacc.c */ +#line 942 "parser.y" { (yyval.declarator) = (yyvsp[(1) - (4)].declarator); (yyval.declarator)->func_type = append_ptrchain_type((yyval.declarator)->type, type_new_function((yyvsp[(3) - (4)].var_list))); (yyval.declarator)->type = NULL; ;} break; - case 290: - -/* Line 1455 of yacc.c */ -#line 948 "parser.y" - { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[(1) - (1)].declarator) ); ;} - break; - - case 291: - -/* Line 1455 of yacc.c */ -#line 949 "parser.y" - { (yyval.declarator_list) = append_declarator( (yyvsp[(1) - (3)].declarator_list), (yyvsp[(3) - (3)].declarator) ); ;} - break; - case 292: /* Line 1455 of yacc.c */ -#line 953 "parser.y" - { (yyval.declarator) = (yyvsp[(1) - (1)].declarator); ;} +#line 951 "parser.y" + { (yyval.declarator) = (yyvsp[(3) - (3)].declarator); (yyval.declarator)->type = append_ptrchain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[(2) - (3)].attr_list))); ;} break; case 293: /* Line 1455 of yacc.c */ -#line 954 "parser.y" - { (yyval.declarator) = (yyvsp[(1) - (3)].declarator); (yyvsp[(1) - (3)].declarator)->var->eval = (yyvsp[(3) - (3)].expr); ;} - break; - - case 294: - -/* Line 1455 of yacc.c */ -#line 958 "parser.y" - { (yyval.num) = RPC_FC_RP; ;} +#line 952 "parser.y" + { (yyval.declarator) = (yyvsp[(2) - (2)].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[(1) - (2)].str))); ;} break; case 295: /* Line 1455 of yacc.c */ #line 959 "parser.y" - { (yyval.num) = RPC_FC_UP; ;} + { (yyval.declarator) = (yyvsp[(3) - (3)].declarator); (yyval.declarator)->type = append_ptrchain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[(2) - (3)].attr_list))); ;} break; case 296: /* Line 1455 of yacc.c */ #line 960 "parser.y" - { (yyval.num) = RPC_FC_FP; ;} + { (yyval.declarator) = (yyvsp[(2) - (2)].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[(1) - (2)].str))); ;} break; case 297: /* Line 1455 of yacc.c */ -#line 963 "parser.y" - { (yyval.type) = type_new_struct((yyvsp[(2) - (5)].str), TRUE, (yyvsp[(4) - (5)].var_list)); ;} - break; - - case 298: - -/* Line 1455 of yacc.c */ -#line 966 "parser.y" - { (yyval.type) = type_new_void(); ;} +#line 964 "parser.y" + { (yyval.declarator) = make_declarator(NULL); ;} break; case 299: /* Line 1455 of yacc.c */ -#line 967 "parser.y" - { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} +#line 970 "parser.y" + { (yyval.declarator) = (yyvsp[(2) - (3)].declarator); ;} break; case 300: /* Line 1455 of yacc.c */ -#line 968 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} +#line 971 "parser.y" + { (yyval.declarator) = (yyvsp[(1) - (2)].declarator); (yyval.declarator)->array = append_array((yyval.declarator)->array, (yyvsp[(2) - (2)].expr)); ;} break; case 301: /* Line 1455 of yacc.c */ -#line 969 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} +#line 972 "parser.y" + { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->array = append_array((yyval.declarator)->array, (yyvsp[(1) - (1)].expr)); ;} break; case 302: /* Line 1455 of yacc.c */ -#line 970 "parser.y" - { (yyval.type) = type_new_enum((yyvsp[(2) - (2)].str), FALSE, NULL); ;} +#line 974 "parser.y" + { (yyval.declarator) = make_declarator(NULL); + (yyval.declarator)->func_type = append_ptrchain_type((yyval.declarator)->type, type_new_function((yyvsp[(2) - (3)].var_list))); + (yyval.declarator)->type = NULL; + ;} break; case 303: /* Line 1455 of yacc.c */ -#line 971 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} +#line 979 "parser.y" + { (yyval.declarator) = (yyvsp[(1) - (4)].declarator); + (yyval.declarator)->func_type = append_ptrchain_type((yyval.declarator)->type, type_new_function((yyvsp[(3) - (4)].var_list))); + (yyval.declarator)->type = NULL; + ;} break; case 304: /* Line 1455 of yacc.c */ -#line 972 "parser.y" - { (yyval.type) = type_new_struct((yyvsp[(2) - (2)].str), FALSE, NULL); ;} +#line 988 "parser.y" + { (yyval.declarator) = (yyvsp[(3) - (3)].declarator); (yyval.declarator)->type = append_ptrchain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[(2) - (3)].attr_list))); ;} break; case 305: /* Line 1455 of yacc.c */ -#line 973 "parser.y" - { (yyval.type) = (yyvsp[(1) - (1)].type); ;} - break; - - case 306: - -/* Line 1455 of yacc.c */ -#line 974 "parser.y" - { (yyval.type) = type_new_nonencapsulated_union((yyvsp[(2) - (2)].str), FALSE, NULL); ;} +#line 989 "parser.y" + { (yyval.declarator) = (yyvsp[(2) - (2)].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[(1) - (2)].str))); ;} break; case 307: /* Line 1455 of yacc.c */ -#line 975 "parser.y" - { (yyval.type) = make_safearray((yyvsp[(3) - (4)].type)); ;} +#line 996 "parser.y" + { (yyval.declarator) = (yyvsp[(3) - (3)].declarator); (yyval.declarator)->type = append_ptrchain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[(2) - (3)].attr_list))); ;} break; case 308: /* Line 1455 of yacc.c */ -#line 979 "parser.y" - { reg_typedefs((yyvsp[(3) - (4)].declspec), (yyvsp[(4) - (4)].declarator_list), check_typedef_attrs((yyvsp[(2) - (4)].attr_list))); - (yyval.statement) = make_statement_typedef((yyvsp[(4) - (4)].declarator_list)); - ;} +#line 997 "parser.y" + { (yyval.declarator) = (yyvsp[(2) - (2)].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[(1) - (2)].str))); ;} break; case 309: /* Line 1455 of yacc.c */ -#line 985 "parser.y" - { (yyval.type) = type_new_nonencapsulated_union((yyvsp[(2) - (5)].str), TRUE, (yyvsp[(4) - (5)].var_list)); ;} - break; - - case 310: - -/* Line 1455 of yacc.c */ -#line 988 "parser.y" - { (yyval.type) = type_new_encapsulated_union((yyvsp[(2) - (10)].str), (yyvsp[(5) - (10)].var), (yyvsp[(7) - (10)].var), (yyvsp[(9) - (10)].var_list)); ;} +#line 1001 "parser.y" + { (yyval.declarator) = make_declarator(NULL); ;} break; case 311: /* Line 1455 of yacc.c */ -#line 992 "parser.y" - { (yyval.num) = MAKEVERSION((yyvsp[(1) - (1)].num), 0); ;} +#line 1009 "parser.y" + { (yyval.declarator) = make_declarator((yyvsp[(1) - (1)].var)); ;} break; case 312: /* Line 1455 of yacc.c */ -#line 993 "parser.y" +#line 1010 "parser.y" + { (yyval.declarator) = (yyvsp[(2) - (3)].declarator); ;} + break; + + case 313: + +/* Line 1455 of yacc.c */ +#line 1011 "parser.y" + { (yyval.declarator) = (yyvsp[(1) - (2)].declarator); (yyval.declarator)->array = append_array((yyval.declarator)->array, (yyvsp[(2) - (2)].expr)); ;} + break; + + case 314: + +/* Line 1455 of yacc.c */ +#line 1012 "parser.y" + { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->array = append_array((yyval.declarator)->array, (yyvsp[(1) - (1)].expr)); ;} + break; + + case 315: + +/* Line 1455 of yacc.c */ +#line 1014 "parser.y" + { (yyval.declarator) = make_declarator(NULL); + (yyval.declarator)->func_type = append_ptrchain_type((yyval.declarator)->type, type_new_function((yyvsp[(2) - (3)].var_list))); + (yyval.declarator)->type = NULL; + ;} + break; + + case 316: + +/* Line 1455 of yacc.c */ +#line 1019 "parser.y" + { (yyval.declarator) = (yyvsp[(1) - (4)].declarator); + (yyval.declarator)->func_type = append_ptrchain_type((yyval.declarator)->type, type_new_function((yyvsp[(3) - (4)].var_list))); + (yyval.declarator)->type = NULL; + ;} + break; + + case 317: + +/* Line 1455 of yacc.c */ +#line 1026 "parser.y" + { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[(1) - (1)].declarator) ); ;} + break; + + case 318: + +/* Line 1455 of yacc.c */ +#line 1027 "parser.y" + { (yyval.declarator_list) = append_declarator( (yyvsp[(1) - (3)].declarator_list), (yyvsp[(3) - (3)].declarator) ); ;} + break; + + case 319: + +/* Line 1455 of yacc.c */ +#line 1030 "parser.y" + { (yyval.expr) = NULL; ;} + break; + + case 320: + +/* Line 1455 of yacc.c */ +#line 1031 "parser.y" + { (yyval.expr) = (yyvsp[(2) - (2)].expr); ;} + break; + + case 321: + +/* Line 1455 of yacc.c */ +#line 1034 "parser.y" + { (yyval.declarator) = (yyvsp[(1) - (2)].declarator); (yyval.declarator)->bits = (yyvsp[(2) - (2)].expr); + if (!(yyval.declarator)->bits && !(yyval.declarator)->var->name) + error_loc("unnamed fields are not allowed"); + ;} + break; + + case 322: + +/* Line 1455 of yacc.c */ +#line 1041 "parser.y" + { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[(1) - (1)].declarator) ); ;} + break; + + case 323: + +/* Line 1455 of yacc.c */ +#line 1043 "parser.y" + { (yyval.declarator_list) = append_declarator( (yyvsp[(1) - (3)].declarator_list), (yyvsp[(3) - (3)].declarator) ); ;} + break; + + case 324: + +/* Line 1455 of yacc.c */ +#line 1047 "parser.y" + { (yyval.declarator) = (yyvsp[(1) - (1)].declarator); ;} + break; + + case 325: + +/* Line 1455 of yacc.c */ +#line 1048 "parser.y" + { (yyval.declarator) = (yyvsp[(1) - (3)].declarator); (yyvsp[(1) - (3)].declarator)->var->eval = (yyvsp[(3) - (3)].expr); ;} + break; + + case 326: + +/* Line 1455 of yacc.c */ +#line 1052 "parser.y" + { (yyval.num) = RPC_FC_RP; ;} + break; + + case 327: + +/* Line 1455 of yacc.c */ +#line 1053 "parser.y" + { (yyval.num) = RPC_FC_UP; ;} + break; + + case 328: + +/* Line 1455 of yacc.c */ +#line 1054 "parser.y" + { (yyval.num) = RPC_FC_FP; ;} + break; + + case 329: + +/* Line 1455 of yacc.c */ +#line 1057 "parser.y" + { (yyval.type) = type_new_struct((yyvsp[(2) - (5)].str), TRUE, (yyvsp[(4) - (5)].var_list)); ;} + break; + + case 330: + +/* Line 1455 of yacc.c */ +#line 1060 "parser.y" + { (yyval.type) = type_new_void(); ;} + break; + + case 331: + +/* Line 1455 of yacc.c */ +#line 1061 "parser.y" + { (yyval.type) = find_type_or_error((yyvsp[(1) - (1)].str), 0); ;} + break; + + case 332: + +/* Line 1455 of yacc.c */ +#line 1062 "parser.y" + { (yyval.type) = (yyvsp[(1) - (1)].type); ;} + break; + + case 333: + +/* Line 1455 of yacc.c */ +#line 1063 "parser.y" + { (yyval.type) = (yyvsp[(1) - (1)].type); ;} + break; + + case 334: + +/* Line 1455 of yacc.c */ +#line 1064 "parser.y" + { (yyval.type) = type_new_enum((yyvsp[(2) - (2)].str), FALSE, NULL); ;} + break; + + case 335: + +/* Line 1455 of yacc.c */ +#line 1065 "parser.y" + { (yyval.type) = (yyvsp[(1) - (1)].type); ;} + break; + + case 336: + +/* Line 1455 of yacc.c */ +#line 1066 "parser.y" + { (yyval.type) = type_new_struct((yyvsp[(2) - (2)].str), FALSE, NULL); ;} + break; + + case 337: + +/* Line 1455 of yacc.c */ +#line 1067 "parser.y" + { (yyval.type) = (yyvsp[(1) - (1)].type); ;} + break; + + case 338: + +/* Line 1455 of yacc.c */ +#line 1068 "parser.y" + { (yyval.type) = type_new_nonencapsulated_union((yyvsp[(2) - (2)].str), FALSE, NULL); ;} + break; + + case 339: + +/* Line 1455 of yacc.c */ +#line 1069 "parser.y" + { (yyval.type) = make_safearray((yyvsp[(3) - (4)].type)); ;} + break; + + case 340: + +/* Line 1455 of yacc.c */ +#line 1073 "parser.y" + { reg_typedefs((yyvsp[(3) - (4)].declspec), (yyvsp[(4) - (4)].declarator_list), check_typedef_attrs((yyvsp[(2) - (4)].attr_list))); + (yyval.statement) = make_statement_typedef((yyvsp[(4) - (4)].declarator_list)); + ;} + break; + + case 341: + +/* Line 1455 of yacc.c */ +#line 1079 "parser.y" + { (yyval.type) = type_new_nonencapsulated_union((yyvsp[(2) - (5)].str), TRUE, (yyvsp[(4) - (5)].var_list)); ;} + break; + + case 342: + +/* Line 1455 of yacc.c */ +#line 1082 "parser.y" + { (yyval.type) = type_new_encapsulated_union((yyvsp[(2) - (10)].str), (yyvsp[(5) - (10)].var), (yyvsp[(7) - (10)].var), (yyvsp[(9) - (10)].var_list)); ;} + break; + + case 343: + +/* Line 1455 of yacc.c */ +#line 1086 "parser.y" + { (yyval.num) = MAKEVERSION((yyvsp[(1) - (1)].num), 0); ;} + break; + + case 344: + +/* Line 1455 of yacc.c */ +#line 1087 "parser.y" { (yyval.num) = MAKEVERSION((yyvsp[(1) - (3)].num), (yyvsp[(3) - (3)].num)); ;} break; /* Line 1455 of yacc.c */ -#line 4709 "parser.tab.c" +#line 5043 "parser.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -4917,7 +5251,7 @@ yyreturn: /* Line 1675 of yacc.c */ -#line 996 "parser.y" +#line 1090 "parser.y" static void decl_builtin_basic(const char *name, enum type_basic_type type) @@ -5162,6 +5496,38 @@ static void type_function_add_head_arg(type_t *type, var_t *arg) list_add_head( type->details.function->args, &arg->entry ); } +static int is_allowed_range_type(const type_t *type) +{ + switch (type_get_type(type)) + { + case TYPE_ENUM: + return TRUE; + case TYPE_BASIC: + switch (type_basic_get_type(type)) + { + case TYPE_BASIC_INT8: + case TYPE_BASIC_INT16: + case TYPE_BASIC_INT32: + case TYPE_BASIC_INT64: + case TYPE_BASIC_INT: + case TYPE_BASIC_INT3264: + case TYPE_BASIC_BYTE: + case TYPE_BASIC_CHAR: + case TYPE_BASIC_WCHAR: + case TYPE_BASIC_HYPER: + return TRUE; + case TYPE_BASIC_FLOAT: + case TYPE_BASIC_DOUBLE: + case TYPE_BASIC_ERROR_STATUS_T: + case TYPE_BASIC_HANDLE: + return FALSE; + } + return FALSE; + default: + return FALSE; + } +} + static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type) { type_t *ptrchain_type; @@ -5174,11 +5540,12 @@ static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type) return ptrchain; } -static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, - int top) +static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, + int top) { - expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); - expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); + var_t *v = decl->var; + expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS); + expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS); int sizeless; expr_t *dim; type_t **ptype; @@ -5203,6 +5570,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, /* add type onto the end of the pointers in pident->type */ v->type = append_ptrchain_type(decl ? decl->type : NULL, type); v->stgclass = decl_spec->stgclass; + v->attrs = attrs; /* check for pointer attribute being applied to non-pointer, non-array * type */ @@ -5241,9 +5609,26 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, error_loc("%s: pointer attribute applied to non-pointer type\n", v->name); } - if (is_attr(v->attrs, ATTR_STRING) && !is_ptr(v->type) && !arr) - error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n", - v->name); + if (is_attr(v->attrs, ATTR_STRING)) + { + type_t *t = type; + + if (!is_ptr(v->type) && !arr) + error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n", + v->name); + + while (is_ptr(t)) + t = type_pointer_get_ref(t); + + if (type_get_type(t) != TYPE_BASIC && + (get_basic_fc(t) != RPC_FC_CHAR && + get_basic_fc(t) != RPC_FC_BYTE && + get_basic_fc(t) != RPC_FC_WCHAR)) + { + error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", + v->name); + } + } if (is_attr(v->attrs, ATTR_V1ENUM)) { @@ -5251,6 +5636,10 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name); } + if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type)) + error_loc("'%s': [range] attribute applied to non-integer type\n", + v->name); + ptype = &v->type; sizeless = FALSE; if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) @@ -5367,6 +5756,11 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, if (is_attr(t->attrs, ATTR_CALLCONV)) error_loc("calling convention applied to non-function-pointer type\n"); } + + if (decl->bits) + v->type = type_new_bitfield(v->type, decl->bits); + + return v; } static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls) @@ -5376,13 +5770,11 @@ static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, dec LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry ) { - var_t *var = decl->var; - - var->attrs = attrs; - set_type(var, decl_spec, decl, 0); + var_t *var = declare_var(attrs, decl_spec, decl, 0); var_list = append_var(var_list, var); free(decl); } + free(decl_spec); return var_list; } @@ -5456,10 +5848,11 @@ static declarator_list_t *append_declarator(declarator_list_t *list, declarator_ static declarator_t *make_declarator(var_t *var) { declarator_t *d = xmalloc(sizeof(*d)); - d->var = var; + d->var = var ? var : make_var(NULL); d->type = NULL; d->func_type = NULL; d->array = NULL; + d->bits = NULL; return d; } @@ -5600,27 +5993,8 @@ static void fix_incomplete_types(type_t *complete_type) static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs) { const declarator_t *decl; - int is_str = is_attr(attrs, ATTR_STRING); type_t *type = decl_spec->type; - if (is_str) - { - type_t *t = decl_spec->type; - - while (is_ptr(t)) - t = type_pointer_get_ref(t); - - if (type_get_type(t) != TYPE_BASIC && - (get_basic_fc(t) != RPC_FC_CHAR && - get_basic_fc(t) != RPC_FC_BYTE && - get_basic_fc(t) != RPC_FC_WCHAR)) - { - decl = LIST_ENTRY( list_head( decls ), const declarator_t, entry ); - error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", - decl->var->name); - } - } - /* We must generate names for tagless enum, struct or union. Typedef-ing a tagless enum, struct or union means we want the typedef to be included in a library hence the public attribute. */ @@ -5639,20 +6013,18 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry ) { - var_t *name = decl->var; - if (name->name) { + if (decl->var->name) { type_t *cur; + var_t *name; - cur = find_type(name->name, 0); + cur = find_type(decl->var->name, 0); if (cur) error_loc("%s: redefinition error; original definition was at %s:%d\n", cur->name, cur->loc_info.input_name, cur->loc_info.line_number); - /* set the attributes to allow set_type to do some checks on them */ - name->attrs = attrs; - set_type(name, decl_spec, decl, 0); + name = declare_var(attrs, decl_spec, decl, 0); cur = type_new_alias(name->type, name->name); cur->attrs = attrs; @@ -5797,6 +6169,7 @@ struct allowed_attr allowed_attr[] = { /* attr { D ACF I Fn ARG T En St Un Fi L DI M C } */ /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "aggregatable" }, + /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" }, /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "appobject" }, /* ATTR_ASYNC */ { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" }, /* ATTR_AUTO_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" }, @@ -5902,14 +6275,10 @@ static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs) return attrs; } -static void check_arg(var_t *arg) +static void check_arg_attrs(const var_t *arg) { - const type_t *t = arg->type; const attr_t *attr; - if (type_get_type(t) == TYPE_VOID) - error_loc("argument '%s' has void type\n", arg->name); - if (arg->attrs) { LIST_FOR_EACH_ENTRY(attr, arg->attrs, const attr_t, entry) @@ -6075,6 +6444,7 @@ static int is_allowed_conf_type(const type_t *type) case TYPE_COCLASS: case TYPE_FUNCTION: case TYPE_INTERFACE: + case TYPE_BITFIELD: return FALSE; } return FALSE; @@ -6118,24 +6488,30 @@ static void check_field_common(const type_t *container_type, { type_t *type = arg->type; int more_to_do; - const char *container_type_name = NULL; + const char *container_type_name; + const char *var_type; - switch (type_get_type_detect_alias(type)) + switch (type_get_type(container_type)) { case TYPE_STRUCT: container_type_name = "struct"; + var_type = "field"; break; case TYPE_UNION: container_type_name = "union"; + var_type = "arm"; break; case TYPE_ENCAPSULATED_UNION: container_type_name = "encapsulated union"; + var_type = "arm"; break; case TYPE_FUNCTION: container_type_name = "function"; + var_type = "parameter"; break; default: - break; + /* should be no other container types */ + assert(0); } if (is_attr(arg->attrs, ATTR_LENGTHIS) && @@ -6195,28 +6571,48 @@ static void check_field_common(const type_t *container_type, check_remoting_fields(arg, type); break; case TGT_INVALID: + { + const char *reason = "is invalid"; switch (type_get_type(type)) { case TYPE_VOID: - error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n", - arg->name, container_type_name, container_name); + reason = "cannot derive from void *"; break; case TYPE_FUNCTION: - error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n", - arg->name, container_type_name, container_name); + reason = "cannot be a function pointer"; + break; + case TYPE_BITFIELD: + reason = "cannot be a bit-field"; break; case TYPE_COCLASS: + reason = "cannot be a class"; + break; case TYPE_INTERFACE: + reason = "cannot be a non-pointer to an interface"; + break; case TYPE_MODULE: - /* FIXME */ + reason = "cannot be a module"; break; default: break; } + error_loc_info(&arg->loc_info, "%s \'%s\' of %s \'%s\' %s\n", + var_type, arg->name, container_type_name, container_name, reason); + break; + } case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: /* FIXME */ break; + case TGT_STRING: + { + const type_t *t = type; + while (is_ptr(t)) + t = type_pointer_get_ref(t); + if (is_aliaschain_attr(t, ATTR_RANGE)) + warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name); + break; + } case TGT_POINTER: type = type_pointer_get_ref(type); more_to_do = TRUE; @@ -6226,10 +6622,10 @@ static void check_field_common(const type_t *container_type, more_to_do = TRUE; break; case TGT_USER_TYPE: - case TGT_STRING: case TGT_IFACE_POINTER: case TGT_BASIC: case TGT_ENUM: + case TGT_RANGE: /* nothing to do */ break; } @@ -6279,6 +6675,7 @@ static void check_remoting_args(const var_t *func) { case TGT_BASIC: case TGT_ENUM: + case TGT_RANGE: case TGT_STRUCT: case TGT_UNION: case TGT_CTXT_HANDLE: @@ -6306,6 +6703,16 @@ static void check_remoting_args(const var_t *func) check_field_common(func->type, funcname, arg); } + + if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID) + { + var_t var; + var = *func; + var.type = type_function_get_rettype(func->type); + var.name = xstrdup("return value"); + check_field_common(func->type, funcname, &var); + free(var.name); + } } static void add_explicit_handle_if_necessary(var_t *func) diff --git a/reactos/tools/widl/parser.tab.h b/reactos/tools/widl/parser.tab.h index f1d74806377..73f6993dbcc 100644 --- a/reactos/tools/widl/parser.tab.h +++ b/reactos/tools/widl/parser.tab.h @@ -57,136 +57,139 @@ LESSEQUAL = 273, LOGICALOR = 274, LOGICALAND = 275, - tAGGREGATABLE = 276, - tALLOCATE = 277, - tAPPOBJECT = 278, - tASYNC = 279, - tASYNCUUID = 280, - tAUTOHANDLE = 281, - tBINDABLE = 282, - tBOOLEAN = 283, - tBROADCAST = 284, - tBYTE = 285, - tBYTECOUNT = 286, - tCALLAS = 287, - tCALLBACK = 288, - tCASE = 289, - tCDECL = 290, - tCHAR = 291, - tCOCLASS = 292, - tCODE = 293, - tCOMMSTATUS = 294, - tCONST = 295, - tCONTEXTHANDLE = 296, - tCONTEXTHANDLENOSERIALIZE = 297, - tCONTEXTHANDLESERIALIZE = 298, - tCONTROL = 299, - tCPPQUOTE = 300, - tDEFAULT = 301, - tDEFAULTCOLLELEM = 302, - tDEFAULTVALUE = 303, - tDEFAULTVTABLE = 304, - tDISPLAYBIND = 305, - tDISPINTERFACE = 306, - tDLLNAME = 307, - tDOUBLE = 308, - tDUAL = 309, - tENDPOINT = 310, - tENTRY = 311, - tENUM = 312, - tERRORSTATUST = 313, - tEXPLICITHANDLE = 314, - tEXTERN = 315, - tFALSE = 316, - tFASTCALL = 317, - tFLOAT = 318, - tHANDLE = 319, - tHANDLET = 320, - tHELPCONTEXT = 321, - tHELPFILE = 322, - tHELPSTRING = 323, - tHELPSTRINGCONTEXT = 324, - tHELPSTRINGDLL = 325, - tHIDDEN = 326, - tHYPER = 327, - tID = 328, - tIDEMPOTENT = 329, - tIIDIS = 330, - tIMMEDIATEBIND = 331, - tIMPLICITHANDLE = 332, - tIMPORT = 333, - tIMPORTLIB = 334, - tIN = 335, - tIN_LINE = 336, - tINLINE = 337, - tINPUTSYNC = 338, - tINT = 339, - tINT64 = 340, - tINTERFACE = 341, - tLCID = 342, - tLENGTHIS = 343, - tLIBRARY = 344, - tLOCAL = 345, - tLONG = 346, - tMETHODS = 347, - tMODULE = 348, - tNONBROWSABLE = 349, - tNONCREATABLE = 350, - tNONEXTENSIBLE = 351, - tNULL = 352, - tOBJECT = 353, - tODL = 354, - tOLEAUTOMATION = 355, - tOPTIONAL = 356, - tOUT = 357, - tPASCAL = 358, - tPOINTERDEFAULT = 359, - tPROPERTIES = 360, - tPROPGET = 361, - tPROPPUT = 362, - tPROPPUTREF = 363, - tPTR = 364, - tPUBLIC = 365, - tRANGE = 366, - tREADONLY = 367, - tREF = 368, - tREGISTER = 369, - tREQUESTEDIT = 370, - tRESTRICTED = 371, - tRETVAL = 372, - tSAFEARRAY = 373, - tSHORT = 374, - tSIGNED = 375, - tSIZEIS = 376, - tSIZEOF = 377, - tSMALL = 378, - tSOURCE = 379, - tSTATIC = 380, - tSTDCALL = 381, - tSTRICTCONTEXTHANDLE = 382, - tSTRING = 383, - tSTRUCT = 384, - tSWITCH = 385, - tSWITCHIS = 386, - tSWITCHTYPE = 387, - tTRANSMITAS = 388, - tTRUE = 389, - tTYPEDEF = 390, - tUNION = 391, - tUNIQUE = 392, - tUNSIGNED = 393, - tUUID = 394, - tV1ENUM = 395, - tVARARG = 396, - tVERSION = 397, - tVOID = 398, - tWCHAR = 399, - tWIREMARSHAL = 400, - ADDRESSOF = 401, - NEG = 402, - POS = 403, - PPTR = 404, - CAST = 405 + ELLIPSIS = 276, + tAGGREGATABLE = 277, + tALLOCATE = 278, + tANNOTATION = 279, + tAPPOBJECT = 280, + tASYNC = 281, + tASYNCUUID = 282, + tAUTOHANDLE = 283, + tBINDABLE = 284, + tBOOLEAN = 285, + tBROADCAST = 286, + tBYTE = 287, + tBYTECOUNT = 288, + tCALLAS = 289, + tCALLBACK = 290, + tCASE = 291, + tCDECL = 292, + tCHAR = 293, + tCOCLASS = 294, + tCODE = 295, + tCOMMSTATUS = 296, + tCONST = 297, + tCONTEXTHANDLE = 298, + tCONTEXTHANDLENOSERIALIZE = 299, + tCONTEXTHANDLESERIALIZE = 300, + tCONTROL = 301, + tCPPQUOTE = 302, + tDEFAULT = 303, + tDEFAULTCOLLELEM = 304, + tDEFAULTVALUE = 305, + tDEFAULTVTABLE = 306, + tDISPLAYBIND = 307, + tDISPINTERFACE = 308, + tDLLNAME = 309, + tDOUBLE = 310, + tDUAL = 311, + tENDPOINT = 312, + tENTRY = 313, + tENUM = 314, + tERRORSTATUST = 315, + tEXPLICITHANDLE = 316, + tEXTERN = 317, + tFALSE = 318, + tFASTCALL = 319, + tFLOAT = 320, + tHANDLE = 321, + tHANDLET = 322, + tHELPCONTEXT = 323, + tHELPFILE = 324, + tHELPSTRING = 325, + tHELPSTRINGCONTEXT = 326, + tHELPSTRINGDLL = 327, + tHIDDEN = 328, + tHYPER = 329, + tID = 330, + tIDEMPOTENT = 331, + tIIDIS = 332, + tIMMEDIATEBIND = 333, + tIMPLICITHANDLE = 334, + tIMPORT = 335, + tIMPORTLIB = 336, + tIN = 337, + tIN_LINE = 338, + tINLINE = 339, + tINPUTSYNC = 340, + tINT = 341, + tINT3264 = 342, + tINT64 = 343, + tINTERFACE = 344, + tLCID = 345, + tLENGTHIS = 346, + tLIBRARY = 347, + tLOCAL = 348, + tLONG = 349, + tMETHODS = 350, + tMODULE = 351, + tNONBROWSABLE = 352, + tNONCREATABLE = 353, + tNONEXTENSIBLE = 354, + tNULL = 355, + tOBJECT = 356, + tODL = 357, + tOLEAUTOMATION = 358, + tOPTIONAL = 359, + tOUT = 360, + tPASCAL = 361, + tPOINTERDEFAULT = 362, + tPROPERTIES = 363, + tPROPGET = 364, + tPROPPUT = 365, + tPROPPUTREF = 366, + tPTR = 367, + tPUBLIC = 368, + tRANGE = 369, + tREADONLY = 370, + tREF = 371, + tREGISTER = 372, + tREQUESTEDIT = 373, + tRESTRICTED = 374, + tRETVAL = 375, + tSAFEARRAY = 376, + tSHORT = 377, + tSIGNED = 378, + tSIZEIS = 379, + tSIZEOF = 380, + tSMALL = 381, + tSOURCE = 382, + tSTATIC = 383, + tSTDCALL = 384, + tSTRICTCONTEXTHANDLE = 385, + tSTRING = 386, + tSTRUCT = 387, + tSWITCH = 388, + tSWITCHIS = 389, + tSWITCHTYPE = 390, + tTRANSMITAS = 391, + tTRUE = 392, + tTYPEDEF = 393, + tUNION = 394, + tUNIQUE = 395, + tUNSIGNED = 396, + tUUID = 397, + tV1ENUM = 398, + tVARARG = 399, + tVERSION = 400, + tVOID = 401, + tWCHAR = 402, + tWIREMARSHAL = 403, + ADDRESSOF = 404, + NEG = 405, + POS = 406, + PPTR = 407, + CAST = 408 }; #endif @@ -229,7 +232,7 @@ typedef union YYSTYPE /* Line 1676 of yacc.c */ -#line 233 "parser.tab.h" +#line 236 "parser.tab.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ diff --git a/reactos/tools/widl/parser.y b/reactos/tools/widl/parser.y index c2f1abc2151..de44ab5626f 100644 --- a/reactos/tools/widl/parser.y +++ b/reactos/tools/widl/parser.y @@ -101,7 +101,7 @@ static attr_t *make_attrv(enum attr_type type, unsigned long val); static attr_t *make_attrp(enum attr_type type, void *val); static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); static array_dims_t *append_array(array_dims_t *list, expr_t *expr); -static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, int top); +static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, int top); static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls); static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_t *make_ifref(type_t *iface); @@ -121,7 +121,7 @@ static type_t *find_type_or_error2(char *name, int t); static var_t *reg_const(var_t *var); static char *gen_name(void); -static void check_arg(var_t *arg); +static void check_arg_attrs(const var_t *arg); static void check_statements(const statement_list_t *stmts, int is_inside_library); static void check_all_user_types(const statement_list_t *stmts); static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs); @@ -194,7 +194,8 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s %token EQUALITY INEQUALITY %token GREATEREQUAL LESSEQUAL %token LOGICALOR LOGICALAND -%token tAGGREGATABLE tALLOCATE tAPPOBJECT tASYNC tASYNCUUID +%token ELLIPSIS +%token tAGGREGATABLE tALLOCATE tANNOTATION tAPPOBJECT tASYNC tASYNCUUID %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT %token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS %token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE @@ -224,7 +225,7 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s %token tIMPORT tIMPORTLIB %token tIN tIN_LINE tINLINE %token tINPUTSYNC -%token tINT tINT64 +%token tINT tINT3264 tINT64 %token tINTERFACE %token tLCID %token tLENGTHIS tLIBRARY @@ -278,7 +279,7 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s %type attribute type_qualifier function_specifier %type m_attributes attributes attrib_list m_type_qual_list %type str_list -%type m_expr expr expr_const expr_int_const array +%type m_expr expr expr_const expr_int_const array m_bitfield %type m_exprs /* exprs expr_list */ expr_list_int_const %type interfacehdr %type storage_cls_spec @@ -292,10 +293,13 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s %type coclass_int %type coclass_ints %type arg ne_union_field union_field s_field case enum declaration -%type m_args no_args args fields ne_union_fields cases enums enum_list dispint_props field +%type m_args arg_list args +%type fields ne_union_fields cases enums enum_list dispint_props field %type m_ident ident -%type declarator direct_declarator init_declarator -%type declarator_list +%type declarator direct_declarator init_declarator struct_declarator +%type m_any_declarator any_declarator any_declarator_no_direct any_direct_declarator +%type m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator +%type declarator_list struct_declarator_list %type funcdef %type coclass coclasshdr coclassdef %type pointer_type version @@ -425,27 +429,24 @@ m_args: { $$ = NULL; } | args ; -no_args: tVOID { $$ = NULL; } +arg_list: arg { check_arg_attrs($1); $$ = append_var( NULL, $1 ); } + | arg_list ',' arg { check_arg_attrs($3); $$ = append_var( $1, $3 ); } ; -args: arg { check_arg($1); $$ = append_var( NULL, $1 ); } - | args ',' arg { check_arg($3); $$ = append_var( $1, $3); } - | no_args +args: arg_list + | arg_list ',' ELLIPSIS { $$ = append_var( $1, make_var(strdup("...")) ); } ; /* split into two rules to get bison to resolve a tVOID conflict */ -arg: attributes decl_spec declarator { $$ = $3->var; - $$->attrs = $1; - if ($2->stgclass != STG_NONE && $2->stgclass != STG_REGISTER) +arg: attributes decl_spec m_any_declarator { if ($2->stgclass != STG_NONE && $2->stgclass != STG_REGISTER) error_loc("invalid storage class for function parameter\n"); - set_type($$, $2, $3, TRUE); - free($3); + $$ = declare_var($1, $2, $3, TRUE); + free($2); free($3); } - | decl_spec declarator { $$ = $2->var; - if ($1->stgclass != STG_NONE && $1->stgclass != STG_REGISTER) + | decl_spec m_any_declarator { if ($1->stgclass != STG_NONE && $1->stgclass != STG_REGISTER) error_loc("invalid storage class for function parameter\n"); - set_type($$, $1, $2, TRUE); - free($2); + $$ = declare_var(NULL, $1, $2, TRUE); + free($1); free($2); } ; @@ -472,6 +473,7 @@ str_list: aSTRING { $$ = append_str( NULL, $1 ); } attribute: { $$ = NULL; } | tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); } + | tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); } | tAPPOBJECT { $$ = make_attr(ATTR_APPOBJECT); } | tASYNC { $$ = make_attr(ATTR_ASYNC); } | tAUTOHANDLE { $$ = make_attr(ATTR_AUTO_HANDLE); } @@ -658,8 +660,10 @@ expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); } | '*' expr %prec PPTR { $$ = make_expr1(EXPR_PPTR, $2); } | expr MEMBERPTR aIDENTIFIER { $$ = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, $1), make_exprs(EXPR_IDENTIFIER, $3)); } | expr '.' aIDENTIFIER { $$ = make_expr2(EXPR_MEMBER, $1, make_exprs(EXPR_IDENTIFIER, $3)); } - | '(' type ')' expr %prec CAST { $$ = make_exprt(EXPR_CAST, $2, $4); } - | tSIZEOF '(' type ')' { $$ = make_exprt(EXPR_SIZEOF, $3, NULL); } + | '(' decl_spec m_abstract_declarator ')' expr %prec CAST + { $$ = make_exprt(EXPR_CAST, declare_var(NULL, $2, $3, 0), $5); free($2); free($3); } + | tSIZEOF '(' decl_spec m_abstract_declarator ')' + { $$ = make_exprt(EXPR_SIZEOF, declare_var(NULL, $3, $4, 0), NULL); free($3); free($4); } | expr '[' expr ']' { $$ = make_expr2(EXPR_ARRAY, $1, $3); } | '(' expr ')' { $$ = $2; } ; @@ -684,7 +688,7 @@ fields: { $$ = NULL; } | fields field { $$ = append_var_list($1, $2); } ; -field: m_attributes decl_spec declarator_list ';' +field: m_attributes decl_spec struct_declarator_list ';' { const char *first = LIST_ENTRY(list_head($3), declarator_t, entry)->var->name; check_field_attrs(first, $1); $$ = set_var_types($1, $2, $3); @@ -709,17 +713,16 @@ union_field: | ';' { $$ = NULL; } ; -s_field: m_attributes decl_spec declarator { $$ = $3->var; - $$->attrs = check_field_attrs($$->name, $1); - set_type($$, $2, $3, FALSE); +s_field: m_attributes decl_spec declarator { $$ = declare_var(check_field_attrs($3->var->name, $1), + $2, $3, FALSE); free($3); } ; funcdef: - m_attributes decl_spec declarator { var_t *v = $3->var; - v->attrs = check_function_attrs(v->name, $1); - set_type(v, $2, $3, FALSE); + m_attributes decl_spec declarator { var_t *v; + v = declare_var(check_function_attrs($3->var->name, $1), + $2, $3, FALSE); free($3); $$ = make_func(v); } @@ -727,13 +730,10 @@ funcdef: declaration: attributes decl_spec init_declarator - { $$ = $3->var; - $$->attrs = $1; - set_type($$, $2, $3, FALSE); + { $$ = declare_var($1, $2, $3, FALSE); free($3); } - | decl_spec init_declarator { $$ = $2->var; - set_type($$, $1, $2, FALSE); + | decl_spec init_declarator { $$ = declare_var(NULL, $1, $2, FALSE); free($2); } ; @@ -776,6 +776,7 @@ int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); } | tHYPER m_int { $$ = type_new_int(TYPE_BASIC_HYPER, 0); } | tINT64 { $$ = type_new_int(TYPE_BASIC_INT64, 0); } | tCHAR { $$ = type_new_int(TYPE_BASIC_CHAR, 0); } + | tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); } ; coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); } @@ -944,11 +945,104 @@ direct_declarator: } ; +/* abstract declarator */ +abstract_declarator: + '*' m_type_qual_list m_abstract_declarator %prec PPTR + { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } + | callconv m_abstract_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } + | abstract_direct_declarator + ; + +/* abstract declarator without accepting direct declarator */ +abstract_declarator_no_direct: + '*' m_type_qual_list m_any_declarator %prec PPTR + { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } + | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } + ; + +/* abstract declarator or empty */ +m_abstract_declarator: { $$ = make_declarator(NULL); } + | abstract_declarator + ; + +/* abstract direct declarator */ +abstract_direct_declarator: + '(' abstract_declarator_no_direct ')' { $$ = $2; } + | abstract_direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); } + | array { $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); } + | '(' m_args ')' + { $$ = make_declarator(NULL); + $$->func_type = append_ptrchain_type($$->type, type_new_function($2)); + $$->type = NULL; + } + | abstract_direct_declarator '(' m_args ')' + { $$ = $1; + $$->func_type = append_ptrchain_type($$->type, type_new_function($3)); + $$->type = NULL; + } + ; + +/* abstract or non-abstract declarator */ +any_declarator: + '*' m_type_qual_list m_any_declarator %prec PPTR + { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } + | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } + | any_direct_declarator + ; + +/* abstract or non-abstract declarator without accepting direct declarator */ +any_declarator_no_direct: + '*' m_type_qual_list m_any_declarator %prec PPTR + { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } + | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } + ; + +/* abstract or non-abstract declarator or empty */ +m_any_declarator: { $$ = make_declarator(NULL); } + | any_declarator + ; + +/* abstract or non-abstract direct declarator. note: direct declarators + * aren't accepted inside brackets to avoid ambiguity with the rule for + * function arguments */ +any_direct_declarator: + ident { $$ = make_declarator($1); } + | '(' any_declarator_no_direct ')' { $$ = $2; } + | any_direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); } + | array { $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); } + | '(' m_args ')' + { $$ = make_declarator(NULL); + $$->func_type = append_ptrchain_type($$->type, type_new_function($2)); + $$->type = NULL; + } + | any_direct_declarator '(' m_args ')' + { $$ = $1; + $$->func_type = append_ptrchain_type($$->type, type_new_function($3)); + $$->type = NULL; + } + ; + declarator_list: declarator { $$ = append_declarator( NULL, $1 ); } | declarator_list ',' declarator { $$ = append_declarator( $1, $3 ); } ; +m_bitfield: { $$ = NULL; } + | ':' expr_const { $$ = $2; } + ; + +struct_declarator: any_declarator m_bitfield { $$ = $1; $$->bits = $2; + if (!$$->bits && !$$->var->name) + error_loc("unnamed fields are not allowed"); + } + ; + +struct_declarator_list: + struct_declarator { $$ = append_declarator( NULL, $1 ); } + | struct_declarator_list ',' struct_declarator + { $$ = append_declarator( $1, $3 ); } + ; + init_declarator: declarator { $$ = $1; } | declarator '=' expr_const { $$ = $1; $1->var->eval = $3; } @@ -1237,6 +1331,38 @@ static void type_function_add_head_arg(type_t *type, var_t *arg) list_add_head( type->details.function->args, &arg->entry ); } +static int is_allowed_range_type(const type_t *type) +{ + switch (type_get_type(type)) + { + case TYPE_ENUM: + return TRUE; + case TYPE_BASIC: + switch (type_basic_get_type(type)) + { + case TYPE_BASIC_INT8: + case TYPE_BASIC_INT16: + case TYPE_BASIC_INT32: + case TYPE_BASIC_INT64: + case TYPE_BASIC_INT: + case TYPE_BASIC_INT3264: + case TYPE_BASIC_BYTE: + case TYPE_BASIC_CHAR: + case TYPE_BASIC_WCHAR: + case TYPE_BASIC_HYPER: + return TRUE; + case TYPE_BASIC_FLOAT: + case TYPE_BASIC_DOUBLE: + case TYPE_BASIC_ERROR_STATUS_T: + case TYPE_BASIC_HANDLE: + return FALSE; + } + return FALSE; + default: + return FALSE; + } +} + static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type) { type_t *ptrchain_type; @@ -1249,11 +1375,12 @@ static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type) return ptrchain; } -static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, - int top) +static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, + int top) { - expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); - expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS); + var_t *v = decl->var; + expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS); + expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS); int sizeless; expr_t *dim; type_t **ptype; @@ -1278,6 +1405,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, /* add type onto the end of the pointers in pident->type */ v->type = append_ptrchain_type(decl ? decl->type : NULL, type); v->stgclass = decl_spec->stgclass; + v->attrs = attrs; /* check for pointer attribute being applied to non-pointer, non-array * type */ @@ -1316,9 +1444,26 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, error_loc("%s: pointer attribute applied to non-pointer type\n", v->name); } - if (is_attr(v->attrs, ATTR_STRING) && !is_ptr(v->type) && !arr) - error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n", - v->name); + if (is_attr(v->attrs, ATTR_STRING)) + { + type_t *t = type; + + if (!is_ptr(v->type) && !arr) + error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n", + v->name); + + while (is_ptr(t)) + t = type_pointer_get_ref(t); + + if (type_get_type(t) != TYPE_BASIC && + (get_basic_fc(t) != RPC_FC_CHAR && + get_basic_fc(t) != RPC_FC_BYTE && + get_basic_fc(t) != RPC_FC_WCHAR)) + { + error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", + v->name); + } + } if (is_attr(v->attrs, ATTR_V1ENUM)) { @@ -1326,6 +1471,10 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name); } + if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type)) + error_loc("'%s': [range] attribute applied to non-integer type\n", + v->name); + ptype = &v->type; sizeless = FALSE; if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) @@ -1442,6 +1591,11 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, if (is_attr(t->attrs, ATTR_CALLCONV)) error_loc("calling convention applied to non-function-pointer type\n"); } + + if (decl->bits) + v->type = type_new_bitfield(v->type, decl->bits); + + return v; } static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls) @@ -1451,13 +1605,11 @@ static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, dec LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry ) { - var_t *var = decl->var; - - var->attrs = attrs; - set_type(var, decl_spec, decl, 0); + var_t *var = declare_var(attrs, decl_spec, decl, 0); var_list = append_var(var_list, var); free(decl); } + free(decl_spec); return var_list; } @@ -1531,10 +1683,11 @@ static declarator_list_t *append_declarator(declarator_list_t *list, declarator_ static declarator_t *make_declarator(var_t *var) { declarator_t *d = xmalloc(sizeof(*d)); - d->var = var; + d->var = var ? var : make_var(NULL); d->type = NULL; d->func_type = NULL; d->array = NULL; + d->bits = NULL; return d; } @@ -1675,27 +1828,8 @@ static void fix_incomplete_types(type_t *complete_type) static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs) { const declarator_t *decl; - int is_str = is_attr(attrs, ATTR_STRING); type_t *type = decl_spec->type; - if (is_str) - { - type_t *t = decl_spec->type; - - while (is_ptr(t)) - t = type_pointer_get_ref(t); - - if (type_get_type(t) != TYPE_BASIC && - (get_basic_fc(t) != RPC_FC_CHAR && - get_basic_fc(t) != RPC_FC_BYTE && - get_basic_fc(t) != RPC_FC_WCHAR)) - { - decl = LIST_ENTRY( list_head( decls ), const declarator_t, entry ); - error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", - decl->var->name); - } - } - /* We must generate names for tagless enum, struct or union. Typedef-ing a tagless enum, struct or union means we want the typedef to be included in a library hence the public attribute. */ @@ -1714,20 +1848,18 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry ) { - var_t *name = decl->var; - if (name->name) { + if (decl->var->name) { type_t *cur; + var_t *name; - cur = find_type(name->name, 0); + cur = find_type(decl->var->name, 0); if (cur) error_loc("%s: redefinition error; original definition was at %s:%d\n", cur->name, cur->loc_info.input_name, cur->loc_info.line_number); - /* set the attributes to allow set_type to do some checks on them */ - name->attrs = attrs; - set_type(name, decl_spec, decl, 0); + name = declare_var(attrs, decl_spec, decl, 0); cur = type_new_alias(name->type, name->name); cur->attrs = attrs; @@ -1872,6 +2004,7 @@ struct allowed_attr allowed_attr[] = { /* attr { D ACF I Fn ARG T En St Un Fi L DI M C } */ /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "aggregatable" }, + /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" }, /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "appobject" }, /* ATTR_ASYNC */ { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" }, /* ATTR_AUTO_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" }, @@ -1977,14 +2110,10 @@ static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs) return attrs; } -static void check_arg(var_t *arg) +static void check_arg_attrs(const var_t *arg) { - const type_t *t = arg->type; const attr_t *attr; - if (type_get_type(t) == TYPE_VOID) - error_loc("argument '%s' has void type\n", arg->name); - if (arg->attrs) { LIST_FOR_EACH_ENTRY(attr, arg->attrs, const attr_t, entry) @@ -2150,6 +2279,7 @@ static int is_allowed_conf_type(const type_t *type) case TYPE_COCLASS: case TYPE_FUNCTION: case TYPE_INTERFACE: + case TYPE_BITFIELD: return FALSE; } return FALSE; @@ -2193,24 +2323,30 @@ static void check_field_common(const type_t *container_type, { type_t *type = arg->type; int more_to_do; - const char *container_type_name = NULL; + const char *container_type_name; + const char *var_type; - switch (type_get_type_detect_alias(type)) + switch (type_get_type(container_type)) { case TYPE_STRUCT: container_type_name = "struct"; + var_type = "field"; break; case TYPE_UNION: container_type_name = "union"; + var_type = "arm"; break; case TYPE_ENCAPSULATED_UNION: container_type_name = "encapsulated union"; + var_type = "arm"; break; case TYPE_FUNCTION: container_type_name = "function"; + var_type = "parameter"; break; default: - break; + /* should be no other container types */ + assert(0); } if (is_attr(arg->attrs, ATTR_LENGTHIS) && @@ -2270,28 +2406,48 @@ static void check_field_common(const type_t *container_type, check_remoting_fields(arg, type); break; case TGT_INVALID: + { + const char *reason = "is invalid"; switch (type_get_type(type)) { case TYPE_VOID: - error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n", - arg->name, container_type_name, container_name); + reason = "cannot derive from void *"; break; case TYPE_FUNCTION: - error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n", - arg->name, container_type_name, container_name); + reason = "cannot be a function pointer"; + break; + case TYPE_BITFIELD: + reason = "cannot be a bit-field"; break; case TYPE_COCLASS: + reason = "cannot be a class"; + break; case TYPE_INTERFACE: + reason = "cannot be a non-pointer to an interface"; + break; case TYPE_MODULE: - /* FIXME */ + reason = "cannot be a module"; break; default: break; } + error_loc_info(&arg->loc_info, "%s \'%s\' of %s \'%s\' %s\n", + var_type, arg->name, container_type_name, container_name, reason); + break; + } case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: /* FIXME */ break; + case TGT_STRING: + { + const type_t *t = type; + while (is_ptr(t)) + t = type_pointer_get_ref(t); + if (is_aliaschain_attr(t, ATTR_RANGE)) + warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name); + break; + } case TGT_POINTER: type = type_pointer_get_ref(type); more_to_do = TRUE; @@ -2301,10 +2457,10 @@ static void check_field_common(const type_t *container_type, more_to_do = TRUE; break; case TGT_USER_TYPE: - case TGT_STRING: case TGT_IFACE_POINTER: case TGT_BASIC: case TGT_ENUM: + case TGT_RANGE: /* nothing to do */ break; } @@ -2354,6 +2510,7 @@ static void check_remoting_args(const var_t *func) { case TGT_BASIC: case TGT_ENUM: + case TGT_RANGE: case TGT_STRUCT: case TGT_UNION: case TGT_CTXT_HANDLE: @@ -2381,6 +2538,16 @@ static void check_remoting_args(const var_t *func) check_field_common(func->type, funcname, arg); } + + if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID) + { + var_t var; + var = *func; + var.type = type_function_get_rettype(func->type); + var.name = xstrdup("return value"); + check_field_common(func->type, funcname, &var); + free(var.name); + } } static void add_explicit_handle_if_necessary(var_t *func) diff --git a/reactos/tools/widl/parser.yy.c b/reactos/tools/widl/parser.yy.c index 57c4cd90667..9cb425c8573 100644 --- a/reactos/tools/widl/parser.yy.c +++ b/reactos/tools/widl/parser.yy.c @@ -301,25 +301,26 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); *yy_cp = '\0'; \ yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 32 -#define YY_END_OF_BUFFER 33 -static yyconst short int yy_accept[139] = +#define YY_NUM_RULES 33 +#define YY_END_OF_BUFFER 34 +static yyconst short int yy_accept[142] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, - 33, 31, 21, 20, 31, 3, 31, 31, 16, 16, - 31, 31, 31, 19, 19, 19, 11, 31, 21, 1, - 10, 32, 4, 10, 6, 16, 16, 13, 13, 13, - 12, 2, 26, 30, 24, 0, 16, 16, 16, 0, - 22, 28, 25, 27, 23, 19, 5, 19, 29, 0, - 1, 1, 9, 8, 7, 16, 0, 13, 13, 2, - 17, 16, 16, 15, 19, 16, 0, 13, 0, 15, - 15, 19, 16, 0, 13, 0, 17, 15, 15, 19, - 16, 0, 13, 19, 16, 0, 13, 19, 16, 0, + 34, 32, 21, 20, 32, 3, 32, 32, 32, 16, + 16, 32, 32, 32, 19, 19, 19, 11, 32, 21, + 1, 10, 33, 4, 10, 6, 16, 16, 13, 13, + 13, 12, 2, 26, 30, 24, 0, 0, 16, 16, + 16, 0, 22, 28, 25, 27, 23, 19, 5, 19, + 29, 0, 1, 1, 9, 8, 7, 16, 0, 13, + 13, 2, 31, 17, 16, 16, 15, 19, 16, 0, + 13, 0, 15, 15, 19, 16, 0, 13, 0, 17, + 15, 15, 19, 16, 0, 13, 19, 16, 0, 13, - 13, 19, 16, 0, 13, 19, 0, 16, 0, 18, + 19, 16, 0, 13, 19, 16, 0, 13, 19, 0, + 16, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 14, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 0 } ; static yyconst int yy_ec[256] = @@ -362,112 +363,112 @@ static yyconst int yy_meta[36] = 3, 4, 4, 4, 1 } ; -static yyconst short int yy_base[175] = +static yyconst short int yy_base[178] = { 0, - 0, 34, 34, 38, 39, 42, 71, 44, 268, 267, - 265, 491, 491, 491, 249, 491, 256, 241, 96, 22, - 37, 241, 38, 0, 250, 237, 491, 218, 53, 249, - 491, 491, 491, 33, 491, 119, 23, 142, 165, 245, - 491, 0, 491, 491, 491, 48, 0, 33, 88, 0, - 491, 491, 491, 491, 491, 0, 491, 228, 491, 63, - 241, 240, 491, 491, 491, 185, 0, 207, 0, 0, - 104, 491, 491, 124, 222, 227, 0, 249, 102, 94, - 102, 220, 269, 0, 291, 113, 168, 491, 491, 213, - 311, 0, 333, 212, 353, 0, 375, 217, 395, 0, + 0, 34, 34, 38, 39, 42, 71, 44, 270, 269, + 271, 491, 491, 491, 255, 491, 258, 248, 252, 96, + 22, 37, 242, 38, 0, 251, 238, 491, 219, 53, + 251, 491, 491, 491, 33, 491, 119, 23, 142, 165, + 246, 491, 0, 491, 491, 491, 239, 48, 0, 33, + 88, 0, 491, 491, 491, 491, 491, 0, 491, 228, + 491, 63, 241, 240, 491, 491, 491, 185, 0, 207, + 0, 0, 491, 104, 491, 491, 124, 222, 227, 0, + 249, 102, 94, 102, 220, 269, 0, 291, 113, 168, + 491, 491, 213, 311, 0, 333, 212, 353, 0, 375, - 417, 206, 439, 222, 221, 62, 0, 220, 140, 491, - 0, 0, 0, 219, 0, 0, 0, 0, 218, 0, - 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 491, 491, 472, 476, - 478, 482, 486, 219, 218, 212, 211, 210, 209, 208, - 206, 205, 203, 198, 197, 192, 191, 190, 189, 188, - 187, 186, 185, 183, 176, 169, 168, 167, 155, 144, - 140, 137, 130, 110 + 217, 395, 0, 417, 206, 439, 222, 221, 62, 0, + 220, 140, 491, 0, 0, 0, 219, 0, 0, 0, + 0, 218, 0, 0, 0, 0, 213, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, + 491, 472, 476, 478, 482, 486, 219, 218, 212, 211, + 210, 209, 208, 206, 205, 203, 198, 197, 192, 191, + 190, 189, 188, 187, 186, 185, 183, 176, 169, 168, + 167, 155, 144, 140, 137, 130, 110 } ; -static yyconst short int yy_def[175] = +static yyconst short int yy_def[178] = { 0, - 138, 1, 139, 139, 139, 139, 138, 7, 140, 140, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 19, - 138, 138, 138, 141, 141, 141, 138, 138, 138, 138, - 138, 138, 138, 142, 138, 138, 36, 138, 38, 39, - 138, 143, 138, 138, 138, 138, 20, 138, 138, 144, - 138, 138, 138, 138, 138, 141, 138, 141, 138, 138, - 138, 138, 138, 138, 138, 138, 145, 39, 39, 143, - 138, 138, 138, 144, 141, 138, 146, 39, 138, 138, - 138, 141, 138, 147, 39, 138, 138, 138, 138, 141, - 138, 148, 39, 141, 138, 149, 39, 141, 138, 150, + 141, 1, 142, 142, 142, 142, 141, 7, 143, 143, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 20, 141, 141, 141, 144, 144, 144, 141, 141, 141, + 141, 141, 141, 141, 145, 141, 141, 37, 141, 39, + 40, 141, 146, 141, 141, 141, 141, 141, 21, 141, + 141, 147, 141, 141, 141, 141, 141, 144, 141, 144, + 141, 141, 141, 141, 141, 141, 141, 141, 148, 40, + 40, 146, 141, 141, 141, 141, 147, 144, 141, 149, + 40, 141, 141, 141, 144, 141, 150, 40, 141, 141, + 141, 141, 144, 141, 151, 40, 144, 141, 152, 40, - 39, 141, 138, 138, 39, 141, 151, 103, 138, 138, - 152, 153, 154, 138, 155, 156, 157, 158, 138, 159, - 160, 161, 162, 138, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 138, 0, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138 + 144, 141, 153, 40, 144, 141, 141, 40, 144, 154, + 106, 141, 141, 155, 156, 157, 141, 158, 159, 160, + 161, 141, 162, 163, 164, 165, 141, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 141, + 0, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141 } ; static yyconst short int yy_nxt[527] = { 0, 12, 13, 14, 15, 16, 12, 17, 12, 12, 18, - 12, 19, 20, 21, 22, 23, 24, 24, 24, 24, - 24, 25, 24, 26, 24, 24, 24, 27, 12, 12, - 24, 24, 24, 24, 28, 29, 32, 64, 33, 30, - 32, 32, 33, 35, 32, 29, 35, 138, 138, 30, - 51, 52, 54, 55, 60, 138, 138, 72, 61, 71, - 71, 65, 34, 109, 60, 72, 34, 34, 61, 110, - 34, 12, 13, 14, 15, 16, 12, 17, 12, 12, - 18, 12, 36, 37, 21, 22, 23, 38, 38, 38, - 38, 39, 40, 39, 39, 39, 39, 39, 27, 12, + 19, 20, 21, 22, 23, 24, 25, 25, 25, 25, + 25, 26, 25, 27, 25, 25, 25, 28, 12, 12, + 25, 25, 25, 25, 29, 30, 33, 66, 34, 31, + 33, 33, 34, 36, 33, 30, 36, 141, 141, 31, + 53, 54, 56, 57, 62, 141, 141, 75, 63, 74, + 74, 67, 35, 112, 62, 75, 35, 35, 63, 113, + 35, 12, 13, 14, 15, 16, 12, 17, 12, 12, + 18, 19, 37, 38, 22, 23, 24, 39, 39, 39, + 39, 40, 41, 40, 40, 40, 40, 40, 28, 12, - 41, 38, 39, 39, 39, 28, 46, 47, 47, 73, - 86, 86, 137, 87, 87, 71, 71, 48, 88, 73, - 49, 50, 79, 89, 87, 87, 88, 48, 49, 50, - 66, 66, 136, 89, 79, 67, 67, 67, 67, 135, - 48, 109, 134, 49, 50, 80, 133, 110, 81, 67, - 48, 49, 50, 68, 68, 80, 81, 132, 68, 68, - 68, 68, 69, 69, 69, 69, 69, 69, 69, 131, - 130, 129, 68, 69, 69, 69, 69, 69, 128, 87, - 87, 69, 69, 69, 69, 127, 79, 126, 124, 123, - 122, 121, 119, 118, 117, 69, 76, 76, 79, 116, + 42, 39, 40, 40, 40, 29, 48, 49, 49, 76, + 89, 89, 140, 90, 90, 74, 74, 50, 91, 76, + 51, 52, 82, 92, 90, 90, 91, 50, 51, 52, + 68, 68, 139, 92, 82, 69, 69, 69, 69, 138, + 50, 112, 137, 51, 52, 83, 136, 113, 84, 69, + 50, 51, 52, 70, 70, 83, 84, 135, 70, 70, + 70, 70, 71, 71, 71, 71, 71, 71, 71, 134, + 133, 132, 70, 71, 71, 71, 71, 71, 131, 90, + 90, 71, 71, 71, 71, 130, 82, 129, 127, 126, + 125, 124, 122, 121, 120, 71, 79, 79, 82, 119, - 114, 77, 77, 77, 77, 113, 48, 112, 111, 49, - 104, 100, 96, 92, 84, 77, 48, 49, 78, 78, - 77, 74, 125, 78, 78, 78, 78, 120, 115, 138, - 107, 107, 106, 102, 98, 94, 90, 78, 83, 83, - 82, 62, 62, 84, 84, 84, 84, 75, 48, 57, - 62, 49, 59, 58, 57, 53, 45, 84, 48, 49, - 85, 85, 44, 43, 138, 85, 85, 85, 85, 32, - 32, 138, 138, 138, 138, 138, 138, 138, 138, 85, - 91, 91, 138, 138, 138, 92, 92, 92, 92, 138, - 48, 138, 138, 49, 138, 138, 138, 138, 138, 92, + 117, 80, 80, 80, 80, 116, 50, 115, 114, 51, + 107, 103, 99, 95, 87, 80, 50, 51, 81, 81, + 80, 77, 128, 81, 81, 81, 81, 123, 118, 141, + 110, 110, 109, 105, 101, 97, 93, 81, 86, 86, + 85, 64, 64, 87, 87, 87, 87, 78, 50, 73, + 59, 51, 64, 61, 60, 59, 55, 87, 50, 51, + 88, 88, 47, 46, 45, 88, 88, 88, 88, 44, + 141, 33, 33, 141, 141, 141, 141, 141, 141, 88, + 94, 94, 141, 141, 141, 95, 95, 95, 95, 141, + 50, 141, 141, 51, 141, 141, 141, 141, 141, 95, - 48, 49, 93, 93, 138, 138, 138, 93, 93, 93, - 93, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 93, 95, 95, 138, 138, 138, 96, 96, 96, - 96, 138, 48, 138, 138, 49, 138, 138, 138, 138, - 138, 96, 48, 49, 97, 97, 138, 138, 138, 97, - 97, 97, 97, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 97, 99, 99, 138, 138, 138, 100, - 100, 100, 100, 138, 48, 138, 138, 49, 138, 138, - 138, 138, 138, 100, 48, 49, 101, 101, 138, 138, - 138, 101, 101, 101, 101, 138, 138, 138, 138, 138, + 50, 51, 96, 96, 141, 141, 141, 96, 96, 96, + 96, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 96, 98, 98, 141, 141, 141, 99, 99, 99, + 99, 141, 50, 141, 141, 51, 141, 141, 141, 141, + 141, 99, 50, 51, 100, 100, 141, 141, 141, 100, + 100, 100, 100, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 100, 102, 102, 141, 141, 141, 103, + 103, 103, 103, 141, 50, 141, 141, 51, 141, 141, + 141, 141, 141, 103, 50, 51, 104, 104, 141, 141, + 141, 104, 104, 104, 104, 141, 141, 141, 141, 141, - 138, 138, 138, 138, 138, 101, 103, 103, 138, 138, - 138, 104, 104, 104, 104, 138, 48, 138, 138, 49, - 138, 138, 138, 138, 138, 104, 48, 49, 105, 105, - 138, 138, 138, 105, 105, 105, 105, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 105, 107, 138, - 108, 108, 138, 138, 138, 138, 138, 138, 138, 138, - 48, 138, 138, 49, 138, 138, 138, 138, 138, 138, - 48, 49, 31, 31, 31, 31, 42, 42, 42, 42, - 56, 56, 63, 138, 63, 63, 70, 138, 70, 70, - 11, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 141, 141, 141, 141, 141, 104, 106, 106, 141, 141, + 141, 107, 107, 107, 107, 141, 50, 141, 141, 51, + 141, 141, 141, 141, 141, 107, 50, 51, 108, 108, + 141, 141, 141, 108, 108, 108, 108, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 108, 110, 141, + 111, 111, 141, 141, 141, 141, 141, 141, 141, 141, + 50, 141, 141, 51, 141, 141, 141, 141, 141, 141, + 50, 51, 32, 32, 32, 32, 43, 43, 43, 43, + 58, 58, 65, 141, 65, 65, 72, 141, 72, 72, + 11, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138 + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141 } ; static yyconst short int yy_chk[527] = @@ -475,61 +476,61 @@ static yyconst short int yy_chk[527] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 3, 34, 3, 2, - 4, 5, 4, 5, 6, 8, 6, 20, 37, 8, - 21, 21, 23, 23, 29, 20, 37, 48, 29, 46, - 46, 34, 3, 106, 60, 48, 4, 5, 60, 106, + 1, 1, 1, 1, 1, 2, 3, 35, 3, 2, + 4, 5, 4, 5, 6, 8, 6, 21, 38, 8, + 22, 22, 24, 24, 30, 21, 38, 50, 30, 48, + 48, 35, 3, 109, 62, 50, 4, 5, 62, 109, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 19, 19, 19, 49, - 79, 79, 174, 79, 79, 71, 71, 19, 80, 49, - 19, 19, 71, 81, 86, 86, 80, 19, 19, 19, - 36, 36, 173, 81, 71, 36, 36, 36, 36, 172, - 36, 109, 171, 36, 36, 74, 170, 109, 74, 36, - 36, 36, 36, 38, 38, 74, 74, 169, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 168, - 167, 166, 38, 38, 38, 38, 39, 39, 165, 87, - 87, 39, 39, 39, 39, 164, 87, 163, 162, 161, - 160, 159, 158, 157, 156, 39, 66, 66, 87, 155, + 7, 7, 7, 7, 7, 7, 20, 20, 20, 51, + 82, 82, 177, 82, 82, 74, 74, 20, 83, 51, + 20, 20, 74, 84, 89, 89, 83, 20, 20, 20, + 37, 37, 176, 84, 74, 37, 37, 37, 37, 175, + 37, 112, 174, 37, 37, 77, 173, 112, 77, 37, + 37, 37, 37, 39, 39, 77, 77, 172, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 171, + 170, 169, 39, 39, 39, 39, 40, 40, 168, 90, + 90, 40, 40, 40, 40, 167, 90, 166, 165, 164, + 163, 162, 161, 160, 159, 40, 68, 68, 90, 158, - 154, 66, 66, 66, 66, 153, 66, 152, 151, 66, - 150, 149, 148, 147, 146, 66, 66, 66, 68, 68, - 145, 144, 124, 68, 68, 68, 68, 119, 114, 108, - 105, 104, 102, 98, 94, 90, 82, 68, 76, 76, - 75, 62, 61, 76, 76, 76, 76, 58, 76, 40, - 30, 76, 28, 26, 25, 22, 18, 76, 76, 76, - 78, 78, 17, 15, 11, 78, 78, 78, 78, 10, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 78, - 83, 83, 0, 0, 0, 83, 83, 83, 83, 0, - 83, 0, 0, 83, 0, 0, 0, 0, 0, 83, + 157, 68, 68, 68, 68, 156, 68, 155, 154, 68, + 153, 152, 151, 150, 149, 68, 68, 68, 70, 70, + 148, 147, 127, 70, 70, 70, 70, 122, 117, 111, + 108, 107, 105, 101, 97, 93, 85, 70, 79, 79, + 78, 64, 63, 79, 79, 79, 79, 60, 79, 47, + 41, 79, 31, 29, 27, 26, 23, 79, 79, 79, + 81, 81, 19, 18, 17, 81, 81, 81, 81, 15, + 11, 10, 9, 0, 0, 0, 0, 0, 0, 81, + 86, 86, 0, 0, 0, 86, 86, 86, 86, 0, + 86, 0, 0, 86, 0, 0, 0, 0, 0, 86, - 83, 83, 85, 85, 0, 0, 0, 85, 85, 85, - 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 85, 91, 91, 0, 0, 0, 91, 91, 91, - 91, 0, 91, 0, 0, 91, 0, 0, 0, 0, - 0, 91, 91, 91, 93, 93, 0, 0, 0, 93, - 93, 93, 93, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 93, 95, 95, 0, 0, 0, 95, - 95, 95, 95, 0, 95, 0, 0, 95, 0, 0, - 0, 0, 0, 95, 95, 95, 97, 97, 0, 0, - 0, 97, 97, 97, 97, 0, 0, 0, 0, 0, + 86, 86, 88, 88, 0, 0, 0, 88, 88, 88, + 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 88, 94, 94, 0, 0, 0, 94, 94, 94, + 94, 0, 94, 0, 0, 94, 0, 0, 0, 0, + 0, 94, 94, 94, 96, 96, 0, 0, 0, 96, + 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 96, 98, 98, 0, 0, 0, 98, + 98, 98, 98, 0, 98, 0, 0, 98, 0, 0, + 0, 0, 0, 98, 98, 98, 100, 100, 0, 0, + 0, 100, 100, 100, 100, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 97, 99, 99, 0, 0, - 0, 99, 99, 99, 99, 0, 99, 0, 0, 99, - 0, 0, 0, 0, 0, 99, 99, 99, 101, 101, - 0, 0, 0, 101, 101, 101, 101, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 101, 103, 0, - 103, 103, 0, 0, 0, 0, 0, 0, 0, 0, - 103, 0, 0, 103, 0, 0, 0, 0, 0, 0, - 103, 103, 139, 139, 139, 139, 140, 140, 140, 140, - 141, 141, 142, 0, 142, 142, 143, 0, 143, 143, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 0, 0, 0, 0, 0, 100, 102, 102, 0, 0, + 0, 102, 102, 102, 102, 0, 102, 0, 0, 102, + 0, 0, 0, 0, 0, 102, 102, 102, 104, 104, + 0, 0, 0, 104, 104, 104, 104, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 104, 106, 0, + 106, 106, 0, 0, 0, 0, 0, 0, 0, 0, + 106, 0, 0, 106, 0, 0, 0, 0, 0, 0, + 106, 106, 142, 142, 142, 142, 143, 143, 143, 143, + 144, 144, 145, 0, 145, 145, 146, 0, 146, 146, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138 + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141 } ; static yy_state_type yy_last_accepting_state; @@ -661,7 +662,7 @@ UUID *parse_uuid(const char *u) * The flexer starts here ************************************************************************** */ -#line 665 "parser.yy.c" +#line 666 "parser.yy.c" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -817,7 +818,7 @@ YY_DECL #line 127 "parser.l" -#line 821 "parser.yy.c" +#line 822 "parser.yy.c" if ( yy_init ) { @@ -869,7 +870,7 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 139 ) + if ( yy_current_state >= 142 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1092,6 +1093,11 @@ return LOGICALAND; case 31: YY_RULE_SETUP #line 196 "parser.l" +return ELLIPSIS; + YY_BREAK +case 32: +YY_RULE_SETUP +#line 197 "parser.l" return yytext[0]; YY_BREAK case YY_STATE_EOF(INITIAL): @@ -1099,19 +1105,19 @@ case YY_STATE_EOF(QUOTE): case YY_STATE_EOF(WSTRQUOTE): case YY_STATE_EOF(ATTR): case YY_STATE_EOF(PP_LINE): -#line 197 "parser.l" +#line 198 "parser.l" { if (import_stack_ptr) return aEOF; else yyterminate(); } YY_BREAK -case 32: +case 33: YY_RULE_SETUP -#line 202 "parser.l" +#line 203 "parser.l" ECHO; YY_BREAK -#line 1115 "parser.yy.c" +#line 1121 "parser.yy.c" case YY_END_OF_BUFFER: { @@ -1402,7 +1408,7 @@ static yy_state_type yy_get_previous_state() while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 139 ) + if ( yy_current_state >= 142 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1437,11 +1443,11 @@ yy_state_type yy_current_state; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 139 ) + if ( yy_current_state >= 142 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 138); + yy_is_jam = (yy_current_state == 141); return yy_is_jam ? 0 : yy_current_state; } @@ -1997,7 +2003,7 @@ int main() return 0; } #endif -#line 202 "parser.l" +#line 203 "parser.l" #ifndef parser_wrap @@ -2019,6 +2025,7 @@ static const struct keyword keywords[] = { {"TRUE", tTRUE}, {"__cdecl", tCDECL}, {"__fastcall", tFASTCALL}, + {"__int3264", tINT3264}, {"__int64", tINT64}, {"__pascal", tPASCAL}, {"__stdcall", tSTDCALL}, @@ -2078,6 +2085,7 @@ static const struct keyword attr_keywords[] = { {"aggregatable", tAGGREGATABLE}, {"allocate", tALLOCATE}, + {"annotation", tANNOTATION}, {"appobject", tAPPOBJECT}, {"async", tASYNC}, {"async_uuid", tASYNCUUID}, diff --git a/reactos/tools/widl/typegen.c b/reactos/tools/widl/typegen.c index b41dcbec3f9..fdb2379a070 100644 --- a/reactos/tools/widl/typegen.c +++ b/reactos/tools/widl/typegen.c @@ -116,12 +116,27 @@ const char *string_of_type(unsigned char type) case RPC_FC_C_WSTRING: return "FC_C_WSTRING"; case RPC_FC_CSTRING: return "FC_CSTRING"; case RPC_FC_WSTRING: return "FC_WSTRING"; + case RPC_FC_INT3264: return "FC_INT3264"; + case RPC_FC_UINT3264: return "FC_UINT3264"; default: error("string_of_type: unknown type 0x%02x\n", type); return NULL; } } +static void *get_aliaschain_attrp(const type_t *type, enum attr_type attr) +{ + const type_t *t = type; + for (;;) + { + if (is_attr(t->attrs, attr)) + return get_attrp(t->attrs, attr); + else if (type_is_alias(t)) + t = type_alias_get_aliasee(t); + else return 0; + } +} + unsigned char get_basic_fc(const type_t *type) { int sign = type_basic_get_sign(type); @@ -132,6 +147,7 @@ unsigned char get_basic_fc(const type_t *type) case TYPE_BASIC_INT32: return (sign <= 0 ? RPC_FC_LONG : RPC_FC_ULONG); case TYPE_BASIC_INT64: return RPC_FC_HYPER; case TYPE_BASIC_INT: return (sign <= 0 ? RPC_FC_LONG : RPC_FC_ULONG); + case TYPE_BASIC_INT3264: return (sign <= 0 ? RPC_FC_INT3264 : RPC_FC_UINT3264); case TYPE_BASIC_BYTE: return RPC_FC_BYTE; case TYPE_BASIC_CHAR: return RPC_FC_CHAR; case TYPE_BASIC_WCHAR: return RPC_FC_WCHAR; @@ -140,8 +156,8 @@ unsigned char get_basic_fc(const type_t *type) case TYPE_BASIC_DOUBLE: return RPC_FC_DOUBLE; case TYPE_BASIC_ERROR_STATUS_T: return RPC_FC_ERROR_STATUS_T; case TYPE_BASIC_HANDLE: return RPC_FC_BIND_PRIMITIVE; - default: return 0; } + return 0; } static inline unsigned int clamp_align(unsigned int align) @@ -200,8 +216,14 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att switch (type_get_type(type)) { case TYPE_BASIC: + if (!(flags & TDT_IGNORE_RANGES) && + (is_attr(attrs, ATTR_RANGE) || is_aliaschain_attr(type, ATTR_RANGE))) + return TGT_RANGE; return TGT_BASIC; case TYPE_ENUM: + if (!(flags & TDT_IGNORE_RANGES) && + (is_attr(attrs, ATTR_RANGE) || is_aliaschain_attr(type, ATTR_RANGE))) + return TGT_RANGE; return TGT_ENUM; case TYPE_POINTER: if (type_get_type(type_pointer_get_ref(type)) == TYPE_INTERFACE || @@ -224,69 +246,12 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att case TYPE_MODULE: case TYPE_VOID: case TYPE_ALIAS: + case TYPE_BITFIELD: break; } return TGT_INVALID; } -static type_t *get_user_type(const type_t *t, const char **pname); - -static int type_contains_iface(const type_t *type) -{ - enum typegen_type typegen_type; - var_list_t *fields; - const var_t *field; - - typegen_type = typegen_detect_type(type, type->attrs, TDT_IGNORE_STRINGS); - - switch(typegen_type) - { - case TGT_USER_TYPE: - return type_contains_iface(get_user_type(type, NULL)); - - case TGT_BASIC: - case TGT_ENUM: - return FALSE; - - case TGT_POINTER: - return type_contains_iface(type_pointer_get_ref(type)); - - case TGT_ARRAY: - return type_contains_iface(type_array_get_element(type)); - - case TGT_IFACE_POINTER: - return TRUE; - - case TGT_STRUCT: - fields = type_struct_get_fields(type); - if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) - { - if(type_contains_iface(field->type)) - return TRUE; - } - return FALSE; - - case TGT_UNION: - fields = type_union_get_cases(type); - if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) - { - if(field->type && type_contains_iface(field->type)) - return TRUE; - } - return FALSE; - - case TGT_STRING: - /* shouldn't get here because of TDT_IGNORE_STRINGS above. fall through */ - case TGT_INVALID: - case TGT_CTXT_HANDLE: - case TGT_CTXT_HANDLE_POINTER: - /* checking after parsing should mean that we don't get here. if we do, - * it's a checker bug */ - assert(0); - } - return FALSE; -} - unsigned char get_struct_fc(const type_t *type) { int has_pointer = 0; @@ -340,15 +305,15 @@ unsigned char get_struct_fc(const type_t *type) case TGT_IFACE_POINTER: return RPC_FC_BOGUS_STRUCT; case TGT_BASIC: + if (type_basic_get_type(t) == TYPE_BASIC_INT3264 && pointer_size != 4) + return RPC_FC_BOGUS_STRUCT; break; case TGT_ENUM: if (get_enum_fc(t) == RPC_FC_ENUM16) return RPC_FC_BOGUS_STRUCT; break; - case TGT_ARRAY: - if(type_contains_iface(type_array_get_element(t))) - return RPC_FC_BOGUS_STRUCT; case TGT_POINTER: + case TGT_ARRAY: if (get_pointer_fc(t, field->attrs, FALSE) == RPC_FC_RP || pointer_size != 4) return RPC_FC_BOGUS_STRUCT; has_pointer = 1; @@ -397,6 +362,8 @@ unsigned char get_struct_fc(const type_t *type) } break; } + case TGT_RANGE: + return RPC_FC_BOGUS_STRUCT; case TGT_STRING: /* shouldn't get here because of TDT_IGNORE_STRINGS above. fall through */ case TGT_INVALID: @@ -460,6 +427,11 @@ unsigned char get_array_fc(const type_t *type) case TGT_USER_TYPE: fc = RPC_FC_BOGUS_ARRAY; break; + case TGT_BASIC: + if (type_basic_get_type(elem_type) == TYPE_BASIC_INT3264 && + pointer_size != 4) + fc = RPC_FC_BOGUS_ARRAY; + break; case TGT_STRUCT: switch (get_struct_fc(elem_type)) { @@ -485,7 +457,9 @@ unsigned char get_array_fc(const type_t *type) if (get_pointer_fc(elem_type, NULL, FALSE) == RPC_FC_RP || pointer_size != 4) fc = RPC_FC_BOGUS_ARRAY; break; - case TGT_BASIC: + case TGT_RANGE: + fc = RPC_FC_BOGUS_ARRAY; + break; case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: case TGT_STRING: @@ -559,6 +533,7 @@ static int type_has_pointers(const type_t *type) case TGT_IFACE_POINTER: case TGT_BASIC: case TGT_ENUM: + case TGT_RANGE: case TGT_INVALID: break; } @@ -612,6 +587,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs, case TGT_IFACE_POINTER: case TGT_BASIC: case TGT_ENUM: + case TGT_RANGE: case TGT_INVALID: break; } @@ -1258,6 +1234,12 @@ unsigned int type_memsize(const type_t *t, unsigned int *align) size = 8; if (size > *align) *align = size; break; + case RPC_FC_INT3264: + case RPC_FC_UINT3264: + assert( pointer_size ); + size = pointer_size; + if (size > *align) *align = size; + break; default: error("type_memsize: Unknown type 0x%x\n", get_basic_fc(t)); size = 0; @@ -1315,10 +1297,11 @@ unsigned int type_memsize(const type_t *t, unsigned int *align) case TYPE_COCLASS: case TYPE_MODULE: case TYPE_FUNCTION: + case TYPE_BITFIELD: /* these types should not be encountered here due to language * restrictions (interface, void, coclass, module), logical * restrictions (alias - due to type_get_type call above) or - * checking restrictions (function). */ + * checking restrictions (function, bitfield). */ assert(0); } @@ -2737,6 +2720,33 @@ static unsigned int write_contexthandle_tfs(FILE *file, const type_t *type, return start_offset; } +static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs, + type_t *type, expr_list_t *range_list, + unsigned int *typeformat_offset) +{ + unsigned char fc; + unsigned int start_offset = *typeformat_offset; + const expr_t *range_min = LIST_ENTRY(list_head(range_list), const expr_t, entry); + const expr_t *range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry); + + if (type_get_type(type) == TYPE_BASIC) + fc = get_basic_fc(type); + else + fc = get_enum_fc(type); + + /* fc must fit in lower 4-bits of 8-bit field below */ + assert(fc <= 0xf); + + print_file(file, 0, "/* %u */\n", *typeformat_offset); + print_file(file, 2, "0x%x,\t/* FC_RANGE */\n", RPC_FC_RANGE); + print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); + print_file(file, 2, "NdrFcLong(0x%lx),\t/* %lu */\n", range_min->cval, range_min->cval); + print_file(file, 2, "NdrFcLong(0x%lx),\t/* %lu */\n", range_max->cval, range_max->cval); + *typeformat_offset += 10; + + return start_offset; +} + static unsigned int write_typeformatstring_var(FILE *file, int indent, const var_t *func, type_t *type, const var_t *var, int toplevel_param, @@ -2784,6 +2794,13 @@ static unsigned int write_typeformatstring_var(FILE *file, int indent, const var case TGT_BASIC: /* nothing to do */ return 0; + case TGT_RANGE: + { + expr_list_t *range_list = get_attrp(var->attrs, ATTR_RANGE); + if (!range_list) + range_list = get_aliaschain_attrp(type, ATTR_RANGE); + return write_range_tfs(file, var->attrs, type, range_list, typeformat_offset); + } case TGT_IFACE_POINTER: return write_ip_tfs(file, var->attrs, type, typeformat_offset); case TGT_POINTER: @@ -2888,6 +2905,14 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty case TGT_BASIC: /* nothing to do */ break; + case TGT_RANGE: + { + expr_list_t *range_list = get_attrp(attrs, ATTR_RANGE); + if (!range_list) + range_list = get_aliaschain_attrp(type, ATTR_RANGE); + write_range_tfs(file, attrs, type, range_list, tfsoff); + break; + } case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: case TGT_INVALID: @@ -2989,7 +3014,7 @@ static unsigned int get_required_buffer_size_type( const type_t *type, const char *name, const attr_list_t *attrs, int toplevel_param, unsigned int *alignment) { *alignment = 0; - switch (typegen_detect_type(type, NULL, TDT_IGNORE_STRINGS)) + switch (typegen_detect_type(type, NULL, TDT_IGNORE_STRINGS|TDT_IGNORE_RANGES)) { case TGT_USER_TYPE: { @@ -3025,6 +3050,12 @@ static unsigned int get_required_buffer_size_type( *alignment = 8; return 8; + case RPC_FC_INT3264: + case RPC_FC_UINT3264: + assert( pointer_size ); + *alignment = pointer_size; + return pointer_size; + case RPC_FC_IGNORE: case RPC_FC_BIND_PRIMITIVE: return 0; @@ -3064,6 +3095,7 @@ static unsigned int get_required_buffer_size_type( { case TGT_BASIC: case TGT_ENUM: + case TGT_RANGE: return get_required_buffer_size_type( ref, name, NULL, FALSE, alignment ); case TGT_STRUCT: if (get_struct_fc(ref) == RPC_FC_STRUCT) @@ -3191,28 +3223,36 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, type_t *type = var->type; unsigned int size; unsigned int alignment = 0; - const type_t *ref; /* no work to do for other phases, buffer sizing is done elsewhere */ if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL) return; - ref = is_ptr(type) ? type_pointer_get_ref(type) : type; - if (type_get_type(ref) == TYPE_ENUM) + if (type_get_type(type) == TYPE_ENUM || + (type_get_type(type) == TYPE_BASIC && + type_basic_get_type(type) == TYPE_BASIC_INT3264 && + pointer_size != 4)) { - if (get_enum_fc(ref) == RPC_FC_ENUM32) - { - size = 4; - alignment = 4; - } - else /* RPC_FC_ENUM16 */ - { - size = 2; - alignment = 2; - } + unsigned char fc; + + if (type_get_type(type) == TYPE_ENUM) + fc = get_enum_fc(type); + else + fc = get_basic_fc(type); + + if (phase == PHASE_MARSHAL) + print_file(file, indent, "NdrSimpleTypeMarshall(\n"); + else + print_file(file, indent, "NdrSimpleTypeUnmarshall(\n"); + print_file(file, indent+1, "&__frame->_StubMsg,\n"); + print_file(file, indent+1, "(unsigned char *)&%s%s,\n", + local_var_prefix, + var->name); + print_file(file, indent+1, "0x%02x /* %s */);\n", fc, string_of_type(fc)); } else { + const type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type; switch (get_basic_fc(ref)) { case RPC_FC_BYTE: @@ -3234,6 +3274,9 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, case RPC_FC_LONG: case RPC_FC_FLOAT: case RPC_FC_ERROR_STATUS_T: + /* pointer_size must be 4 if we got here in these two cases */ + case RPC_FC_INT3264: + case RPC_FC_UINT3264: size = 4; alignment = 4; break; @@ -3254,46 +3297,46 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, var->name, get_basic_fc(ref)); size = 0; } - } - if (phase == PHASE_MARSHAL) - print_file(file, indent, "MIDL_memset(__frame->_StubMsg.Buffer, 0, (0x%x - (ULONG_PTR)__frame->_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1); - print_file(file, indent, "__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + %u) & ~0x%x);\n", - alignment - 1, alignment - 1); + if (phase == PHASE_MARSHAL) + print_file(file, indent, "MIDL_memset(__frame->_StubMsg.Buffer, 0, (0x%x - (ULONG_PTR)__frame->_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1); + print_file(file, indent, "__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + %u) & ~0x%x);\n", + alignment - 1, alignment - 1); - if (phase == PHASE_MARSHAL) - { - print_file(file, indent, "*("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); - if (is_ptr(type)) - fprintf(file, " *)__frame->_StubMsg.Buffer = *"); - else - fprintf(file, " *)__frame->_StubMsg.Buffer = "); - fprintf(file, "%s%s", local_var_prefix, varname); - fprintf(file, ";\n"); - } - else if (phase == PHASE_UNMARSHAL) - { - print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); - fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n"); - print_file(file, indent, "{\n"); - print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); - print_file(file, indent, "}\n"); - print_file(file, indent, "%s%s%s", - (pass == PASS_IN || pass == PASS_RETURN) ? "" : "*", - local_var_prefix, varname); - if (pass == PASS_IN && is_ptr(type)) - fprintf(file, " = ("); - else - fprintf(file, " = *("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); - fprintf(file, " *)__frame->_StubMsg.Buffer;\n"); - } + if (phase == PHASE_MARSHAL) + { + print_file(file, indent, "*("); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + if (is_ptr(type)) + fprintf(file, " *)__frame->_StubMsg.Buffer = *"); + else + fprintf(file, " *)__frame->_StubMsg.Buffer = "); + fprintf(file, "%s%s", local_var_prefix, varname); + fprintf(file, ";\n"); + } + else if (phase == PHASE_UNMARSHAL) + { + print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof("); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n"); + print_file(file, indent, "{\n"); + print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); + print_file(file, indent, "}\n"); + print_file(file, indent, "%s%s%s", + (pass == PASS_IN || pass == PASS_RETURN) ? "" : "*", + local_var_prefix, varname); + if (pass == PASS_IN && is_ptr(type)) + fprintf(file, " = ("); + else + fprintf(file, " = *("); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + fprintf(file, " *)__frame->_StubMsg.Buffer;\n"); + } - print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); - fprintf(file, ");\n"); + print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof("); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + fprintf(file, ");\n"); + } } /* returns whether the MaxCount, Offset or ActualCount members need to be @@ -3546,21 +3589,33 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const break; } case TGT_BASIC: - if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) - print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); + print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); break; case TGT_ENUM: - if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) + print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); + break; + case TGT_RANGE: + print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); + /* Note: this goes beyond what MIDL does - it only supports arguments + * with the [range] attribute in Oicf mode */ + if (phase == PHASE_UNMARSHAL) { - if (phase == PHASE_MARSHAL) - print_file(file, indent, "NdrSimpleTypeMarshall(\n"); - else - print_file(file, indent, "NdrSimpleTypeUnmarshall(\n"); - print_file(file, indent+1, "&__frame->_StubMsg,\n"); - print_file(file, indent+1, "(unsigned char *)&%s%s,\n", - local_var_prefix, - var->name); - print_file(file, indent+1, "0x%02x /* %s */);\n", get_enum_fc(type), string_of_type(get_enum_fc(type))); + const expr_t *range_min; + const expr_t *range_max; + expr_list_t *range_list = get_attrp(var->attrs, ATTR_RANGE); + if (!range_list) + range_list = get_aliaschain_attrp(type, ATTR_RANGE); + range_min = LIST_ENTRY(list_head(range_list), const expr_t, entry); + range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry); + + print_file(file, indent, "if ((%s%s < (", local_var_prefix, var->name); + write_type_decl(file, var->type, NULL); + fprintf(file, ")0x%lx) || (%s%s > (", range_min->cval, local_var_prefix, var->name); + write_type_decl(file, var->type, NULL); + fprintf(file, ")0x%lx))\n", range_max->cval); + print_file(file, indent, "{\n"); + print_file(file, indent+1, "RpcRaiseException(RPC_S_INVALID_BOUND);\n"); + print_file(file, indent, "}\n"); } break; case TGT_STRUCT: @@ -3603,23 +3658,19 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const case TGT_POINTER: { const type_t *ref = type_pointer_get_ref(type); - if (pointer_type == RPC_FC_RP && !is_user_type(ref)) switch (type_get_type(ref)) + if (pointer_type == RPC_FC_RP) switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES)) { - case TYPE_BASIC: - /* base types have known sizes, so don't need a sizing pass - * and don't have any memory to free and so don't need a - * freeing pass */ - if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) - print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); + case TGT_BASIC: + print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); break; - case TYPE_ENUM: + case TGT_ENUM: /* base types have known sizes, so don't need a sizing pass * and don't have any memory to free and so don't need a * freeing pass */ if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL) print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset); break; - case TYPE_STRUCT: + case TGT_STRUCT: { const char *struct_type = NULL; switch (get_struct_fc(ref)) @@ -3665,8 +3716,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const } break; } - case TYPE_UNION: - case TYPE_ENCAPSULATED_UNION: + case TGT_UNION: { const char *union_type = NULL; if (phase == PHASE_FREE) @@ -3685,16 +3735,17 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const phase, var, start_offset); break; } - case TYPE_POINTER: - case TYPE_ARRAY: + case TGT_STRING: + case TGT_POINTER: + case TGT_ARRAY: + case TGT_RANGE: + case TGT_IFACE_POINTER: + case TGT_USER_TYPE: + case TGT_CTXT_HANDLE: + case TGT_CTXT_HANDLE_POINTER: print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset); break; - case TYPE_VOID: - case TYPE_ALIAS: - case TYPE_MODULE: - case TYPE_COCLASS: - case TYPE_FUNCTION: - case TYPE_INTERFACE: + case TGT_INVALID: assert(0); break; } @@ -3918,6 +3969,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char case TGT_BASIC: case TGT_ENUM: case TGT_POINTER: + case TGT_RANGE: print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i); break; case TGT_STRUCT: diff --git a/reactos/tools/widl/typegen.h b/reactos/tools/widl/typegen.h index 8c8ba11da64..2b2e65dacfc 100644 --- a/reactos/tools/widl/typegen.h +++ b/reactos/tools/widl/typegen.h @@ -40,6 +40,7 @@ enum typegen_detect_flags { TDT_ALL_TYPES = 1 << 0, TDT_IGNORE_STRINGS = 1 << 1, + TDT_IGNORE_RANGES = 1 << 2, }; enum typegen_type @@ -56,6 +57,7 @@ enum typegen_type TGT_ENUM, TGT_STRUCT, TGT_UNION, + TGT_RANGE, }; typedef int (*type_pred_t)(const type_t *); diff --git a/reactos/tools/widl/typelib.c b/reactos/tools/widl/typelib.c index a27202f7173..ce099c8d0f2 100644 --- a/reactos/tools/widl/typelib.c +++ b/reactos/tools/widl/typelib.c @@ -180,6 +180,21 @@ unsigned short get_type_vt(type_t *t) return VT_UI8; else return VT_I8; + case TYPE_BASIC_INT3264: + if (typelib_kind == SYS_WIN64) + { + if (type_basic_get_sign(t) > 0) + return VT_UI8; + else + return VT_I8; + } + else + { + if (type_basic_get_sign(t) > 0) + return VT_UI4; + else + return VT_I4; + } case TYPE_BASIC_FLOAT: return VT_R4; case TYPE_BASIC_DOUBLE: @@ -228,6 +243,10 @@ unsigned short get_type_vt(type_t *t) case TYPE_FUNCTION: error("get_type_vt: functions not supported\n"); break; + + case TYPE_BITFIELD: + error("get_type_vt: bitfields not supported\n"); + break; } return 0; } diff --git a/reactos/tools/widl/typelib.h b/reactos/tools/widl/typelib.h index 58bad43f2e3..18e6cdbcc56 100644 --- a/reactos/tools/widl/typelib.h +++ b/reactos/tools/widl/typelib.h @@ -61,6 +61,8 @@ enum VARENUM { VT_LPSTR = 30, VT_LPWSTR = 31, VT_RECORD = 36, + VT_INT_PTR = 37, + VT_UINT_PTR = 38, VT_FILETIME = 64, VT_BLOB = 65, VT_STREAM = 66, @@ -70,6 +72,7 @@ enum VARENUM { VT_BLOB_OBJECT = 70, VT_CF = 71, VT_CLSID = 72, + VT_VERSIONED_STREAM = 73, VT_BSTR_BLOB = 0xfff, VT_VECTOR = 0x1000, VT_ARRAY = 0x2000, diff --git a/reactos/tools/widl/typetree.c b/reactos/tools/widl/typetree.c index 4359d924ba0..a60e757a958 100644 --- a/reactos/tools/widl/typetree.c +++ b/reactos/tools/widl/typetree.c @@ -63,9 +63,63 @@ type_t *make_type(enum type_type type) return t; } +static const var_t *find_arg(const var_list_t *args, const char *name) +{ + const var_t *arg; + + if (args) LIST_FOR_EACH_ENTRY(arg, args, const var_t, entry) + { + if (arg->name && !strcmp(name, arg->name)) + return arg; + } + + return NULL; +} + type_t *type_new_function(var_list_t *args) { - type_t *t = make_type(TYPE_FUNCTION); + var_t *arg; + type_t *t; + unsigned int i = 0; + + if (args) + { + arg = LIST_ENTRY(list_head(args), var_t, entry); + if (list_count(args) == 1 && !arg->name && arg->type && type_get_type(arg->type) == TYPE_VOID) + { + list_remove(&arg->entry); + free(arg); + free(args); + args = NULL; + } + } + if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry) + { + if (arg->type && type_get_type(arg->type) == TYPE_VOID) + error_loc("argument '%s' has void type\n", arg->name); + if (!arg->name) + { + if (i > 26 * 26) + error_loc("too many unnamed arguments\n"); + else + { + int unique; + do + { + char name[3]; + name[0] = i > 26 ? 'a' + i / 26 : 'a' + i; + name[1] = i > 26 ? 'a' + i % 26 : 0; + name[2] = 0; + unique = !find_arg(args, name); + if (unique) + arg->name = xstrdup(name); + i++; + } while (!unique); + } + } + } + + t = make_type(TYPE_FUNCTION); t->details.function = xmalloc(sizeof(*t->details.function)); t->details.function->args = args; t->details.function->idx = -1; @@ -248,6 +302,56 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio return t; } +static int is_valid_bitfield_type(const type_t *type) +{ + switch (type_get_type(type)) + { + case TYPE_ENUM: + return TRUE; + case TYPE_BASIC: + switch (type_basic_get_type(type)) + { + case TYPE_BASIC_INT8: + case TYPE_BASIC_INT16: + case TYPE_BASIC_INT32: + case TYPE_BASIC_INT64: + case TYPE_BASIC_INT: + case TYPE_BASIC_INT3264: + case TYPE_BASIC_CHAR: + case TYPE_BASIC_HYPER: + case TYPE_BASIC_BYTE: + case TYPE_BASIC_WCHAR: + case TYPE_BASIC_ERROR_STATUS_T: + return TRUE; + case TYPE_BASIC_FLOAT: + case TYPE_BASIC_DOUBLE: + case TYPE_BASIC_HANDLE: + return FALSE; + } + return FALSE; + default: + return FALSE; + } +} + +type_t *type_new_bitfield(type_t *field, const expr_t *bits) +{ + type_t *t; + + if (!is_valid_bitfield_type(field)) + error_loc("bit-field has invalid type\n"); + + if (bits->cval < 0) + error_loc("negative width for bit-field\n"); + + /* FIXME: validate bits->cval <= memsize(field) * 8 */ + + t = make_type(TYPE_BITFIELD); + t->details.bitfield.field = field; + t->details.bitfield.bits = bits; + return t; +} + static int compute_method_indexes(type_t *iface) { int idx; diff --git a/reactos/tools/widl/typetree.h b/reactos/tools/widl/typetree.h index fb0401b87a6..591406b67b6 100644 --- a/reactos/tools/widl/typetree.h +++ b/reactos/tools/widl/typetree.h @@ -39,6 +39,7 @@ type_t *type_new_enum(const char *name, int defined, var_list_t *enums); type_t *type_new_struct(char *name, int defined, var_list_t *fields); type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields); type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases); +type_t *type_new_bitfield(type_t *field_type, const expr_t *bits); void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts); void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods); void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface); @@ -190,6 +191,7 @@ static inline int type_is_complete(const type_t *type) case TYPE_COCLASS: case TYPE_POINTER: case TYPE_ARRAY: + case TYPE_BITFIELD: return TRUE; } return FALSE; @@ -283,4 +285,18 @@ static inline unsigned char type_pointer_get_default_fc(const type_t *type) return type->details.pointer.def_fc; } +static inline type_t *type_bitfield_get_field(const type_t *type) +{ + type = type_get_real_type(type); + assert(type_get_type(type) == TYPE_BITFIELD); + return type->details.bitfield.field; +} + +static inline const expr_t *type_bitfield_get_bits(const type_t *type) +{ + type = type_get_real_type(type); + assert(type_get_type(type) == TYPE_BITFIELD); + return type->details.bitfield.bits; +} + #endif /* WIDL_TYPE_TREE_H */ diff --git a/reactos/tools/widl/widltypes.h b/reactos/tools/widl/widltypes.h index 2f1e9f7b346..f0afce4e6a5 100644 --- a/reactos/tools/widl/widltypes.h +++ b/reactos/tools/widl/widltypes.h @@ -81,6 +81,7 @@ typedef struct list statement_list_t; enum attr_type { ATTR_AGGREGATABLE, + ATTR_ANNOTATION, ATTR_APPOBJECT, ATTR_ASYNC, ATTR_AUTO_HANDLE, @@ -238,6 +239,7 @@ enum type_basic_type TYPE_BASIC_INT32, TYPE_BASIC_INT64, TYPE_BASIC_INT, + TYPE_BASIC_INT3264, TYPE_BASIC_CHAR, TYPE_BASIC_HYPER, TYPE_BASIC_BYTE, @@ -350,6 +352,12 @@ struct pointer_details unsigned char def_fc; }; +struct bitfield_details +{ + struct _type_t *field; + const expr_t *bits; +}; + enum type_type { TYPE_VOID, @@ -365,6 +373,7 @@ enum type_type TYPE_INTERFACE, TYPE_POINTER, TYPE_ARRAY, + TYPE_BITFIELD, }; struct _type_t { @@ -382,6 +391,7 @@ struct _type_t { struct coclass_details coclass; struct basic_details basic; struct pointer_details pointer; + struct bitfield_details bitfield; } details; type_t *orig; /* dup'd types */ unsigned int typestring_offset; @@ -415,6 +425,7 @@ struct _declarator_t { type_t *type; type_t *func_type; array_dims_t *array; + expr_t *bits; /* parser-internal */ struct list entry; From d1aeb20e331f6f95caa69d5878cfbb52db586b75 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 24 Nov 2009 22:56:43 +0000 Subject: [PATCH 091/140] [ntoskrnl/cm] - CmpSelectLeaf fixes: looking into an incorrect cell, returning wrong cell, slightly simplify code and add more comments for clarity. Thanks to Michael Martin for spotting these bugs. svn path=/trunk/; revision=44285 --- reactos/ntoskrnl/config/cmindex.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/reactos/ntoskrnl/config/cmindex.c b/reactos/ntoskrnl/config/cmindex.c index e48977523b7..162263d7590 100644 --- a/reactos/ntoskrnl/config/cmindex.c +++ b/reactos/ntoskrnl/config/cmindex.c @@ -1344,6 +1344,8 @@ CmpSelectLeaf(IN PHHIVE Hive, *RootCell = &IndexKey->List[SubKeyIndex]; return LeafCell; } + + /* It didn't fit, so proceed to splitting */ } else { @@ -1380,22 +1382,22 @@ CmpSelectLeaf(IN PHHIVE Hive, /* Check if it's above */ if (Result >= 0) { - /* Get the first cell in the index */ - LeafCell = IndexKey->List[0]; + /* Get the cell in the index */ + LeafCell = IndexKey->List[SubKeyIndex]; LeafKey = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell); /* Return an error in case of problems */ if (!LeafKey) return HCELL_NIL; - /* Check if it fits into this leaf and break */ + /* Check if it fits into this leaf */ if (LeafKey->Count < CmpMaxIndexPerHblock) { /* Fill in the result and return the cell */ - *RootCell = &IndexKey->List[SubKeyIndex + 1]; + *RootCell = &IndexKey->List[SubKeyIndex]; return LeafCell; } - /* No, it doesn't fit, check the other leaf */ + /* No, it doesn't fit, check the next adjacent leaf */ if (SubKeyIndex < (IndexKey->Count - 1)) { /* Yes, there is space */ @@ -1413,6 +1415,8 @@ CmpSelectLeaf(IN PHHIVE Hive, return LeafCell; } } + + /* It didn't fit, so proceed to splitting */ } else { @@ -1429,11 +1433,8 @@ CmpSelectLeaf(IN PHHIVE Hive, /* Check if it fits and break */ if (LeafKey->Count < CmpMaxIndexPerHblock) { - /* Decrement the subkey index */ - SubKeyIndex--; - /* Fill in the result and return the cell */ - *RootCell = &IndexKey->List[SubKeyIndex]; + *RootCell = &IndexKey->List[SubKeyIndex - 1]; return LeafCell; } } From 3384debaf5046348847060d83761d41391d31981 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 25 Nov 2009 18:08:43 +0000 Subject: [PATCH 092/140] - Initialize SocketError to 0 to prevent a bogus error from GCC svn path=/trunk/; revision=44286 --- reactos/lib/drivers/ip/transport/tcp/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 8c051677353..fe571126379 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -47,7 +47,7 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) NTSTATUS Status; PIRP Irp; PMDL Mdl; - ULONG SocketError; + ULONG SocketError = 0; TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", Connection, Connection->SocketContext)); From f41f8181563308db0259be4d40fb580138c169c4 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Wed, 25 Nov 2009 19:36:10 +0000 Subject: [PATCH 093/140] [rpcrt4] - Revert rpcrt4 back to 1.1.31-partial. Fixes various RPC related regressions. svn path=/trunk/; revision=44287 --- reactos/dll/win32/rpcrt4/cproxy.c | 203 +- reactos/dll/win32/rpcrt4/cpsf.c | 68 +- reactos/dll/win32/rpcrt4/cpsf.h | 33 +- reactos/dll/win32/rpcrt4/cstub.c | 206 +- reactos/dll/win32/rpcrt4/epm_towers.h | 2 +- reactos/dll/win32/rpcrt4/ndr_contexthandle.c | 4 +- reactos/dll/win32/rpcrt4/ndr_misc.h | 2 +- reactos/dll/win32/rpcrt4/ndr_ole.c | 24 - reactos/dll/win32/rpcrt4/ndr_stubless.c | 353 +-- reactos/dll/win32/rpcrt4/ndr_stubless.h | 3 +- reactos/dll/win32/rpcrt4/rpc_assoc.c | 6 +- reactos/dll/win32/rpcrt4/rpc_assoc.h | 3 +- reactos/dll/win32/rpcrt4/rpc_async.c | 16 +- reactos/dll/win32/rpcrt4/rpc_binding.c | 42 +- reactos/dll/win32/rpcrt4/rpc_binding.h | 4 - reactos/dll/win32/rpcrt4/rpc_defs.h | 28 +- reactos/dll/win32/rpcrt4/rpc_epmap.c | 60 +- reactos/dll/win32/rpcrt4/rpc_message.c | 390 +--- reactos/dll/win32/rpcrt4/rpc_message.h | 22 +- reactos/dll/win32/rpcrt4/rpc_server.c | 141 +- reactos/dll/win32/rpcrt4/rpc_server.h | 4 +- reactos/dll/win32/rpcrt4/rpc_transport.c | 2085 ++++-------------- reactos/dll/win32/rpcrt4/rpcrt4.rbuild | 1 - reactos/dll/win32/rpcrt4/rpcrt4.spec | 5 +- reactos/dll/win32/rpcrt4/rpcrt4_main.c | 157 +- 25 files changed, 900 insertions(+), 2962 deletions(-) diff --git a/reactos/dll/win32/rpcrt4/cproxy.c b/reactos/dll/win32/rpcrt4/cproxy.c index 9ce555f7146..6c26d181978 100644 --- a/reactos/dll/win32/rpcrt4/cproxy.c +++ b/reactos/dll/win32/rpcrt4/cproxy.c @@ -2,7 +2,6 @@ * COM proxy implementation * * Copyright 2001 Ove KĂĄven, TransGaming Technologies - * Copyright 2009 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,9 +20,6 @@ * TODO: Handle non-i386 architectures */ -#include "config.h" -#include "wine/port.h" - #include #define COBJMACROS @@ -41,19 +37,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); +struct StublessThunk; + /* I don't know what MS's std proxy structure looks like, so this probably doesn't match, but that shouldn't matter */ typedef struct { const IRpcProxyBufferVtbl *lpVtbl; LPVOID *PVtbl; LONG RefCount; + const MIDL_STUBLESS_PROXY_INFO *stubless; const IID* piid; LPUNKNOWN pUnkOuter; - IUnknown *base_object; /* must be at offset 0x10 from PVtbl */ - IRpcProxyBuffer *base_proxy; PCInterfaceName name; LPPSFACTORYBUFFER pPSFactory; LPRPCCHANNELBUFFER pChannel; + struct StublessThunk *thunks; } StdProxyImpl; static const IRpcProxyBufferVtbl StdProxy_Vtbl; @@ -64,111 +62,66 @@ static const IRpcProxyBufferVtbl StdProxy_Vtbl; #include "pshpack1.h" -struct thunk { +struct StublessThunk { BYTE push; DWORD index; - BYTE jmp; + BYTE call; LONG handler; + BYTE ret; + WORD bytes; + BYTE pad[3]; }; #include "poppack.h" -extern void call_stubless_func(void); -__ASM_GLOBAL_FUNC(call_stubless_func, - "pushl %esp\n\t" /* pointer to index */ - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - "call " __ASM_NAME("ObjectStubless") __ASM_STDCALL(4) "\n\t" - "popl %edx\n\t" /* args size */ - __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t") - "movl (%esp),%ecx\n\t" /* return address */ - "addl %edx,%esp\n\t" - "jmp *%ecx" ); +/* adjust the stack size since we don't use Windows's method */ +#define STACK_ADJUST sizeof(DWORD) -HRESULT WINAPI ObjectStubless(DWORD *args) +#define FILL_STUBLESS(x,idx,stk) \ + x->push = 0x68; /* pushl [immediate] */ \ + x->index = (idx); \ + x->call = 0xe8; /* call [near] */ \ + x->handler = (char*)ObjectStubless - (char*)&x->ret; \ + x->ret = 0xc2; /* ret [immediate] */ \ + x->bytes = stk; \ + x->pad[0] = 0x8d; /* leal (%esi),%esi */ \ + x->pad[1] = 0x76; \ + x->pad[2] = 0x00; + +static HRESULT WINAPI ObjectStubless(DWORD index) { - DWORD index = args[0]; - void **iface = (void **)args[2]; - const void **vtbl = (const void **)*iface; - const MIDL_STUBLESS_PROXY_INFO *stubless = *(const MIDL_STUBLESS_PROXY_INFO **)(vtbl - 2); - const PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[index]; + char *args = (char*)(&index + 2); + LPVOID iface = *(LPVOID*)args; - /* store bytes to remove from stack */ - args[0] = *(const WORD*)(fs + 8); - TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, args[0], args[1]); + ICOM_THIS_MULTI(StdProxyImpl,PVtbl,iface); - return NdrClientCall2(stubless->pStubDesc, fs, args + 2); -} + PFORMAT_STRING fs = This->stubless->ProcFormatString + This->stubless->FormatStringOffset[index]; + unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; + TRACE("(%p)->(%d)([%d bytes]) ret=%08x\n", iface, index, bytes, *(DWORD*)(args+bytes)); -#define BLOCK_SIZE 1024 -#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */ - -static const struct thunk *method_blocks[MAX_BLOCKS]; - -static const struct thunk *allocate_block( unsigned int num ) -{ - unsigned int i; - struct thunk *prev, *block; - - block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block), - MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); - if (!block) return NULL; - - for (i = 0; i < BLOCK_SIZE; i++) - { - block[i].push = 0x68; /* pushl */ - block[i].index = BLOCK_SIZE * num + i + 3; - block[i].jmp = 0xe9; /* jmp */ - block[i].handler = (char *)call_stubless_func - (char *)(&block[i].handler + 1); - } - VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL ); - prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL ); - if (prev) /* someone beat us to it */ - { - VirtualFree( block, 0, MEM_RELEASE ); - block = prev; - } - return block; -} - -static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num ) -{ - const void **entry = (const void **)(vtbl + 1); - DWORD i, j; - - if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) - { - FIXME( "%u methods not supported\n", num ); - return FALSE; - } - for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) - { - const struct thunk *block = method_blocks[i]; - if (!block && !(block = allocate_block( i ))) return FALSE; - for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++) - if (*entry == (LPVOID)-1) *entry = &block[j]; - } - return TRUE; + return NdrClientCall2(This->stubless->pStubDesc, fs, args); } #else /* __i386__ */ -static BOOL fill_stubless_table( IUnknownVtbl *vtbl, DWORD num ) -{ - ERR("stubless proxies are not supported on this architecture\n"); - return FALSE; -} +/* can't do that on this arch */ +struct StublessThunk { int dummy; }; +#define FILL_STUBLESS(x,idx,stk) \ + ERR("stubless proxies are not supported on this architecture\n"); +#define STACK_ADJUST 0 #endif /* __i386__ */ -HRESULT StdProxy_Construct(REFIID riid, - LPUNKNOWN pUnkOuter, - const ProxyFileInfo *ProxyInfo, - int Index, - LPPSFACTORYBUFFER pPSFactory, - LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppvObj) +HRESULT WINAPI StdProxy_Construct(REFIID riid, + LPUNKNOWN pUnkOuter, + const ProxyFileInfo *ProxyInfo, + int Index, + LPPSFACTORYBUFFER pPSFactory, + LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppvObj) { StdProxyImpl *This; + const MIDL_STUBLESS_PROXY_INFO *stubless = NULL; PCInterfaceName name = ProxyInfo->pNamesArray[Index]; CInterfaceProxyVtbl *vtbl = ProxyInfo->pProxyVtblList[Index]; @@ -176,12 +129,14 @@ HRESULT StdProxy_Construct(REFIID riid, /* TableVersion = 2 means it is the stubless version of CInterfaceProxyVtbl */ if (ProxyInfo->TableVersion > 1) { - ULONG count = ProxyInfo->pStubVtblList[Index]->header.DispatchTableCount; + stubless = *(const void **)vtbl; vtbl = (CInterfaceProxyVtbl *)((const void **)vtbl + 1); - TRACE("stubless vtbl %p: count=%d\n", vtbl->Vtbl, count ); - fill_stubless_table( (IUnknownVtbl *)vtbl->Vtbl, count ); + TRACE("stubless=%p\n", stubless); } + TRACE("iid=%s\n", debugstr_guid(vtbl->header.piid)); + TRACE("vtbl=%p\n", vtbl->Vtbl); + if (!IsEqualGUID(vtbl->header.piid, riid)) { ERR("IID mismatch during proxy creation\n"); return RPC_E_UNEXPECTED; @@ -190,37 +145,51 @@ HRESULT StdProxy_Construct(REFIID riid, This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(StdProxyImpl)); if (!This) return E_OUTOFMEMORY; - if (!pUnkOuter) pUnkOuter = (IUnknown *)This; + if (stubless) { + CInterfaceStubVtbl *svtbl = ProxyInfo->pStubVtblList[Index]; + unsigned long i, count = svtbl->header.DispatchTableCount; + /* Maybe the original vtbl is just modified directly to point at + * ObjectStublessClientXXX thunks in real Windows, but I don't like it + */ + TRACE("stubless thunks: count=%ld\n", count); + This->thunks = HeapAlloc(GetProcessHeap(),0,sizeof(struct StublessThunk)*count); + This->PVtbl = HeapAlloc(GetProcessHeap(),0,sizeof(LPVOID)*count); + for (i=0; ithunks[i]; + if (vtbl->Vtbl[i] == (LPVOID)-1) { + PFORMAT_STRING fs = stubless->ProcFormatString + stubless->FormatStringOffset[i]; + unsigned bytes = *(const WORD*)(fs+8) - STACK_ADJUST; + TRACE("method %ld: stacksize=%d\n", i, bytes); + FILL_STUBLESS(thunk, i, bytes) + This->PVtbl[i] = thunk; + } + else { + memset(thunk, 0, sizeof(struct StublessThunk)); + This->PVtbl[i] = vtbl->Vtbl[i]; + } + } + } + else + This->PVtbl = vtbl->Vtbl; + This->lpVtbl = &StdProxy_Vtbl; - This->PVtbl = vtbl->Vtbl; /* one reference for the proxy */ This->RefCount = 1; + This->stubless = stubless; This->piid = vtbl->header.piid; - This->base_object = NULL; - This->base_proxy = NULL; This->pUnkOuter = pUnkOuter; This->name = name; This->pPSFactory = pPSFactory; This->pChannel = NULL; - - if(ProxyInfo->pDelegatedIIDs && ProxyInfo->pDelegatedIIDs[Index]) - { - HRESULT r = create_proxy( ProxyInfo->pDelegatedIIDs[Index], NULL, - &This->base_proxy, (void **)&This->base_object ); - if (FAILED(r)) - { - HeapFree( GetProcessHeap(), 0, This ); - return r; - } - } - *ppProxy = (LPRPCPROXYBUFFER)&This->lpVtbl; *ppvObj = &This->PVtbl; - IUnknown_AddRef((IUnknown *)*ppvObj); + /* if there is no outer unknown then the caller will control the lifetime + * of the proxy object through the proxy buffer, so no need to increment the + * ref count of the proxy object */ + if (pUnkOuter) + IUnknown_AddRef((IUnknown *)*ppvObj); IPSFactoryBuffer_AddRef(pPSFactory); - TRACE( "iid=%s this %p proxy %p obj %p vtbl %p base proxy %p base obj %p\n", - debugstr_guid(riid), This, *ppProxy, *ppvObj, This->PVtbl, This->base_proxy, This->base_object ); return S_OK; } @@ -231,10 +200,11 @@ static void StdProxy_Destruct(LPRPCPROXYBUFFER iface) if (This->pChannel) IRpcProxyBuffer_Disconnect(iface); - if (This->base_object) IUnknown_Release( This->base_object ); - if (This->base_proxy) IRpcProxyBuffer_Release( This->base_proxy ); - IPSFactoryBuffer_Release(This->pPSFactory); + if (This->thunks) { + HeapFree(GetProcessHeap(),0,This->PVtbl); + HeapFree(GetProcessHeap(),0,This->thunks); + } HeapFree(GetProcessHeap(),0,This); } @@ -289,7 +259,6 @@ static HRESULT WINAPI StdProxy_Connect(LPRPCPROXYBUFFER iface, This->pChannel = pChannel; IRpcChannelBuffer_AddRef(pChannel); - if (This->base_proxy) IRpcProxyBuffer_Connect( This->base_proxy, pChannel ); return S_OK; } @@ -298,8 +267,6 @@ static VOID WINAPI StdProxy_Disconnect(LPRPCPROXYBUFFER iface) ICOM_THIS_MULTI(StdProxyImpl,lpVtbl,iface); TRACE("(%p)->Disconnect()\n",This); - if (This->base_proxy) IRpcProxyBuffer_Disconnect( This->base_proxy ); - IRpcChannelBuffer_Release(This->pChannel); This->pChannel = NULL; } diff --git a/reactos/dll/win32/rpcrt4/cpsf.c b/reactos/dll/win32/rpcrt4/cpsf.c index ac1eccf56fa..bece899d964 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.c +++ b/reactos/dll/win32/rpcrt4/cpsf.c @@ -145,41 +145,6 @@ static const IPSFactoryBufferVtbl CStdPSFactory_Vtbl = CStdPSFactory_CreateStub }; - -static void init_psfactory( CStdPSFactoryBuffer *psfac, const ProxyFileInfo **file_list ) -{ - DWORD i, j, k; - - psfac->lpVtbl = &CStdPSFactory_Vtbl; - psfac->RefCount = 0; - psfac->pProxyFileList = file_list; - for (i = 0; file_list[i]; i++) - { - const PCInterfaceProxyVtblList *proxies = file_list[i]->pProxyVtblList; - const PCInterfaceStubVtblList *stubs = file_list[i]->pStubVtblList; - - for (j = 0; j < file_list[i]->TableSize; j++) - { - /* FIXME: i think that different vtables should be copied for - * async interfaces */ - void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; - void **pRpcStubVtbl = (void **)&stubs[j]->Vtbl; - - if (file_list[i]->pDelegatedIIDs && file_list[i]->pDelegatedIIDs[j]) - { - void **vtbl = proxies[j]->Vtbl; - if (file_list[i]->TableVersion > 1) vtbl++; - fill_delegated_proxy_table( (IUnknownVtbl *)vtbl, stubs[j]->header.DispatchTableCount ); - pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; - } - - for (k = 0; k < sizeof(IRpcStubBufferVtbl)/sizeof(void *); k++) - if (!pRpcStubVtbl[k]) pRpcStubVtbl[k] = pSrcRpcStubVtbl[k]; - } - } -} - - /*********************************************************************** * NdrDllGetClassObject [RPCRT4.@] */ @@ -193,8 +158,35 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, pPSFactoryBuffer); *ppv = NULL; - if (!pPSFactoryBuffer->lpVtbl) init_psfactory( pPSFactoryBuffer, pProxyFileList ); + if (!pPSFactoryBuffer->lpVtbl) { + const ProxyFileInfo **pProxyFileList2; + DWORD max_delegating_vtbl_size = 0; + pPSFactoryBuffer->lpVtbl = &CStdPSFactory_Vtbl; + pPSFactoryBuffer->RefCount = 0; + pPSFactoryBuffer->pProxyFileList = pProxyFileList; + for (pProxyFileList2 = pProxyFileList; *pProxyFileList2; pProxyFileList2++) { + int i; + for (i = 0; i < (*pProxyFileList2)->TableSize; i++) { + /* FIXME: i think that different vtables should be copied for + * async interfaces */ + void * const *pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Vtbl; + void **pRpcStubVtbl = (void **)&(*pProxyFileList2)->pStubVtblList[i]->Vtbl; + unsigned int j; + if ((*pProxyFileList2)->pDelegatedIIDs && (*pProxyFileList2)->pDelegatedIIDs[i]) { + pSrcRpcStubVtbl = (void * const *)&CStdStubBuffer_Delegating_Vtbl; + if ((*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount > max_delegating_vtbl_size) + max_delegating_vtbl_size = (*pProxyFileList2)->pStubVtblList[i]->header.DispatchTableCount; + } + + for (j = 0; j < sizeof(IRpcStubBufferVtbl)/sizeof(void *); j++) + if (!pRpcStubVtbl[j]) + pRpcStubVtbl[j] = pSrcRpcStubVtbl[j]; + } + } + if(max_delegating_vtbl_size > 0) + create_delegating_vtbl(max_delegating_vtbl_size); + } if (pclsid && IsEqualGUID(rclsid, pclsid)) return IPSFactoryBuffer_QueryInterface((LPPSFACTORYBUFFER)pPSFactoryBuffer, iid, ppv); else { @@ -215,7 +207,7 @@ HRESULT WINAPI NdrDllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv, */ HRESULT WINAPI NdrDllCanUnloadNow(CStdPSFactoryBuffer *pPSFactoryBuffer) { - return pPSFactoryBuffer->RefCount != 0 ? S_FALSE : S_OK; + return !(pPSFactoryBuffer->RefCount); } @@ -274,7 +266,7 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll, if (len && len < sizeof(module)) { TRACE("registering CLSID %s => %s\n", debugstr_w(clsid), debugstr_w(module)); if (RegCreateKeyW(HKEY_CLASSES_ROOT, keyname, &key) == ERROR_SUCCESS) { - RegSetValueExW(key, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW)); + RegSetValueExW(subkey, NULL, 0, REG_SZ, (const BYTE *)psfactoryW, sizeof(psfactoryW)); if (RegCreateKeyW(key, inprocserverW, &subkey) == ERROR_SUCCESS) { RegSetValueExW(subkey, NULL, 0, REG_SZ, (LPBYTE)module, (strlenW(module)+1)*sizeof(WCHAR)); RegSetValueExW(subkey, threadingmodelW, 0, REG_SZ, (const BYTE *)bothW, sizeof(bothW)); diff --git a/reactos/dll/win32/rpcrt4/cpsf.h b/reactos/dll/win32/rpcrt4/cpsf.h index 9cc046ff7ca..d8867d40e60 100644 --- a/reactos/dll/win32/rpcrt4/cpsf.h +++ b/reactos/dll/win32/rpcrt4/cpsf.h @@ -21,25 +21,36 @@ #ifndef __WINE_CPSF_H #define __WINE_CPSF_H -HRESULT StdProxy_Construct(REFIID riid, LPUNKNOWN pUnkOuter, const ProxyFileInfo *ProxyInfo, - int Index, LPPSFACTORYBUFFER pPSFactory, LPRPCPROXYBUFFER *ppProxy, - LPVOID *ppvObj); +HRESULT WINAPI StdProxy_Construct(REFIID riid, + LPUNKNOWN pUnkOuter, + const ProxyFileInfo *ProxyInfo, + int Index, + LPPSFACTORYBUFFER pPSFactory, + LPRPCPROXYBUFFER *ppProxy, + LPVOID *ppvObj); -HRESULT CStdStubBuffer_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name, - CInterfaceStubVtbl *vtbl, LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub); +HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub); -HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, LPUNKNOWN pUnkServer, PCInterfaceName name, - CInterfaceStubVtbl *vtbl, REFIID delegating_iid, - LPPSFACTORYBUFFER pPSFactory, LPRPCSTUBBUFFER *ppStub); +HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + REFIID delegating_iid, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub); const MIDL_SERVER_INFO *CStdStubBuffer_GetServerInfo(IRpcStubBuffer *iface); const IRpcStubBufferVtbl CStdStubBuffer_Vtbl; const IRpcStubBufferVtbl CStdStubBuffer_Delegating_Vtbl; -BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num); -HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv); +void create_delegating_vtbl(DWORD num_methods); + HRESULT create_stub(REFIID iid, IUnknown *pUnk, IRpcStubBuffer **ppstub); #endif /* __WINE_CPSF_H */ diff --git a/reactos/dll/win32/rpcrt4/cstub.c b/reactos/dll/win32/rpcrt4/cstub.c index 95ac1d89af2..85411cd81e9 100644 --- a/reactos/dll/win32/rpcrt4/cstub.c +++ b/reactos/dll/win32/rpcrt4/cstub.c @@ -2,7 +2,6 @@ * COM stub (CStdStubBuffer) implementation * * Copyright 2001 Ove KĂĄven, TransGaming Technologies - * Copyright 2009 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -62,12 +61,12 @@ static inline cstdstubbuffer_delegating_t *impl_from_delegating( IRpcStubBuffer return (cstdstubbuffer_delegating_t*)((char *)iface - FIELD_OFFSET(cstdstubbuffer_delegating_t, stub_buffer)); } -HRESULT CStdStubBuffer_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub) +HRESULT WINAPI CStdStubBuffer_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub) { CStdStubBuffer *This; IUnknown *pvServer; @@ -114,16 +113,20 @@ typedef struct { DWORD ref; DWORD size; + void **methods; IUnknownVtbl vtbl; /* remaining entries in vtbl */ } ref_counted_vtbl; -static ref_counted_vtbl *current_vtbl; +static struct +{ + ref_counted_vtbl *table; +} current_vtbl; static HRESULT WINAPI delegating_QueryInterface(IUnknown *pUnk, REFIID iid, void **ppv) { - *ppv = pUnk; + *ppv = (void *)pUnk; return S_OK; } @@ -158,137 +161,87 @@ typedef struct { } vtbl_method_t; #include "poppack.h" -#define BLOCK_SIZE 1024 -#define MAX_BLOCKS 64 /* 64k methods should be enough for anybody */ - -static const vtbl_method_t *method_blocks[MAX_BLOCKS]; - -static const vtbl_method_t *allocate_block( unsigned int num ) +static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num) { - unsigned int i; - vtbl_method_t *prev, *block; + vtbl_method_t *method; + void **entry; + DWORD i; - block = VirtualAlloc( NULL, BLOCK_SIZE * sizeof(*block), - MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); - if (!block) return NULL; - - for (i = 0; i < BLOCK_SIZE; i++) - { - block[i].mov1 = 0x0424448b; - block[i].mov2 = 0x408b; - block[i].sixteen = 0x10; - block[i].mov3 = 0x04244489; - block[i].mov4 = 0x008b; - block[i].mov5 = 0x808b; - block[i].offset = (BLOCK_SIZE * num + i + 3) << 2; - block[i].jmp = 0xe0ff; - block[i].pad[0] = 0x8d; - block[i].pad[1] = 0x76; - block[i].pad[2] = 0x00; - } - VirtualProtect( block, BLOCK_SIZE * sizeof(*block), PAGE_EXECUTE_READ, NULL ); - prev = InterlockedCompareExchangePointer( (void **)&method_blocks[num], block, NULL ); - if (prev) /* someone beat us to it */ - { - VirtualFree( block, 0, MEM_RELEASE ); - block = prev; - } - return block; -} - -static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num) -{ - const void **entry = (const void **)(vtbl + 1); - DWORD i, j; - - if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) - { - FIXME( "%u methods not supported\n", num ); - return FALSE; - } vtbl->QueryInterface = delegating_QueryInterface; vtbl->AddRef = delegating_AddRef; vtbl->Release = delegating_Release; - for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) - { - const vtbl_method_t *block = method_blocks[i]; - if (!block && !(block = allocate_block( i ))) return FALSE; - for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++) *entry++ = &block[j]; - } - return TRUE; -} -BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) -{ - const void **entry = (const void **)(vtbl + 1); - DWORD i, j; + method = (vtbl_method_t*)methods; + entry = (void**)(vtbl + 1); - if (num - 3 > BLOCK_SIZE * MAX_BLOCKS) + for(i = 3; i < num; i++) { - FIXME( "%u methods not supported\n", num ); - return FALSE; + *entry = method; + method->mov1 = 0x0424448b; + method->mov2 = 0x408b; + method->sixteen = 0x10; + method->mov3 = 0x04244489; + method->mov4 = 0x008b; + method->mov5 = 0x808b; + method->offset = i << 2; + method->jmp = 0xe0ff; + method->pad[0] = 0x8d; + method->pad[1] = 0x76; + method->pad[2] = 0x00; + + method++; + entry++; } - vtbl->QueryInterface = IUnknown_QueryInterface_Proxy; - vtbl->AddRef = IUnknown_AddRef_Proxy; - vtbl->Release = IUnknown_Release_Proxy; - for (i = 0; i < (num - 3 + BLOCK_SIZE - 1) / BLOCK_SIZE; i++) - { - const vtbl_method_t *block = method_blocks[i]; - if (!block && !(block = allocate_block( i ))) return FALSE; - for (j = 0; j < BLOCK_SIZE && j < num - 3 - i * BLOCK_SIZE; j++, entry++) - if (!*entry) *entry = &block[j]; - } - return TRUE; } #else /* __i386__ */ -static BOOL fill_delegated_stub_table(IUnknownVtbl *vtbl, DWORD num) +typedef struct {int dummy;} vtbl_method_t; +static void fill_table(IUnknownVtbl *vtbl, void **methods, DWORD num) { ERR("delegated stubs are not supported on this architecture\n"); - return FALSE; -} - -BOOL fill_delegated_proxy_table(IUnknownVtbl *vtbl, DWORD num) -{ - ERR("delegated proxies are not supported on this architecture\n"); - return FALSE; } #endif /* __i386__ */ -static IUnknownVtbl *get_delegating_vtbl(DWORD num_methods) +void create_delegating_vtbl(DWORD num_methods) +{ + TRACE("%d\n", num_methods); + if(num_methods <= 3) + { + ERR("should have more than %d methods\n", num_methods); + return; + } + + EnterCriticalSection(&delegating_vtbl_section); + if(!current_vtbl.table || num_methods > current_vtbl.table->size) + { + DWORD size; + DWORD old_protect; + if(current_vtbl.table && current_vtbl.table->ref == 0) + { + TRACE("freeing old table\n"); + VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE); + HeapFree(GetProcessHeap(), 0, current_vtbl.table); + } + size = (num_methods - 3) * sizeof(vtbl_method_t); + current_vtbl.table = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); + current_vtbl.table->ref = 0; + current_vtbl.table->size = num_methods; + current_vtbl.table->methods = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + fill_table(¤t_vtbl.table->vtbl, current_vtbl.table->methods, num_methods); + VirtualProtect(current_vtbl.table->methods, size, PAGE_EXECUTE_READ, &old_protect); + } + LeaveCriticalSection(&delegating_vtbl_section); +} + +static IUnknownVtbl *get_delegating_vtbl(void) { IUnknownVtbl *ret; - if (num_methods < 256) num_methods = 256; /* avoid frequent reallocations */ - EnterCriticalSection(&delegating_vtbl_section); - - if(!current_vtbl || num_methods > current_vtbl->size) - { - ref_counted_vtbl *table = HeapAlloc(GetProcessHeap(), 0, - FIELD_OFFSET(ref_counted_vtbl, vtbl) + num_methods * sizeof(void*)); - if (!table) - { - LeaveCriticalSection(&delegating_vtbl_section); - return NULL; - } - - table->ref = 0; - table->size = num_methods; - fill_delegated_stub_table(&table->vtbl, num_methods); - - if (current_vtbl && current_vtbl->ref == 0) - { - TRACE("freeing old table\n"); - HeapFree(GetProcessHeap(), 0, current_vtbl); - } - current_vtbl = table; - } - - current_vtbl->ref++; - ret = ¤t_vtbl->vtbl; + current_vtbl.table->ref++; + ret = ¤t_vtbl.table->vtbl; LeaveCriticalSection(&delegating_vtbl_section); return ret; } @@ -300,21 +253,22 @@ static void release_delegating_vtbl(IUnknownVtbl *vtbl) EnterCriticalSection(&delegating_vtbl_section); table->ref--; TRACE("ref now %d\n", table->ref); - if(table->ref == 0 && table != current_vtbl) + if(table->ref == 0 && table != current_vtbl.table) { TRACE("... and we're not current so free'ing\n"); + VirtualFree(current_vtbl.table->methods, 0, MEM_RELEASE); HeapFree(GetProcessHeap(), 0, table); } LeaveCriticalSection(&delegating_vtbl_section); } -HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, - LPUNKNOWN pUnkServer, - PCInterfaceName name, - CInterfaceStubVtbl *vtbl, - REFIID delegating_iid, - LPPSFACTORYBUFFER pPSFactory, - LPRPCSTUBBUFFER *ppStub) +HRESULT WINAPI CStdStubBuffer_Delegating_Construct(REFIID riid, + LPUNKNOWN pUnkServer, + PCInterfaceName name, + CInterfaceStubVtbl *vtbl, + REFIID delegating_iid, + LPPSFACTORYBUFFER pPSFactory, + LPRPCSTUBBUFFER *ppStub) { cstdstubbuffer_delegating_t *This; IUnknown *pvServer; @@ -340,7 +294,7 @@ HRESULT CStdStubBuffer_Delegating_Construct(REFIID riid, return E_OUTOFMEMORY; } - This->base_obj = get_delegating_vtbl( vtbl->header.DispatchTableCount ); + This->base_obj = get_delegating_vtbl(); r = create_stub(delegating_iid, (IUnknown*)&This->base_obj, &This->base_stub); if(FAILED(r)) { diff --git a/reactos/dll/win32/rpcrt4/epm_towers.h b/reactos/dll/win32/rpcrt4/epm_towers.h index 3eec37aa228..1afd3eb3376 100644 --- a/reactos/dll/win32/rpcrt4/epm_towers.h +++ b/reactos/dll/win32/rpcrt4/epm_towers.h @@ -19,7 +19,7 @@ * */ -#include "epm.h" +#include "epm_c.h" #define EPM_PROTOCOL_DNET_NSP 0x04 #define EPM_PROTOCOL_OSI_TP4 0x05 diff --git a/reactos/dll/win32/rpcrt4/ndr_contexthandle.c b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c index cab0fc5d86e..15192a72878 100644 --- a/reactos/dll/win32/rpcrt4/ndr_contexthandle.c +++ b/reactos/dll/win32/rpcrt4/ndr_contexthandle.c @@ -59,7 +59,7 @@ static CRITICAL_SECTION ndr_context_cs = { &ndr_context_debug, -1, 0, 0, 0, 0 }; static struct context_handle_entry *get_context_entry(NDR_CCONTEXT CContext) { - struct context_handle_entry *che = CContext; + struct context_handle_entry *che = (struct context_handle_entry*) CContext; if (che->magic != NDR_CONTEXT_HANDLE_MAGIC) return NULL; @@ -111,7 +111,7 @@ void WINAPI NDRCContextMarshall(NDR_CCONTEXT CContext, void *pBuff) } else { - ndr_context_handle *wire_data = pBuff; + ndr_context_handle *wire_data = (ndr_context_handle *)pBuff; wire_data->attributes = 0; wire_data->uuid = GUID_NULL; } diff --git a/reactos/dll/win32/rpcrt4/ndr_misc.h b/reactos/dll/win32/rpcrt4/ndr_misc.h index b0150c3a2eb..c3beff4d725 100644 --- a/reactos/dll/win32/rpcrt4/ndr_misc.h +++ b/reactos/dll/win32/rpcrt4/ndr_misc.h @@ -62,6 +62,6 @@ extern const NDR_BUFFERSIZE NdrBufferSizer[]; extern const NDR_MEMORYSIZE NdrMemorySizer[]; extern const NDR_FREE NdrFreer[]; -ULONG ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat); +unsigned long ComplexStructSize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat); #endif /* __WINE_NDR_MISC_H */ diff --git a/reactos/dll/win32/rpcrt4/ndr_ole.c b/reactos/dll/win32/rpcrt4/ndr_ole.c index a4c23c2c5c2..a3264e70122 100644 --- a/reactos/dll/win32/rpcrt4/ndr_ole.c +++ b/reactos/dll/win32/rpcrt4/ndr_ole.c @@ -369,30 +369,6 @@ void WINAPI NdrOleFree(void *NodeToFree) COM_MemFree(NodeToFree); } -/*********************************************************************** - * Helper function to create a proxy. - * Probably similar to NdrpCreateProxy. - */ -HRESULT create_proxy(REFIID iid, IUnknown *pUnkOuter, IRpcProxyBuffer **pproxy, void **ppv) -{ - CLSID clsid; - IPSFactoryBuffer *psfac; - HRESULT r; - - if(!LoadCOM()) return E_FAIL; - - r = COM_GetPSClsid( iid, &clsid ); - if(FAILED(r)) return r; - - r = COM_GetClassObject( &clsid, CLSCTX_INPROC_SERVER, NULL, &IID_IPSFactoryBuffer, (void**)&psfac ); - if(FAILED(r)) return r; - - r = IPSFactoryBuffer_CreateProxy(psfac, pUnkOuter, iid, pproxy, ppv); - - IPSFactoryBuffer_Release(psfac); - return r; -} - /*********************************************************************** * Helper function to create a stub. * This probably looks very much like NdrpCreateStub. diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.c b/reactos/dll/win32/rpcrt4/ndr_stubless.c index 8cb5f2b5e45..645a0ca4729 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.c +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.c @@ -173,7 +173,7 @@ static PFORMAT_STRING client_get_handle( if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); + pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; *phBinding = pGenPair->pfnBind(pObject); @@ -256,7 +256,7 @@ static void client_free_handle( if (pDesc->flag_and_size & HANDLE_PARAM_IS_VIA_PTR) pArg = *(void **)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); else - pArg = ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); + pArg = (void *)ARG_FROM_OFFSET(pStubMsg->StackTop, pDesc->offset); memcpy(&pObject, pArg, pDesc->flag_and_size & 0xf); pGenPair = &pStubMsg->StubDesc->aGenericBindingRoutinePairs[pDesc->binding_routine_pair_index]; pGenPair->pfnUnbind(pObject, hBinding); @@ -867,14 +867,9 @@ __declspec(naked) LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigne LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned int stack_size); __ASM_GLOBAL_FUNC(call_server_func, "pushl %ebp\n\t" - __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") - __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") - "movl %esp,%ebp\n\t" - __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "movl %esp, %ebp\n\t" "pushl %edi\n\t" /* Save registers */ - __ASM_CFI(".cfi_rel_offset %edi,-4\n\t") "pushl %esi\n\t" - __ASM_CFI(".cfi_rel_offset %esi,-8\n\t") "movl 16(%ebp), %eax\n\t" /* Get stack size */ "subl %eax, %esp\n\t" /* Make room in stack for arguments */ "andl $~15, %esp\n\t" /* Make sure stack has 16-byte alignment for Mac OS X */ @@ -887,13 +882,9 @@ __ASM_GLOBAL_FUNC(call_server_func, "call *8(%ebp)\n\t" /* Call function */ "leal -8(%ebp), %esp\n\t" /* Restore stack */ "popl %esi\n\t" /* Restore registers */ - __ASM_CFI(".cfi_same_value %esi\n\t") "popl %edi\n\t" - __ASM_CFI(".cfi_same_value %edi\n\t") "popl %ebp\n\t" - __ASM_CFI(".cfi_def_cfa %esp,4\n\t") - __ASM_CFI(".cfi_same_value %ebp\n\t") - "ret" ) + "ret\n" ) #else #warning call_server_func not implemented for your architecture LONG_PTR __cdecl call_server_func(SERVER_ROUTINE func, unsigned char * args, unsigned short stack_size) @@ -1531,339 +1522,3 @@ void WINAPI NdrServerCall2(PRPC_MESSAGE pRpcMsg) DWORD dwPhase; NdrStubCall2(NULL, NULL, pRpcMsg, &dwPhase); } - -struct async_call_data -{ - MIDL_STUB_MESSAGE *pStubMsg; - const NDR_PROC_HEADER *pProcHeader; - PFORMAT_STRING pHandleFormat; - PFORMAT_STRING pParamFormat; - RPC_BINDING_HANDLE hBinding; - /* size of stack */ - unsigned short stack_size; - /* number of parameters. optional for client to give it to us */ - unsigned char number_of_params; - /* correlation cache */ - unsigned long NdrCorrCache[256]; -}; - -LONG_PTR WINAPIV NdrAsyncClientCall(PMIDL_STUB_DESC pStubDesc, - PFORMAT_STRING pFormat, ...) -{ - /* pointer to start of stack where arguments start */ - PRPC_MESSAGE pRpcMsg; - PMIDL_STUB_MESSAGE pStubMsg; - RPC_ASYNC_STATE *pAsync; - struct async_call_data *async_call_data; - /* procedure number */ - unsigned short procedure_number; - /* cache of Oif_flags from v2 procedure header */ - INTERPRETER_OPT_FLAGS Oif_flags = { 0 }; - /* cache of extension flags from NDR_PROC_HEADER_EXTS */ - INTERPRETER_OPT_FLAGS2 ext_flags = { 0 }; - /* the type of pass we are currently doing */ - int phase; - /* header for procedure string */ - const NDR_PROC_HEADER * pProcHeader = (const NDR_PROC_HEADER *)&pFormat[0]; - /* -Oif or -Oicf generated format */ - BOOL bV2Format = FALSE; - - TRACE("pStubDesc %p, pFormat %p, ...\n", pStubDesc, pFormat); - - /* Later NDR language versions probably won't be backwards compatible */ - if (pStubDesc->Version > 0x50002) - { - FIXME("Incompatible stub description version: 0x%x\n", pStubDesc->Version); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); - } - - async_call_data = I_RpcAllocate(sizeof(*async_call_data) + sizeof(MIDL_STUB_MESSAGE) + sizeof(RPC_MESSAGE)); - if (!async_call_data) RpcRaiseException(ERROR_OUTOFMEMORY); - async_call_data->number_of_params = ~0; - async_call_data->pProcHeader = pProcHeader; - - async_call_data->pStubMsg = pStubMsg = (PMIDL_STUB_MESSAGE)(async_call_data + 1); - pRpcMsg = (PRPC_MESSAGE)(pStubMsg + 1); - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - { - const NDR_PROC_HEADER_RPC *pProcHeader = (const NDR_PROC_HEADER_RPC *)&pFormat[0]; - async_call_data->stack_size = pProcHeader->stack_size; - procedure_number = pProcHeader->proc_num; - pFormat += sizeof(NDR_PROC_HEADER_RPC); - } - else - { - async_call_data->stack_size = pProcHeader->stack_size; - procedure_number = pProcHeader->proc_num; - pFormat += sizeof(NDR_PROC_HEADER); - } - TRACE("stack size: 0x%x\n", async_call_data->stack_size); - TRACE("proc num: %d\n", procedure_number); - - /* create the full pointer translation tables, if requested */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) - pStubMsg->FullPtrXlatTables = NdrFullPointerXlatInit(0,XLAT_CLIENT); - - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT) - { - ERR("objects not supported\n"); - I_RpcFree(async_call_data); - RpcRaiseException(RPC_X_BAD_STUB_DATA); - } - - NdrClientInitializeNew(pRpcMsg, pStubMsg, pStubDesc, procedure_number); - - TRACE("Oi_flags = 0x%02x\n", pProcHeader->Oi_flags); - TRACE("MIDL stub version = 0x%x\n", pStubDesc->MIDLVersion); - - /* needed for conformance of top-level objects */ -#ifdef __i386__ - pStubMsg->StackTop = I_RpcAllocate(async_call_data->stack_size); - /* FIXME: this may read one more DWORD than is necessary, but it shouldn't hurt */ - memcpy(pStubMsg->StackTop, *(unsigned char **)(&pFormat+1), async_call_data->stack_size); -#else -# warning Stack not retrieved for your CPU architecture -#endif - - pAsync = *(RPC_ASYNC_STATE **)pStubMsg->StackTop; - pAsync->StubInfo = async_call_data; - async_call_data->pHandleFormat = pFormat; - - pFormat = client_get_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, &async_call_data->hBinding); - if (!pFormat) return 0; - - bV2Format = (pStubDesc->Version >= 0x20000); - - if (bV2Format) - { - const NDR_PROC_PARTIAL_OIF_HEADER *pOIFHeader = - (const NDR_PROC_PARTIAL_OIF_HEADER *)pFormat; - - Oif_flags = pOIFHeader->Oi2Flags; - async_call_data->number_of_params = pOIFHeader->number_of_params; - - pFormat += sizeof(NDR_PROC_PARTIAL_OIF_HEADER); - } - - TRACE("Oif_flags = "); dump_INTERPRETER_OPT_FLAGS(Oif_flags); - - if (Oif_flags.HasExtensions) - { - const NDR_PROC_HEADER_EXTS *pExtensions = - (const NDR_PROC_HEADER_EXTS *)pFormat; - ext_flags = pExtensions->Flags2; - pFormat += pExtensions->Size; - } - - async_call_data->pParamFormat = pFormat; - - pStubMsg->BufferLength = 0; - - /* store the RPC flags away */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCFLAGS) - pRpcMsg->RpcFlags = ((const NDR_PROC_HEADER_RPC *)pProcHeader)->rpc_flags; - - /* use alternate memory allocation routines */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_RPCSSALLOC) - NdrRpcSmSetClientToOsf(pStubMsg); - - if (Oif_flags.HasPipes) - { - FIXME("pipes not supported yet\n"); - RpcRaiseException(RPC_X_WRONG_STUB_VERSION); /* FIXME: remove when implemented */ - /* init pipes package */ - /* NdrPipesInitialize(...) */ - } - if (ext_flags.HasNewCorrDesc) - { - /* initialize extra correlation package */ - NdrCorrelationInitialize(pStubMsg, async_call_data->NdrCorrCache, sizeof(async_call_data->NdrCorrCache), 0); - } - - /* order of phases: - * 1. PROXY_CALCSIZE - calculate the buffer size - * 2. PROXY_GETBUFFER - allocate the buffer - * 3. PROXY_MARHSAL - marshal [in] params into the buffer - * 4. PROXY_SENDRECEIVE - send buffer - * Then in NdrpCompleteAsyncClientCall: - * 1. PROXY_SENDRECEIVE - receive buffer - * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer - */ - for (phase = PROXY_CALCSIZE; phase <= PROXY_SENDRECEIVE; phase++) - { - RPC_STATUS status; - TRACE("phase = %d\n", phase); - switch (phase) - { - case PROXY_GETBUFFER: - /* allocate the buffer */ - if (Oif_flags.HasPipes) - /* NdrGetPipeBuffer(...) */ - FIXME("pipes not supported yet\n"); - else - { - if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) -#if 0 - NdrNsGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding); -#else - FIXME("using auto handle - call NdrNsGetBuffer when it gets implemented\n"); -#endif - else - NdrGetBuffer(pStubMsg, pStubMsg->BufferLength, async_call_data->hBinding); - } - pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; - status = I_RpcAsyncSetHandle(pRpcMsg, pAsync); - if (status != RPC_S_OK) - RpcRaiseException(status); - break; - case PROXY_SENDRECEIVE: - pRpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; - /* send the [in] params only */ - if (Oif_flags.HasPipes) - /* NdrPipesSend(...) */ - FIXME("pipes not supported yet\n"); - else - { - if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) -#if 0 - NdrNsSend(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle); -#else - FIXME("using auto handle - call NdrNsSend when it gets implemented\n"); -#endif - else - { - pStubMsg->RpcMsg->BufferLength = pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer; - status = I_RpcSend(pStubMsg->RpcMsg); - if (status != RPC_S_OK) - RpcRaiseException(status); - } - } - - break; - case PROXY_CALCSIZE: - case PROXY_MARSHAL: - if (bV2Format) - client_do_args(pStubMsg, pFormat, phase, pStubMsg->StackTop, - async_call_data->number_of_params, NULL); - else - client_do_args_old_format(pStubMsg, pFormat, phase, - pStubMsg->StackTop, async_call_data->stack_size, NULL, - (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_OBJECT), FALSE); - break; - default: - ERR("shouldn't reach here. phase %d\n", phase); - break; - } - } - - TRACE("returning 0\n"); - return 0; -} - -RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply) -{ - /* pointer to start of stack where arguments start */ - PMIDL_STUB_MESSAGE pStubMsg; - struct async_call_data *async_call_data; - /* the type of pass we are currently doing */ - int phase; - /* header for procedure string */ - const NDR_PROC_HEADER * pProcHeader; - /* -Oif or -Oicf generated format */ - BOOL bV2Format; - RPC_STATUS status = RPC_S_OK; - - if (!pAsync->StubInfo) - return RPC_S_INVALID_ASYNC_HANDLE; - - async_call_data = pAsync->StubInfo; - pStubMsg = async_call_data->pStubMsg; - pProcHeader = async_call_data->pProcHeader; - - bV2Format = (pStubMsg->StubDesc->Version >= 0x20000); - - /* order of phases: - * 1. PROXY_CALCSIZE - calculate the buffer size - * 2. PROXY_GETBUFFER - allocate the buffer - * 3. PROXY_MARHSAL - marshal [in] params into the buffer - * 4. PROXY_SENDRECEIVE - send buffer - * Then in NdrpCompleteAsyncClientCall: - * 1. PROXY_SENDRECEIVE - receive buffer - * 2. PROXY_UNMARHSAL - unmarshal [out] params from buffer - */ - for (phase = PROXY_SENDRECEIVE; phase <= PROXY_UNMARSHAL; phase++) - { - switch (phase) - { - case PROXY_SENDRECEIVE: - pStubMsg->RpcMsg->RpcFlags |= RPC_BUFFER_ASYNC; - /* receive the [out] params */ - if (pProcHeader->handle_type == RPC_FC_AUTO_HANDLE) -#if 0 - NdrNsReceive(&stubMsg, stubMsg.Buffer, pStubDesc->IMPLICIT_HANDLE_INFO.pAutoHandle); -#else - FIXME("using auto handle - call NdrNsReceive when it gets implemented\n"); -#endif - else - { - status = I_RpcReceive(pStubMsg->RpcMsg); - if (status != RPC_S_OK) - goto cleanup; - pStubMsg->BufferLength = pStubMsg->RpcMsg->BufferLength; - pStubMsg->BufferStart = pStubMsg->RpcMsg->Buffer; - pStubMsg->BufferEnd = pStubMsg->BufferStart + pStubMsg->BufferLength; - pStubMsg->Buffer = pStubMsg->BufferStart; - } - - /* convert strings, floating point values and endianess into our - * preferred format */ -#if 0 - if ((pStubMsg->RpcMsg.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION) - NdrConvert(pStubMsg, pFormat); -#endif - - break; - case PROXY_UNMARSHAL: - if (bV2Format) - client_do_args(pStubMsg, async_call_data->pParamFormat, phase, pStubMsg->StackTop, - async_call_data->number_of_params, Reply); - else - client_do_args_old_format(pStubMsg, async_call_data->pParamFormat, phase, - pStubMsg->StackTop, async_call_data->stack_size, Reply, FALSE, FALSE); - break; - default: - ERR("shouldn't reach here. phase %d\n", phase); - break; - } - } - -cleanup: - if (pStubMsg->fHasNewCorrDesc) - { - /* free extra correlation package */ - NdrCorrelationFree(pStubMsg); - } - - /* free the full pointer translation tables */ - if (pProcHeader->Oi_flags & RPC_FC_PROC_OIF_FULLPTR) - NdrFullPointerXlatFree(pStubMsg->FullPtrXlatTables); - - /* free marshalling buffer */ - NdrFreeBuffer(pStubMsg); - client_free_handle(pStubMsg, pProcHeader, async_call_data->pHandleFormat, async_call_data->hBinding); - - I_RpcFree(pStubMsg->StackTop); - I_RpcFree(async_call_data); - - TRACE("-- 0x%x\n", status); - return status; -} - -RPCRTAPI LONG RPC_ENTRY NdrAsyncStubCall(struct IRpcStubBuffer* pThis, - struct IRpcChannelBuffer* pChannel, PRPC_MESSAGE pRpcMsg, - DWORD * pdwStubPhase) -{ - FIXME("unimplemented, expect crash!\n"); - return 0; -} diff --git a/reactos/dll/win32/rpcrt4/ndr_stubless.h b/reactos/dll/win32/rpcrt4/ndr_stubless.h index 87f603b6065..9a6fb444783 100644 --- a/reactos/dll/win32/rpcrt4/ndr_stubless.h +++ b/reactos/dll/win32/rpcrt4/ndr_stubless.h @@ -85,7 +85,7 @@ typedef struct _NDR_PROC_HEADER_RPC * RPCF_Asynchronous = 0x4000 - [async] MIDL attribute * Reserved = 0x8000 */ - unsigned int rpc_flags; + unsigned long rpc_flags; unsigned short proc_num; unsigned short stack_size; @@ -240,4 +240,3 @@ void client_do_args_old_format(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING pFormat, int phase, unsigned char *args, unsigned short stack_size, unsigned char *pRetVal, BOOL object_proc, BOOL ignore_retval); -RPC_STATUS NdrpCompleteAsyncClientCall(RPC_ASYNC_STATE *pAsync, void *Reply); diff --git a/reactos/dll/win32/rpcrt4/rpc_assoc.c b/reactos/dll/win32/rpcrt4/rpc_assoc.c index 117301f42c0..32e951a929a 100644 --- a/reactos/dll/win32/rpcrt4/rpc_assoc.c +++ b/reactos/dll/win32/rpcrt4/rpc_assoc.c @@ -125,7 +125,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, - ULONG assoc_gid, + unsigned long assoc_gid, RpcAssoc **assoc_out) { RpcAssoc *assoc; @@ -223,7 +223,7 @@ static RPC_STATUS RpcAssoc_BindConnection(const RpcAssoc *assoc, RpcConnection * RPC_MESSAGE msg; RPC_STATUS status; unsigned char *auth_data = NULL; - ULONG auth_length; + unsigned long auth_length; TRACE("sending bind request to server\n"); @@ -394,7 +394,6 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, if (status != RPC_S_OK) return status; - NewConnection->assoc = assoc; status = RPCRT4_OpenClientConnection(NewConnection); if (status != RPC_S_OK) { @@ -417,7 +416,6 @@ RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection) { assert(!Connection->server); - Connection->async_state = NULL; EnterCriticalSection(&assoc->cs); if (!assoc->assoc_group_id) assoc->assoc_group_id = Connection->assoc_group_id; list_add_head(&assoc->free_connection_pool, &Connection->conn_pool_entry); diff --git a/reactos/dll/win32/rpcrt4/rpc_assoc.h b/reactos/dll/win32/rpcrt4/rpc_assoc.h index 70fb664e31d..1ce1f135638 100644 --- a/reactos/dll/win32/rpcrt4/rpc_assoc.h +++ b/reactos/dll/win32/rpcrt4/rpc_assoc.h @@ -34,7 +34,6 @@ typedef struct _RpcAssoc /* id of this association group */ ULONG assoc_group_id; - UUID http_uuid; CRITICAL_SECTION cs; @@ -50,7 +49,7 @@ RPC_STATUS RPCRT4_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endp RPC_STATUS RpcAssoc_GetClientConnection(RpcAssoc *assoc, const RPC_SYNTAX_IDENTIFIER *InterfaceId, const RPC_SYNTAX_IDENTIFIER *TransferSyntax, RpcAuthInfo *AuthInfo, RpcQualityOfService *QOS, RpcConnection **Connection); void RpcAssoc_ReleaseIdleConnection(RpcAssoc *assoc, RpcConnection *Connection); ULONG RpcAssoc_Release(RpcAssoc *assoc); -RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, ULONG assoc_gid, RpcAssoc **assoc_out); +RPC_STATUS RpcServerAssoc_GetAssociation(LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, unsigned long assoc_gid, RpcAssoc **assoc_out); RPC_STATUS RpcServerAssoc_AllocateContextHandle(RpcAssoc *assoc, void *CtxGuard, NDR_SCONTEXT *SContext); RPC_STATUS RpcServerAssoc_FindContextHandle(RpcAssoc *assoc, const UUID *uuid, void *CtxGuard, ULONG Flags, NDR_SCONTEXT *SContext); RPC_STATUS RpcServerAssoc_UpdateContextHandle(RpcAssoc *assoc, NDR_SCONTEXT SContext, void *CtxGuard, NDR_RUNDOWN rundown_routine); diff --git a/reactos/dll/win32/rpcrt4/rpc_async.c b/reactos/dll/win32/rpcrt4/rpc_async.c index 891fc5ad725..33fdc774304 100644 --- a/reactos/dll/win32/rpcrt4/rpc_async.c +++ b/reactos/dll/win32/rpcrt4/rpc_async.c @@ -29,17 +29,11 @@ #include "rpc_binding.h" #include "rpc_message.h" -#include "ndr_stubless.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); #define RPC_ASYNC_SIGNATURE 0x43595341 -static inline BOOL valid_async_handle(PRPC_ASYNC_STATE pAsync) -{ - return pAsync->Signature == RPC_ASYNC_SIGNATURE; -} - /*********************************************************************** * RpcAsyncInitializeHandle [RPCRT4.@] * @@ -110,14 +104,8 @@ RPC_STATUS WINAPI RpcAsyncGetCallStatus(PRPC_ASYNC_STATE pAsync) */ RPC_STATUS WINAPI RpcAsyncCompleteCall(PRPC_ASYNC_STATE pAsync, void *Reply) { - TRACE("(%p, %p)\n", pAsync, Reply); - - if (!valid_async_handle(pAsync)) - return RPC_S_INVALID_ASYNC_HANDLE; - - /* FIXME: check completed */ - - return NdrpCompleteAsyncClientCall(pAsync, Reply); + FIXME("(%p, %p): stub\n", pAsync, Reply); + return RPC_S_INVALID_ASYNC_HANDLE; } /*********************************************************************** diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.c b/reactos/dll/win32/rpcrt4/rpc_binding.c index 29e0709e54f..696887cb7b3 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.c +++ b/reactos/dll/win32/rpcrt4/rpc_binding.c @@ -661,11 +661,11 @@ RPC_STATUS WINAPI RpcStringBindingParseA( RPC_CSTR StringBinding, RPC_CSTR *ObjU return RPC_S_OK; fail: - if (ObjUuid) RpcStringFreeA(ObjUuid); - if (Protseq) RpcStringFreeA(Protseq); - if (NetworkAddr) RpcStringFreeA(NetworkAddr); - if (Endpoint) RpcStringFreeA(Endpoint); - if (Options) RpcStringFreeA(Options); + if (ObjUuid) RpcStringFreeA((unsigned char**)ObjUuid); + if (Protseq) RpcStringFreeA((unsigned char**)Protseq); + if (NetworkAddr) RpcStringFreeA((unsigned char**)NetworkAddr); + if (Endpoint) RpcStringFreeA((unsigned char**)Endpoint); + if (Options) RpcStringFreeA((unsigned char**)Options); return RPC_S_INVALID_STRING_BINDING; } @@ -796,7 +796,7 @@ RPC_STATUS WINAPI RpcBindingFree( RPC_BINDING_HANDLE* Binding ) RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) { RPC_STATUS status; - ULONG c; + unsigned long c; TRACE("(%p)\n", BindingVector); for (c=0; c<(*BindingVector)->Count; c++) { @@ -812,7 +812,7 @@ RPC_STATUS WINAPI RpcBindingVectorFree( RPC_BINDING_VECTOR** BindingVector ) */ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; TRACE("(%p,%p) = %s\n", Binding, ObjectUuid, debugstr_guid(&bind->ObjectUuid)); *ObjectUuid = bind->ObjectUuid; @@ -824,7 +824,7 @@ RPC_STATUS WINAPI RpcBindingInqObject( RPC_BINDING_HANDLE Binding, UUID* ObjectU */ RPC_STATUS WINAPI RpcBindingSetObject( RPC_BINDING_HANDLE Binding, UUID* ObjectUuid ) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; TRACE("(%p,%s)\n", Binding, debugstr_guid(ObjectUuid)); if (bind->server) return RPC_S_WRONG_KIND_OF_BINDING; @@ -856,11 +856,11 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingA( RPC_CSTR StringBinding, RPC_BIND if (ret == RPC_S_OK) ret = RPCRT4_CompleteBindingA(bind, (char*)NetworkAddr, (char*)Endpoint, (char*)Options); - RpcStringFreeA(&Options); - RpcStringFreeA(&Endpoint); - RpcStringFreeA(&NetworkAddr); - RpcStringFreeA(&Protseq); - RpcStringFreeA(&ObjectUuid); + RpcStringFreeA((unsigned char**)&Options); + RpcStringFreeA((unsigned char**)&Endpoint); + RpcStringFreeA((unsigned char**)&NetworkAddr); + RpcStringFreeA((unsigned char**)&Protseq); + RpcStringFreeA((unsigned char**)&ObjectUuid); if (ret == RPC_S_OK) *Binding = (RPC_BINDING_HANDLE)bind; @@ -915,7 +915,7 @@ RPC_STATUS WINAPI RpcBindingFromStringBindingW( RPC_WSTR StringBinding, RPC_BIND RPC_STATUS WINAPI RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding, RPC_CSTR *StringBinding ) { RPC_STATUS ret; - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; RPC_CSTR ObjectUuid; TRACE("(%p,%p)\n", Binding, StringBinding); @@ -946,7 +946,7 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, RPC_WS TRACE("(%p,%p)\n", Binding, StringBinding); ret = RpcBindingToStringBindingA(Binding, &str); *StringBinding = RPCRT4_strdupAtoW((char*)str); - RpcStringFreeA(&str); + RpcStringFreeA((unsigned char**)&str); return ret; } @@ -969,7 +969,7 @@ RPC_STATUS WINAPI I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding, unsi */ RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; TRACE( "(%p,%p): stub\n", Binding, BlockingFn ); @@ -986,7 +986,7 @@ RPC_STATUS RPC_ENTRY RpcBindingCopy( RPC_BINDING_HANDLE* DestinationBinding) { RpcBinding *DestBinding; - RpcBinding *SrcBinding = SourceBinding; + RpcBinding *SrcBinding = (RpcBinding*)SourceBinding; RPC_STATUS status; TRACE("(%p, %p)\n", SourceBinding, DestinationBinding); @@ -1501,7 +1501,7 @@ RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding, RPC_CSTR ServerPrincName, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, RPC_SECURITY_QOS *SecurityQos ) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; SECURITY_STATUS r; CredHandle cred; TimeStamp exp; @@ -1631,7 +1631,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr, RPC_SECURITY_QOS *SecurityQos ) { - RpcBinding* bind = Binding; + RpcBinding* bind = (RpcBinding*)Binding; SECURITY_STATUS r; CredHandle cred; TimeStamp exp; @@ -1640,7 +1640,7 @@ RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, PSecPkgInfoW packages; ULONG cbMaxToken; - TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w(ServerPrincName), + TRACE("%p %s %u %u %p %u %p\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, SecurityQos); if (SecurityQos) @@ -1772,7 +1772,7 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding, RPC_WSTR ServerPrincName, ULONG AuthnLevel, ULONG AuthnSvc, RPC_AUTH_IDENTITY_HANDLE AuthIdentity, ULONG AuthzSvr ) { - TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w(ServerPrincName), + TRACE("%p %s %u %u %p %u\n", Binding, debugstr_w((const WCHAR*)ServerPrincName), AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr); return RpcBindingSetAuthInfoExW(Binding, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvr, NULL); } diff --git a/reactos/dll/win32/rpcrt4/rpc_binding.h b/reactos/dll/win32/rpcrt4/rpc_binding.h index 036b59a5567..5aa83079d51 100644 --- a/reactos/dll/win32/rpcrt4/rpc_binding.h +++ b/reactos/dll/win32/rpcrt4/rpc_binding.h @@ -24,7 +24,6 @@ #include "rpcndr.h" #include "security.h" #include "wine/list.h" -#include "rpc_defs.h" typedef struct _RpcAuthInfo @@ -67,7 +66,6 @@ typedef struct _RpcConnection TimeStamp exp; ULONG attr; RpcAuthInfo *AuthInfo; - ULONG auth_context_id; ULONG encryption_auth_len; ULONG signature_auth_len; RpcQualityOfService *QOS; @@ -76,7 +74,6 @@ typedef struct _RpcConnection struct list conn_pool_entry; ULONG assoc_group_id; /* association group returned during binding */ RPC_ASYNC_STATE *async_state; - struct _RpcAssoc *assoc; /* association this connection is part of */ /* server-only */ /* The active interface bound to server. */ @@ -99,7 +96,6 @@ struct connection_ops { int (*wait_for_incoming_data)(RpcConnection *conn); size_t (*get_top_of_tower)(unsigned char *tower_data, const char *networkaddr, const char *endpoint); RPC_STATUS (*parse_top_of_tower)(const unsigned char *tower_data, size_t tower_size, char **networkaddr, char **endpoint); - RPC_STATUS (*receive_fragment)(RpcConnection *conn, RpcPktHdr **Header, void **Payload); }; /* don't know what MS's structure looks like */ diff --git a/reactos/dll/win32/rpcrt4/rpc_defs.h b/reactos/dll/win32/rpcrt4/rpc_defs.h index e70731a3818..cae77c4f356 100644 --- a/reactos/dll/win32/rpcrt4/rpc_defs.h +++ b/reactos/dll/win32/rpcrt4/rpc_defs.h @@ -31,13 +31,13 @@ typedef struct unsigned char drep[4]; /* Data representation */ unsigned short frag_len; /* Data size in bytes including header and tail. */ unsigned short auth_len; /* Authentication length */ - unsigned int call_id; /* Call identifier. */ + unsigned long call_id; /* Call identifier. */ } RpcPktCommonHdr; typedef struct { RpcPktCommonHdr common; - unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned short opnum; } RpcPktRequestHdr; @@ -45,7 +45,7 @@ typedef struct typedef struct { RpcPktCommonHdr common; - unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned char cancel_count; unsigned char reserved; @@ -54,12 +54,12 @@ typedef struct typedef struct { RpcPktCommonHdr common; - unsigned int alloc_hint; /* Data size in bytes excluding header and tail. */ + unsigned long alloc_hint; /* Data size in bytes excluding header and tail. */ unsigned short context_id; /* Presentation context identifier */ unsigned char cancel_count; /* Received cancel count */ unsigned char reserved; /* Force alignment! */ - unsigned int status; /* Runtime fault code (RPC_STATUS) */ - unsigned int reserved2; + unsigned long status; /* Runtime fault code (RPC_STATUS) */ + unsigned long reserved2; } RpcPktFaultHdr; typedef struct @@ -67,7 +67,7 @@ typedef struct RpcPktCommonHdr common; unsigned short max_tsize; /* Maximum transmission fragment size */ unsigned short max_rsize; /* Maximum receive fragment size */ - unsigned int assoc_gid; /* Associated group id */ + unsigned long assoc_gid; /* Associated group id */ unsigned char num_elements; /* Number of elements */ unsigned char padding[3]; /* Force alignment! */ unsigned short context_id; /* Presentation context identifier */ @@ -99,7 +99,7 @@ typedef struct RpcPktCommonHdr common; unsigned short max_tsize; /* Maximum transmission fragment size */ unsigned short max_rsize; /* Maximum receive fragment size */ - unsigned int assoc_gid; /* Associated group id */ + unsigned long assoc_gid; /* Associated group id */ /* * Following this header are these fields: * RpcAddressString server_address; @@ -120,14 +120,6 @@ typedef struct } protocols[1]; } RpcPktBindNAckHdr; -/* undocumented packet sent during RPC over HTTP */ -typedef struct -{ - RpcPktCommonHdr common; - unsigned short flags; - unsigned short num_data_items; -} RpcPktHttpHdr; - /* Union representing all possible packet headers */ typedef union { @@ -138,7 +130,6 @@ typedef union RpcPktBindHdr bind; RpcPktBindAckHdr bind_ack; RpcPktBindNAckHdr bind_nack; - RpcPktHttpHdr http; } RpcPktHdr; typedef struct @@ -147,7 +138,7 @@ typedef struct unsigned char auth_level; /* RPC_C_AUTHN_LEVEL* */ unsigned char auth_pad_length; /* length of padding to restore n % 4 alignment */ unsigned char auth_reserved; /* reserved, must be zero */ - unsigned int auth_context_id; /* unique value for the authenticated connection */ + unsigned long auth_context_id; /* unique value for the authenticated connection */ } RpcAuthVerifier; #define RPC_AUTH_VERIFIER_LEN(common_hdr) \ @@ -183,7 +174,6 @@ typedef struct #define PKT_SHUTDOWN 17 #define PKT_CO_CANCEL 18 #define PKT_ORPHANED 19 -#define PKT_HTTP 20 #define RESULT_ACCEPT 0 #define RESULT_USER_REJECTION 1 diff --git a/reactos/dll/win32/rpcrt4/rpc_epmap.c b/reactos/dll/win32/rpcrt4/rpc_epmap.c index 60c425550ad..286ffbf9973 100644 --- a/reactos/dll/win32/rpcrt4/rpc_epmap.c +++ b/reactos/dll/win32/rpcrt4/rpc_epmap.c @@ -32,7 +32,7 @@ #include "wine/exception.h" #include "rpc_binding.h" -#include "epm.h" +#include "epm_c.h" #include "epm_towers.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -116,7 +116,7 @@ static BOOL start_rpcss(void) static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle) { - RpcBinding *bind = handle; + RpcBinding *bind = (RpcBinding *)handle; const char *protseq = bind->Protseq; const char *network_addr = bind->NetworkAddr; @@ -127,7 +127,7 @@ static inline BOOL is_epm_destination_local(RPC_BINDING_HANDLE handle) static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_HANDLE *epm_handle) { - RpcBinding *bind = handle; + RpcBinding *bind = (RpcBinding *)handle; const char * pszEndpoint = NULL; RPC_STATUS status; RpcBinding* epm_bind; @@ -149,7 +149,7 @@ static RPC_STATUS get_epm_handle_client(RPC_BINDING_HANDLE handle, RPC_BINDING_H status = RpcBindingCopy(handle, epm_handle); if (status != RPC_S_OK) return status; - epm_bind = *epm_handle; + epm_bind = (RpcBinding*)*epm_handle; if (epm_bind->AuthInfo) { /* don't bother with authenticating against the EPM by default @@ -187,8 +187,8 @@ static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *__eptr) RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, UUID_VECTOR *UuidVector, RPC_CSTR Annotation ) { - PRPC_SERVER_INTERFACE If = IfSpec; - ULONG i; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + unsigned long i; RPC_STATUS status = RPC_S_OK; error_status_t status2; ept_entry_t *entries; @@ -197,13 +197,13 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind TRACE("(%p,%p,%p,%s)\n", IfSpec, BindingVector, UuidVector, debugstr_a((char*)Annotation)); TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); for (i=0; iCount; i++) { - RpcBinding* bind = BindingVector->BindingH[i]; - TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq)); - TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint)); + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); + TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq)); + TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint)); } if (UuidVector) { for (i=0; iCount; i++) - TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); + TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); } if (!BindingVector->Count) return RPC_S_OK; @@ -222,9 +222,10 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind for (i = 0; i < BindingVector->Count; i++) { unsigned j; - RpcBinding* bind = BindingVector->BindingH[i]; + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++) { + int len = strlen((char *)Annotation); status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, bind->Protseq, bind->Endpoint, bind->NetworkAddr, @@ -235,9 +236,7 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind memcpy(&entries[i * UuidVector->Count].object, &UuidVector->Uuid[j], sizeof(GUID)); else memset(&entries[i].object, 0, sizeof(entries[i].object)); - if (Annotation) - memcpy(entries[i].annotation, Annotation, - min(strlen((char *)Annotation) + 1, ept_max_annotation_size)); + memcpy(entries[i].annotation, Annotation, min(len + 1, ept_max_annotation_size)); } } @@ -281,29 +280,14 @@ RPC_STATUS WINAPI RpcEpRegisterA( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bind return status; } -/*********************************************************************** - * RpcEpRegisterW (RPCRT4.@) - */ -RPC_STATUS WINAPI RpcEpRegisterW( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, - UUID_VECTOR *UuidVector, RPC_WSTR Annotation ) -{ - LPSTR annA = RPCRT4_strdupWtoA(Annotation); - RPC_STATUS status; - - status = RpcEpRegisterA(IfSpec, BindingVector, UuidVector, (RPC_CSTR)annA); - - HeapFree(GetProcessHeap(), 0, annA); - return status; -} - /*********************************************************************** * RpcEpUnregister (RPCRT4.@) */ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, UUID_VECTOR *UuidVector ) { - PRPC_SERVER_INTERFACE If = IfSpec; - ULONG i; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; + unsigned long i; RPC_STATUS status = RPC_S_OK; error_status_t status2; ept_entry_t *entries; @@ -312,13 +296,13 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector); TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); for (i=0; iCount; i++) { - RpcBinding* bind = BindingVector->BindingH[i]; - TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq)); - TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint)); + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); + TRACE(" protseq[%ld]=%s\n", i, debugstr_a(bind->Protseq)); + TRACE(" endpoint[%ld]=%s\n", i, debugstr_a(bind->Endpoint)); } if (UuidVector) { for (i=0; iCount; i++) - TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); + TRACE(" obj[%ld]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); } entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1)); @@ -335,7 +319,7 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin for (i = 0; i < BindingVector->Count; i++) { unsigned j; - RpcBinding* bind = BindingVector->BindingH[i]; + RpcBinding* bind = (RpcBinding*)(BindingVector->BindingH[i]); for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++) { status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, @@ -388,8 +372,8 @@ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *Bin */ RPC_STATUS WINAPI RpcEpResolveBinding( RPC_BINDING_HANDLE Binding, RPC_IF_HANDLE IfSpec ) { - PRPC_CLIENT_INTERFACE If = IfSpec; - RpcBinding* bind = Binding; + PRPC_CLIENT_INTERFACE If = (PRPC_CLIENT_INTERFACE)IfSpec; + RpcBinding* bind = (RpcBinding*)Binding; RPC_STATUS status; error_status_t status2; handle_t handle; diff --git a/reactos/dll/win32/rpcrt4/rpc_message.c b/reactos/dll/win32/rpcrt4/rpc_message.c index 5e7c857acdd..e4f96a9179e 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.c +++ b/reactos/dll/win32/rpcrt4/rpc_message.c @@ -59,13 +59,13 @@ enum secure_packet_direction static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg); -DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) +static DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) { static const DWORD header_sizes[] = { sizeof(Header->request), 0, sizeof(Header->response), sizeof(Header->fault), 0, 0, 0, 0, 0, 0, 0, sizeof(Header->bind), sizeof(Header->bind_ack), sizeof(Header->bind_nack), - 0, 0, 0, 0, 0, 0, sizeof(Header->http) + 0, 0, 0, 0, 0 }; ULONG ret = 0; @@ -76,7 +76,7 @@ DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) if (Header->common.flags & RPC_FLG_OBJECT_UUID) ret += sizeof(UUID); } else { - WARN("invalid packet type %u\n", Header->common.ptype); + TRACE("invalid packet type\n"); } return ret; @@ -96,7 +96,7 @@ static int packet_has_auth_verifier(const RpcPktHdr *Header) } static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType, - ULONG DataRepresentation) + unsigned long DataRepresentation) { Header->common.rpc_ver = RPC_VER_MAJOR; Header->common.rpc_ver_minor = RPC_VER_MINOR; @@ -111,8 +111,8 @@ static VOID RPCRT4_BuildCommonHeader(RpcPktHdr *Header, unsigned char PacketType /* Flags and fragment length are computed in RPCRT4_Send. */ } -static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation, - ULONG BufferLength, +static RpcPktHdr *RPCRT4_BuildRequestHeader(unsigned long DataRepresentation, + unsigned long BufferLength, unsigned short ProcNum, UUID *ObjectUuid) { @@ -141,7 +141,8 @@ static RpcPktHdr *RPCRT4_BuildRequestHeader(ULONG DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength) +RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, + unsigned long BufferLength) { RpcPktHdr *header; @@ -157,7 +158,8 @@ RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLeng return header; } -RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status) +RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, + RPC_STATUS Status) { RpcPktHdr *header; @@ -173,10 +175,10 @@ RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status) return header; } -RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, - ULONG AssocGroupId, + unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId) { @@ -200,7 +202,7 @@ RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, return header; } -static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation) +static RpcPktHdr *RPCRT4_BuildAuthHeader(unsigned long DataRepresentation) { RpcPktHdr *header; @@ -216,7 +218,7 @@ static RpcPktHdr *RPCRT4_BuildAuthHeader(ULONG DataRepresentation) return header; } -RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor) { @@ -237,17 +239,17 @@ RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, +RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, - ULONG AssocGroupId, + unsigned long AssocGroupId, LPCSTR ServerAddress, - unsigned short Result, - unsigned short Reason, + unsigned long Result, + unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId) { RpcPktHdr *header; - ULONG header_size; + unsigned long header_size; RpcAddressString *server_address; RpcResults *results; RPC_SYNTAX_IDENTIFIER *transfer_id; @@ -281,118 +283,6 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, return header; } -RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation, - unsigned short flags, - unsigned short num_data_items, - unsigned int payload_size) -{ - RpcPktHdr *header; - - header = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(header->http) + payload_size); - if (header == NULL) { - ERR("failed to allocate memory\n"); - return NULL; - } - - RPCRT4_BuildCommonHeader(header, PKT_HTTP, DataRepresentation); - /* since the packet isn't current sent using RPCRT4_Send, set the flags - * manually here */ - header->common.flags = RPC_FLG_FIRST|RPC_FLG_LAST; - header->common.call_id = 0; - header->common.frag_len = sizeof(header->http) + payload_size; - header->http.flags = flags; - header->http.num_data_items = num_data_items; - - return header; -} - -#define WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, type, value) \ - do { \ - *(unsigned int *)(payload) = (type); \ - (payload) += 4; \ - *(unsigned int *)(payload) = (value); \ - (payload) += 4; \ - } while (0) - -#define WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, type, uuid) \ - do { \ - *(unsigned int *)(payload) = (type); \ - (payload) += 4; \ - *(UUID *)(payload) = (uuid); \ - (payload) += sizeof(UUID); \ - } while (0) - -#define WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, flow_control_increment, uuid) \ - do { \ - *(unsigned int *)(payload) = 0x00000001; \ - (payload) += 4; \ - *(unsigned int *)(payload) = (bytes_transmitted); \ - (payload) += 4; \ - *(unsigned int *)(payload) = (flow_control_increment); \ - (payload) += 4; \ - *(UUID *)(payload) = (uuid); \ - (payload) += sizeof(UUID); \ - } while (0) - -RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, - const UUID *connection_uuid, - const UUID *pipe_uuid, - const UUID *association_uuid) -{ - RpcPktHdr *header; - unsigned int size; - char *payload; - - size = 8 + 4 + sizeof(UUID) + 4 + sizeof(UUID) + 8; - if (!out_pipe) - size += 8 + 4 + sizeof(UUID); - - header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, flags, - out_pipe ? 4 : 6, size); - if (!header) return NULL; - payload = (char *)(&header->http+1); - - /* FIXME: what does this part of the payload do? */ - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000006, 0x00000001); - - WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *connection_uuid); - WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x00000003, *pipe_uuid); - - if (out_pipe) - /* FIXME: what does this part of the payload do? */ - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000000, 0x00010000); - else - { - /* FIXME: what does this part of the payload do? */ - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000004, 0x40000000); - /* FIXME: what does this part of the payload do? */ - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x00000005, 0x000493e0); - - WRITE_HTTP_PAYLOAD_FIELD_UUID(payload, 0x0000000c, *association_uuid); - } - - return header; -} - -RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, - ULONG flow_control_increment, - const UUID *pipe_uuid) -{ - RpcPktHdr *header; - char *payload; - - header = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x2, 2, - 5 * sizeof(ULONG) + sizeof(UUID)); - if (!header) return NULL; - payload = (char *)(&header->http+1); - - WRITE_HTTP_PAYLOAD_FIELD_UINT32(payload, 0x0000000d, (server ? 0x0 : 0x3)); - - WRITE_HTTP_PAYLOAD_FIELD_FLOW_CONTROL(payload, bytes_transmitted, - flow_control_increment, *pipe_uuid); - return header; -} - VOID RPCRT4_FreeHeader(RpcPktHdr *Header) { HeapFree(GetProcessHeap(), 0, Header); @@ -472,206 +362,6 @@ static RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status) } } -/* assumes the common header fields have already been validated */ -BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, - unsigned short data_len) -{ - unsigned short i; - BYTE *p = data; - - for (i = 0; i < hdr->http.num_data_items; i++) - { - ULONG type; - - if (data_len < sizeof(ULONG)) - return FALSE; - - type = *(ULONG *)p; - p += sizeof(ULONG); - data_len -= sizeof(ULONG); - - switch (type) - { - case 0x3: - case 0xc: - if (data_len < sizeof(GUID)) - return FALSE; - p += sizeof(GUID); - data_len -= sizeof(GUID); - break; - case 0x0: - case 0x2: - case 0x4: - case 0x5: - case 0x6: - case 0xd: - if (data_len < sizeof(ULONG)) - return FALSE; - p += sizeof(ULONG); - data_len -= sizeof(ULONG); - break; - case 0x1: - if (data_len < 24) - return FALSE; - p += 24; - data_len -= 24; - break; - default: - FIXME("unimplemented type 0x%x\n", type); - break; - } - } - return TRUE; -} - -/* assumes the HTTP packet has been validated */ -static unsigned char *RPCRT4_NextHttpHeaderField(unsigned char *data) -{ - ULONG type; - - type = *(ULONG *)data; - data += sizeof(ULONG); - - switch (type) - { - case 0x3: - case 0xc: - return data + sizeof(GUID); - case 0x0: - case 0x2: - case 0x4: - case 0x5: - case 0x6: - case 0xd: - return data + sizeof(ULONG); - case 0x1: - return data + 24; - default: - FIXME("unimplemented type 0x%x\n", type); - return data; - } -} - -#define READ_HTTP_PAYLOAD_FIELD_TYPE(data) *(ULONG *)(data) -#define GET_HTTP_PAYLOAD_FIELD_DATA(data) ((data) + sizeof(ULONG)) - -/* assumes the HTTP packet has been validated */ -RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, - unsigned char *data, ULONG *field1) -{ - ULONG type; - if (header->http.flags != 0x0) - { - ERR("invalid flags 0x%x\n", header->http.flags); - return RPC_S_PROTOCOL_ERROR; - } - if (header->http.num_data_items != 1) - { - ERR("invalid number of data items %d\n", header->http.num_data_items); - return RPC_S_PROTOCOL_ERROR; - } - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000002) - { - ERR("invalid type 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - return RPC_S_OK; -} - -/* assumes the HTTP packet has been validated */ -RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, - unsigned char *data, ULONG *field1, - ULONG *bytes_until_next_packet, - ULONG *field3) -{ - ULONG type; - if (header->http.flags != 0x0) - { - ERR("invalid flags 0x%x\n", header->http.flags); - return RPC_S_PROTOCOL_ERROR; - } - if (header->http.num_data_items != 3) - { - ERR("invalid number of data items %d\n", header->http.num_data_items); - return RPC_S_PROTOCOL_ERROR; - } - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000006) - { - ERR("invalid type for field 1: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *field1 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - data = RPCRT4_NextHttpHeaderField(data); - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000000) - { - ERR("invalid type for field 2: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *bytes_until_next_packet = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - data = RPCRT4_NextHttpHeaderField(data); - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000002) - { - ERR("invalid type for field 3: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *field3 = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - - return RPC_S_OK; -} - -RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, - unsigned char *data, BOOL server, - ULONG *bytes_transmitted, - ULONG *flow_control_increment, - UUID *pipe_uuid) -{ - ULONG type; - if (header->http.flags != 0x2) - { - ERR("invalid flags 0x%x\n", header->http.flags); - return RPC_S_PROTOCOL_ERROR; - } - if (header->http.num_data_items != 2) - { - ERR("invalid number of data items %d\n", header->http.num_data_items); - return RPC_S_PROTOCOL_ERROR; - } - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x0000000d) - { - ERR("invalid type for field 1: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - if (*(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data) != (server ? 0x3 : 0x0)) - { - ERR("invalid type for 0xd field data: 0x%08x\n", *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data)); - return RPC_S_PROTOCOL_ERROR; - } - data = RPCRT4_NextHttpHeaderField(data); - - type = READ_HTTP_PAYLOAD_FIELD_TYPE(data); - if (type != 0x00000001) - { - ERR("invalid type for field 2: 0x%08x\n", type); - return RPC_S_PROTOCOL_ERROR; - } - *bytes_transmitted = *(ULONG *)GET_HTTP_PAYLOAD_FIELD_DATA(data); - *flow_control_increment = *(ULONG *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 4); - *pipe_uuid = *(UUID *)(GET_HTTP_PAYLOAD_FIELD_DATA(data) + 8); - - return RPC_S_OK; -} - - static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, @@ -819,7 +509,7 @@ static RPC_STATUS RPCRT4_SendWithAuth(RpcConnection *Connection, RpcPktHdr *Head auth_hdr->auth_pad_length = auth_pad_len; auth_hdr->auth_reserved = 0; /* a unique number... */ - auth_hdr->auth_context_id = Connection->auth_context_id; + auth_hdr->auth_context_id = (unsigned long)Connection; if (AuthLength) memcpy(auth_hdr + 1, Auth, AuthLength); @@ -997,7 +687,7 @@ RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, } /* validates version and frag_len fields */ -RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) +static RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) { DWORD hdr_length; @@ -1026,11 +716,11 @@ RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr) } /*********************************************************************** - * RPCRT4_default_receive_fragment (internal) + * RPCRT4_receive_fragment (internal) * * Receive a fragment from a connection. */ -static RPC_STATUS RPCRT4_default_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) +static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) { RPC_STATUS status; DWORD hdr_length; @@ -1104,14 +794,6 @@ fail: return status; } -static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) -{ - if (Connection->ops->receive_fragment) - return Connection->ops->receive_fragment(Connection, Header, Payload); - else - return RPCRT4_default_receive_fragment(Connection, Header, Payload); -} - /*********************************************************************** * RPCRT4_ReceiveWithAuth (internal) * @@ -1121,14 +803,14 @@ static RPC_STATUS RPCRT4_receive_fragment(RpcConnection *Connection, RpcPktHdr * RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, - ULONG *auth_length_out) + unsigned long *auth_length_out) { RPC_STATUS status; DWORD hdr_length; unsigned short first_flag; - ULONG data_length; - ULONG buffer_length; - ULONG auth_length = 0; + unsigned long data_length; + unsigned long buffer_length; + unsigned long auth_length = 0; unsigned char *auth_data = NULL; RpcPktHdr *CurrentHeader = NULL; void *payload = NULL; @@ -1192,7 +874,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, } if (CurrentHeader->common.auth_len != auth_length) { - WARN("auth_len header field changed from %d to %d\n", + WARN("auth_len header field changed from %ld to %d\n", auth_length, CurrentHeader->common.auth_len); status = RPC_S_PROTOCOL_ERROR; goto fail; @@ -1206,7 +888,7 @@ RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, data_length = CurrentHeader->common.frag_len - hdr_length - header_auth_len; if (data_length + buffer_length > pMsg->BufferLength) { - TRACE("allocation hint exceeded, new buffer length = %d\n", + TRACE("allocation hint exceeded, new buffer length = %ld\n", data_length + buffer_length); pMsg->BufferLength = data_length + buffer_length; status = I_RpcReAllocateBuffer(pMsg); @@ -1316,7 +998,7 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, */ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection* conn; RPC_STATUS status = RPC_S_OK; @@ -1381,7 +1063,7 @@ RPC_STATUS WINAPI I_RpcNegotiateTransferSyntax(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) { RPC_STATUS status; - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength); @@ -1438,7 +1120,7 @@ static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg) */ RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; TRACE("(%p) Buffer=%p\n", pMsg, pMsg->Buffer); @@ -1532,7 +1214,7 @@ static DWORD WINAPI async_notifier_proc(LPVOID p) */ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection* conn; RPC_STATUS status; RpcPktHdr *hdr; @@ -1586,7 +1268,7 @@ static inline BOOL is_hard_error(RPC_STATUS status) */ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; RPC_STATUS status; RpcPktHdr *hdr = NULL; RpcConnection *conn; @@ -1605,7 +1287,7 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) case PKT_RESPONSE: break; case PKT_FAULT: - ERR ("we got fault packet with status 0x%x\n", hdr->fault.status); + ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); status = NCA2RPC_STATUS(hdr->fault.status); if (is_hard_error(status)) goto fail; @@ -1678,7 +1360,7 @@ RPC_STATUS WINAPI I_RpcSendReceive(PRPC_MESSAGE pMsg) */ RPC_STATUS WINAPI I_RpcAsyncSetHandle(PRPC_MESSAGE pMsg, PRPC_ASYNC_STATE pAsync) { - RpcBinding* bind = pMsg->Handle; + RpcBinding* bind = (RpcBinding*)pMsg->Handle; RpcConnection *conn; TRACE("(%p, %p)\n", pMsg, pAsync); diff --git a/reactos/dll/win32/rpcrt4/rpc_message.h b/reactos/dll/win32/rpcrt4/rpc_message.h index aeeef0773e5..e4033882feb 100644 --- a/reactos/dll/win32/rpcrt4/rpc_message.h +++ b/reactos/dll/win32/rpcrt4/rpc_message.h @@ -25,25 +25,15 @@ typedef unsigned int NCA_STATUS; -RpcPktHdr *RPCRT4_BuildFaultHeader(ULONG DataRepresentation, RPC_STATUS Status); -RpcPktHdr *RPCRT4_BuildResponseHeader(ULONG DataRepresentation, ULONG BufferLength); -RpcPktHdr *RPCRT4_BuildBindHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); -RpcPktHdr *RPCRT4_BuildBindNackHeader(ULONG DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); -RpcPktHdr *RPCRT4_BuildBindAckHeader(ULONG DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, ULONG AssocGroupId, LPCSTR ServerAddress, unsigned short Result, unsigned short Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); -RpcPktHdr *RPCRT4_BuildHttpHeader(ULONG DataRepresentation, unsigned short flags, unsigned short num_data_items, unsigned int payload_size); -RpcPktHdr *RPCRT4_BuildHttpConnectHeader(unsigned short flags, int out_pipe, const UUID *connection_uuid, const UUID *pipe_uuid, const UUID *association_uuid); -RpcPktHdr *RPCRT4_BuildHttpFlowControlHeader(BOOL server, ULONG bytes_transmitted, ULONG flow_control_increment, const UUID *pipe_uuid); +RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status); +RpcPktHdr *RPCRT4_BuildResponseHeader(unsigned long DataRepresentation, unsigned long BufferLength); +RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); +RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); +RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, LPCSTR ServerAddress, unsigned long Result, unsigned long Reason, const RPC_SYNTAX_IDENTIFIER *TransferId); VOID RPCRT4_FreeHeader(RpcPktHdr *Header); RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength); RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg); -RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, ULONG *auth_length_out); -DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header); -RPC_STATUS RPCRT4_ValidateCommonHeader(const RpcPktCommonHdr *hdr); - -BOOL RPCRT4_IsValidHttpPacket(RpcPktHdr *hdr, unsigned char *data, unsigned short data_len); -RPC_STATUS RPCRT4_ParseHttpPrepareHeader1(RpcPktHdr *header, unsigned char *data, ULONG *field1); -RPC_STATUS RPCRT4_ParseHttpPrepareHeader2(RpcPktHdr *header, unsigned char *data, ULONG *field1, ULONG *bytes_until_next_packet, ULONG *field3); -RPC_STATUS RPCRT4_ParseHttpFlowControlHeader(RpcPktHdr *header, unsigned char *data, BOOL server, ULONG *bytes_transmitted, ULONG *flow_control_increment, UUID *pipe_uuid); +RPC_STATUS RPCRT4_ReceiveWithAuth(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg, unsigned char **auth_data_out, unsigned long *auth_length_out); NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status); RPC_STATUS RPCRT4_AuthorizeConnection(RpcConnection* conn, BYTE *challenge, ULONG count); diff --git a/reactos/dll/win32/rpcrt4/rpc_server.c b/reactos/dll/win32/rpcrt4/rpc_server.c index 34006396220..473c7ba9328 100644 --- a/reactos/dll/win32/rpcrt4/rpc_server.c +++ b/reactos/dll/win32/rpcrt4/rpc_server.c @@ -367,7 +367,7 @@ static DWORD CALLBACK RPCRT4_worker_thread(LPVOID the_arg) static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) { - RpcConnection* conn = the_arg; + RpcConnection* conn = (RpcConnection*)the_arg; RpcPktHdr *hdr; RPC_MESSAGE *msg; RPC_STATUS status; @@ -449,23 +449,27 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) /* start waiting */ res = cps->ops->wait_for_new_connection(cps, count, objs); - - if (res == -1 || (res == 0 && !std_listen)) - { - /* cleanup */ - cps->ops->free_wait_array(cps, objs); - EnterCriticalSection(&cps->cs); - for (conn = cps->conn; conn; conn = conn->Next) - RPCRT4_CloseConnection(conn); - LeaveCriticalSection(&cps->cs); - - if (res == 0 && !std_listen) - SetEvent(cps->server_ready_event); + if (res == -1) break; - } else if (res == 0) + { + if (!std_listen) + { + SetEvent(cps->server_ready_event); + break; + } set_ready_event = TRUE; + } } + cps->ops->free_wait_array(cps, objs); + EnterCriticalSection(&cps->cs); + /* close connections */ + conn = cps->conn; + while (conn) { + RPCRT4_CloseConnection(conn); + conn = conn->Next; + } + LeaveCriticalSection(&cps->cs); return 0; } @@ -566,32 +570,11 @@ static void RPCRT4_stop_listen(BOOL auto_listen) LeaveCriticalSection(&listen_cs); } -static BOOL RPCRT4_protseq_is_endpoint_registered(RpcServerProtseq *protseq, const char *endpoint) -{ - RpcConnection *conn; - EnterCriticalSection(&protseq->cs); - for (conn = protseq->conn; conn; conn = conn->Next) - { - if (!endpoint || !strcmp(endpoint, conn->Endpoint)) - break; - } - LeaveCriticalSection(&protseq->cs); - return (conn != NULL); -} - -static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, const char *endpoint) +static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps, LPSTR endpoint) { RPC_STATUS status; - EnterCriticalSection(&ps->cs); - - if (RPCRT4_protseq_is_endpoint_registered(ps, endpoint)) - status = RPC_S_OK; - else - status = ps->ops->open_endpoint(ps, endpoint); - - LeaveCriticalSection(&ps->cs); - + status = ps->ops->open_endpoint(ps, endpoint); if (status != RPC_S_OK) return status; @@ -625,8 +608,11 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) count = 0; LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { EnterCriticalSection(&ps->cs); - for (conn = ps->conn; conn; conn = conn->Next) + conn = ps->conn; + while (conn) { count++; + conn = conn->Next; + } LeaveCriticalSection(&ps->cs); } if (count) { @@ -638,10 +624,12 @@ RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector ) count = 0; LIST_FOR_EACH_ENTRY(ps, &protseqs, RpcServerProtseq, entry) { EnterCriticalSection(&ps->cs); - for (conn = ps->conn; conn; conn = conn->Next) { + conn = ps->conn; + while (conn) { RPCRT4_MakeBinding((RpcBinding**)&(*BindingVector)->BindingH[count], conn); count++; + conn = conn->Next; } LeaveCriticalSection(&ps->cs); } @@ -693,7 +681,7 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpW( RPC_WSTR Protseq, UINT MaxCalls, RPC_W * * Must be called with server_cs held. */ -static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps) +static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) { const struct protseq_ops *ops = rpcrt4_get_protseq_ops(Protseq); @@ -707,7 +695,7 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcSe if (!*ps) return RPC_S_OUT_OF_RESOURCES; (*ps)->MaxCalls = MaxCalls; - (*ps)->Protseq = RPCRT4_strdupA(Protseq); + (*ps)->Protseq = Protseq; (*ps)->ops = ops; (*ps)->MaxCalls = 0; (*ps)->conn = NULL; @@ -723,19 +711,8 @@ static RPC_STATUS alloc_serverprotoseq(UINT MaxCalls, const char *Protseq, RpcSe return RPC_S_OK; } -/* must be called with server_cs held */ -static void destroy_serverprotoseq(RpcServerProtseq *ps) -{ - RPCRT4_strfree(ps->Protseq); - DeleteCriticalSection(&ps->cs); - CloseHandle(ps->mgr_mutex); - CloseHandle(ps->server_ready_event); - list_remove(&ps->entry); - HeapFree(GetProcessHeap(), 0, ps); -} - /* Finds a given protseq or creates a new one if one doesn't already exist */ -static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char *Protseq, RpcServerProtseq **ps) +static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, char *Protseq, RpcServerProtseq **ps) { RPC_STATUS status; RpcServerProtseq *cps; @@ -764,18 +741,19 @@ static RPC_STATUS RPCRT4_get_or_create_serverprotseq(UINT MaxCalls, const char * RPC_STATUS WINAPI RpcServerUseProtseqEpExA( RPC_CSTR Protseq, UINT MaxCalls, RPC_CSTR Endpoint, LPVOID SecurityDescriptor, PRPC_POLICY lpPolicy ) { + char *szps = (char*)Protseq, *szep = (char*)Endpoint; RpcServerProtseq* ps; RPC_STATUS status; - TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a((const char *)Protseq), - MaxCalls, debugstr_a((const char *)Endpoint), SecurityDescriptor, + TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_a(szps), MaxCalls, + debugstr_a(szep), SecurityDescriptor, lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupA(szps), &ps); if (status != RPC_S_OK) return status; - return RPCRT4_use_protseq(ps, (const char *)Endpoint); + return RPCRT4_use_protseq(ps, szep); } /*********************************************************************** @@ -786,16 +764,13 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC { RpcServerProtseq* ps; RPC_STATUS status; - LPSTR ProtseqA; LPSTR EndpointA; TRACE("(%s,%u,%s,%p,{%u,%u,%u})\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor, lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags ); - ProtseqA = RPCRT4_strdupWtoA(Protseq); - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps); - RPCRT4_strfree(ProtseqA); + status = RPCRT4_get_or_create_serverprotseq(MaxCalls, RPCRT4_strdupWtoA(Protseq), &ps); if (status != RPC_S_OK) return status; @@ -810,16 +785,8 @@ RPC_STATUS WINAPI RpcServerUseProtseqEpExW( RPC_WSTR Protseq, UINT MaxCalls, RPC */ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) { - RPC_STATUS status; - RpcServerProtseq* ps; - TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_a((char*)Protseq), MaxCalls, SecurityDescriptor); - - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, (const char *)Protseq, &ps); - if (status != RPC_S_OK) - return status; - - return RPCRT4_use_protseq(ps, NULL); + return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor); } /*********************************************************************** @@ -827,36 +794,8 @@ RPC_STATUS WINAPI RpcServerUseProtseqA(RPC_CSTR Protseq, unsigned int MaxCalls, */ RPC_STATUS WINAPI RpcServerUseProtseqW(RPC_WSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor) { - RPC_STATUS status; - RpcServerProtseq* ps; - LPSTR ProtseqA; - TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)\n", debugstr_w(Protseq), MaxCalls, SecurityDescriptor); - - ProtseqA = RPCRT4_strdupWtoA(Protseq); - status = RPCRT4_get_or_create_serverprotseq(MaxCalls, ProtseqA, &ps); - RPCRT4_strfree(ProtseqA); - if (status != RPC_S_OK) - return status; - - return RPCRT4_use_protseq(ps, NULL); -} - -void RPCRT4_destroy_all_protseqs(void) -{ - RpcServerProtseq *cps, *cursor2; - - if (listen_count != 0) - std_listen = FALSE; - - EnterCriticalSection(&server_cs); - LIST_FOR_EACH_ENTRY_SAFE(cps, cursor2, &protseqs, RpcServerProtseq, entry) - { - if (listen_count != 0) - RPCRT4_sync_with_server_thread(cps); - destroy_serverprotoseq(cps); - } - LeaveCriticalSection(&server_cs); + return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor); } /*********************************************************************** @@ -884,7 +823,7 @@ RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn ) { - PRPC_SERVER_INTERFACE If = IfSpec; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; RpcServerInterface* sif; unsigned int i; @@ -937,7 +876,7 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, */ RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete ) { - PRPC_SERVER_INTERFACE If = IfSpec; + PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec; HANDLE event = NULL; BOOL found = FALSE; BOOL completed = TRUE; diff --git a/reactos/dll/win32/rpcrt4/rpc_server.h b/reactos/dll/win32/rpcrt4/rpc_server.h index cacce794e34..ffd5b016e4b 100644 --- a/reactos/dll/win32/rpcrt4/rpc_server.h +++ b/reactos/dll/win32/rpcrt4/rpc_server.h @@ -56,7 +56,7 @@ struct protseq_ops * new connection was established */ int (*wait_for_new_connection)(RpcServerProtseq *protseq, unsigned int count, void *wait_array); /* opens the endpoint and optionally begins listening */ - RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, const char *endpoint); + RPC_STATUS (*open_endpoint)(RpcServerProtseq *protseq, LPSTR endpoint); }; typedef struct _RpcServerInterface @@ -79,6 +79,4 @@ typedef struct _RpcServerInterface void RPCRT4_new_client(RpcConnection* conn); const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq); -void RPCRT4_destroy_all_protseqs(void); - #endif /* __WINE_RPC_SERVER_H */ diff --git a/reactos/dll/win32/rpcrt4/rpc_transport.c b/reactos/dll/win32/rpcrt4/rpc_transport.c index dddc5135c9d..735a19df648 100644 --- a/reactos/dll/win32/rpcrt4/rpc_transport.c +++ b/reactos/dll/win32/rpcrt4/rpc_transport.c @@ -40,8 +40,6 @@ # ifndef EAGAIN # define EAGAIN WSAEWOULDBLOCK # endif -# undef errno -# define errno WSAGetLastError() #else # include # ifdef HAVE_UNISTD_H @@ -66,21 +64,16 @@ # ifdef HAVE_SYS_POLL_H # include # endif -# ifdef HAVE_SYS_FILIO_H -# include -# endif -# ifdef HAVE_SYS_IOCTL_H -# include -# endif # define closesocket close -# define ioctlsocket ioctl #endif /* defined(__MINGW32__) || defined (_MSC_VER) */ +#include +#include + #include "windef.h" #include "winbase.h" #include "winnls.h" #include "winerror.h" -#include "wininet.h" #include "winternl.h" #include "wine/unicode.h" @@ -90,17 +83,16 @@ #include "wine/debug.h" #include "rpc_binding.h" -#include "rpc_assoc.h" #include "rpc_message.h" #include "rpc_server.h" #include "epm_towers.h" +#include "unix_func.h" + #ifndef SOL_TCP # define SOL_TCP IPPROTO_TCP #endif -#define DEFAULT_NCACN_HTTP_TIMEOUT (60 * 1000) - WINE_DEFAULT_DEBUG_CHANNEL(rpc); static RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection); @@ -266,23 +258,12 @@ static RPC_STATUS rpcrt4_ncalrpc_open(RpcConnection* Connection) return r; } -static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, const char *endpoint) +static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq, LPSTR endpoint) { static const char prefix[] = "\\\\.\\pipe\\lrpc\\"; RPC_STATUS r; LPSTR pname; RpcConnection *Connection; - char generated_endpoint[22]; - - if (!endpoint) - { - static LONG lrpc_nameless_id; - DWORD process_id = GetCurrentProcessId(); - ULONG id = InterlockedIncrement(&lrpc_nameless_id); - snprintf(generated_endpoint, sizeof(generated_endpoint), - "LRPC%08x.%08x", process_id, id); - endpoint = generated_endpoint; - } r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); @@ -324,23 +305,12 @@ static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection) return r; } -static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, const char *endpoint) +static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint) { static const char prefix[] = "\\\\."; RPC_STATUS r; LPSTR pname; RpcConnection *Connection; - char generated_endpoint[21]; - - if (!endpoint) - { - static LONG np_nameless_id; - DWORD process_id = GetCurrentProcessId(); - ULONG id = InterlockedExchangeAdd(&np_nameless_id, 1 ); - snprintf(generated_endpoint, sizeof(generated_endpoint), - "\\\\pipe\\\\%08x.%03x", process_id, id); - endpoint = generated_endpoint; - } r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); @@ -370,7 +340,7 @@ static void rpcrt4_conn_np_handoff(RpcConnection_np *old_npc, RpcConnection_np * new_npc->ovl[0] = old_npc->ovl[0]; new_npc->ovl[1] = old_npc->ovl[1]; old_npc->pipe = 0; - memset(&old_npc->ovl[0], 0, sizeof(old_npc->ovl)); + memset(&old_npc->ovl, 0, sizeof(old_npc->ovl)); old_npc->listening = FALSE; } @@ -422,11 +392,11 @@ static int rpcrt4_conn_np_read(RpcConnection *Connection, ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, &npc->ovl[0]); if ((!ret || !bytes_read) && (GetLastError() != ERROR_IO_PENDING)) break; + ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE); - if (!ret && GetLastError() == ERROR_MORE_DATA) - ret = TRUE; - if (!ret || !bytes_read) + if (!ret && (GetLastError() != ERROR_MORE_DATA)) break; + bytes_left -= bytes_read; buf += bytes_read; } @@ -447,11 +417,11 @@ static int rpcrt4_conn_np_write(RpcConnection *Connection, ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, &npc->ovl[1]); if ((!ret || !bytes_written) && (GetLastError() != ERROR_IO_PENDING)) break; + ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE); - if (!ret && GetLastError() == ERROR_MORE_DATA) - ret = TRUE; - if (!ret || !bytes_written) + if (!ret && (GetLastError() != ERROR_MORE_DATA)) break; + bytes_left -= bytes_written; buf += bytes_written; } @@ -786,10 +756,377 @@ static RPC_STATUS rpcrt4_ncalrpc_parse_top_of_tower(const unsigned char *tower_d /**** ncacn_ip_tcp support ****/ -static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data, - const char *networkaddr, - unsigned char tcp_protid, - const char *endpoint) +#ifdef HAVE_SOCKETPAIR + +typedef struct _RpcConnection_tcp +{ + RpcConnection common; + int sock; + int cancel_fds[2]; +} RpcConnection_tcp; + +static RpcConnection *rpcrt4_conn_tcp_alloc(void) +{ + RpcConnection_tcp *tcpc; + tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp)); + if (tcpc == NULL) + return NULL; + tcpc->sock = -1; + if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0) + { + ERR("socketpair() failed: %s\n", strerror(errno)); + HeapFree(GetProcessHeap(), 0, tcpc); + return NULL; + } + return &tcpc->common; +} + +static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int sock; + int ret; + struct addrinfo *ai; + struct addrinfo *ai_cur; + struct addrinfo hints; + + TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); + + if (tcpc->sock != -1) + return RPC_S_OK; + + hints.ai_flags = 0; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + ret = getaddrinfo(Connection->NetworkAddr, Connection->Endpoint, &hints, &ai); + if (ret) + { + ERR("getaddrinfo for %s:%s failed: %s\n", Connection->NetworkAddr, + Connection->Endpoint, gai_strerror(ret)); + return RPC_S_SERVER_UNAVAILABLE; + } + + for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) + { + int val; + + if (TRACE_ON(rpc)) + { + char host[256]; + char service[256]; + getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, + host, sizeof(host), service, sizeof(service), + NI_NUMERICHOST | NI_NUMERICSERV); + TRACE("trying %s:%s\n", host, service); + } + + sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); + if (sock == -1) + { + WARN("socket() failed: %s\n", strerror(errno)); + continue; + } + + if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen)) + { + WARN("connect() failed: %s\n", strerror(errno)); + closesocket(sock); + continue; + } + + /* RPC depends on having minimal latency so disable the Nagle algorithm */ + val = 1; + setsockopt(sock, SOL_TCP, TCP_NODELAY, &val, sizeof(val)); + fcntl(sock, F_SETFL, O_NONBLOCK); /* make socket nonblocking */ + + tcpc->sock = sock; + + freeaddrinfo(ai); + TRACE("connected\n"); + return RPC_S_OK; + } + + freeaddrinfo(ai); + ERR("couldn't connect to %s:%s\n", Connection->NetworkAddr, Connection->Endpoint); + return RPC_S_SERVER_UNAVAILABLE; +} + +static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, LPSTR endpoint) +{ + RPC_STATUS status = RPC_S_CANT_CREATE_ENDPOINT; + int sock; + int ret; + struct addrinfo *ai; + struct addrinfo *ai_cur; + struct addrinfo hints; + RpcConnection *first_connection = NULL; + + TRACE("(%p, %s)\n", protseq, endpoint); + + hints.ai_flags = AI_PASSIVE /* for non-localhost addresses */; + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + ret = getaddrinfo(NULL, endpoint, &hints, &ai); + if (ret) + { + ERR("getaddrinfo for port %s failed: %s\n", endpoint, + gai_strerror(ret)); + if ((ret == EAI_SERVICE) || (ret == EAI_NONAME)) + return RPC_S_INVALID_ENDPOINT_FORMAT; + return RPC_S_CANT_CREATE_ENDPOINT; + } + + for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) + { + RpcConnection_tcp *tcpc; + RPC_STATUS create_status; + + if (TRACE_ON(rpc)) + { + char host[256]; + char service[256]; + getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, + host, sizeof(host), service, sizeof(service), + NI_NUMERICHOST | NI_NUMERICSERV); + TRACE("trying %s:%s\n", host, service); + } + + sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); + if (sock == -1) + { + WARN("socket() failed: %s\n", strerror(errno)); + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + + ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen); + if (ret < 0) + { + WARN("bind failed: %s\n", strerror(errno)); + closesocket(sock); + if (errno == EADDRINUSE) + status = RPC_S_DUPLICATE_ENDPOINT; + else + status = RPC_S_CANT_CREATE_ENDPOINT; + continue; + } + create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE, + protseq->Protseq, NULL, + endpoint, NULL, NULL, NULL); + if (create_status != RPC_S_OK) + { + closesocket(sock); + status = create_status; + continue; + } + + tcpc->sock = sock; + ret = listen(sock, protseq->MaxCalls); + if (ret < 0) + { + WARN("listen failed: %s\n", strerror(errno)); + RPCRT4_DestroyConnection(&tcpc->common); + status = RPC_S_OUT_OF_RESOURCES; + continue; + } + /* need a non-blocking socket, otherwise accept() has a potential + * race-condition (poll() says it is readable, connection drops, + * and accept() blocks until the next connection comes...) + */ + ret = fcntl(sock, F_SETFL, O_NONBLOCK); + if (ret < 0) + { + WARN("couldn't make socket non-blocking, error %d\n", ret); + RPCRT4_DestroyConnection(&tcpc->common); + status = RPC_S_OUT_OF_RESOURCES; + continue; + } + + tcpc->common.Next = first_connection; + first_connection = &tcpc->common; + } + + freeaddrinfo(ai); + + /* if at least one connection was created for an endpoint then + * return success */ + if (first_connection) + { + RpcConnection *conn; + + /* find last element in list */ + for (conn = first_connection; conn->Next; conn = conn->Next) + ; + + EnterCriticalSection(&protseq->cs); + conn->Next = protseq->conn; + protseq->conn = first_connection; + LeaveCriticalSection(&protseq->cs); + + TRACE("listening on %s\n", endpoint); + return RPC_S_OK; + } + + ERR("couldn't listen on port %s\n", endpoint); + return status; +} + +static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection *new_conn) +{ + int ret; + struct sockaddr_in address; + socklen_t addrsize; + RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn; + RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn; + + addrsize = sizeof(address); + ret = accept(server->sock, (struct sockaddr*) &address, &addrsize); + if (ret < 0) + { + ERR("Failed to accept a TCP connection: error %d\n", ret); + return RPC_S_OUT_OF_RESOURCES; + } + /* reset to blocking behaviour */ + fcntl(ret, F_SETFL, 0); + client->sock = ret; + TRACE("Accepted a new TCP connection\n"); + return RPC_S_OK; +} + +static int rpcrt4_conn_tcp_read(RpcConnection *Connection, + void *buffer, unsigned int count) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int bytes_read = 0; + do + { + int r = recv(tcpc->sock, (char *)buffer + bytes_read, count - bytes_read, 0); + if (!r) + return -1; + else if (r > 0) + bytes_read += r; + else if (errno != EAGAIN) + { + WARN("recv() failed: %s\n", strerror(errno)); + return -1; + } + else + { + struct pollfd pfds[2]; + pfds[0].fd = tcpc->sock; + pfds[0].events = POLLIN; + pfds[1].fd = tcpc->cancel_fds[0]; + pfds[1].events = POLLIN; + if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) + { + ERR("poll() failed: %s\n", strerror(errno)); + return -1; + } + if (pfds[1].revents & POLLIN) /* canceled */ + { + char dummy; + read(pfds[1].fd, &dummy, sizeof(dummy)); + return -1; + } + } + } while (bytes_read != count); + TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_read); + return bytes_read; +} + +static int rpcrt4_conn_tcp_write(RpcConnection *Connection, + const void *buffer, unsigned int count) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + int bytes_written = 0; + do + { + int r = send(tcpc->sock, (const char *)buffer + bytes_written, count - bytes_written, 0); + if (r >= 0) + bytes_written += r; + else if (errno != EAGAIN) + return -1; + else + { + struct pollfd pfd; + pfd.fd = tcpc->sock; + pfd.events = POLLOUT; + if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR) + { + ERR("poll() failed: %s\n", strerror(errno)); + return -1; + } + } + } while (bytes_written != count); + TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_written); + return bytes_written; +} + +static int rpcrt4_conn_tcp_close(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + + TRACE("%d\n", tcpc->sock); + + if (tcpc->sock != -1) + closesocket(tcpc->sock); + tcpc->sock = -1; + close(tcpc->cancel_fds[0]); + close(tcpc->cancel_fds[1]); + return 0; +} + +static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + char dummy = 1; + + TRACE("%p\n", Connection); + + write(tcpc->cancel_fds[1], &dummy, 1); +} + +static int rpcrt4_conn_tcp_wait_for_incoming_data(RpcConnection *Connection) +{ + RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; + struct pollfd pfds[2]; + + TRACE("%p\n", Connection); + + pfds[0].fd = tcpc->sock; + pfds[0].events = POLLIN; + pfds[1].fd = tcpc->cancel_fds[0]; + pfds[1].events = POLLIN; + if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) + { + ERR("poll() failed: %s\n", strerror(errno)); + return -1; + } + if (pfds[1].revents & POLLIN) /* canceled */ + { + char dummy; + read(pfds[1].fd, &dummy, sizeof(dummy)); + return -1; + } + + return 0; +} + +static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data, + const char *networkaddr, + const char *endpoint) { twr_tcp_floor_t *tcp_floor; twr_ipv4_floor_t *ipv4_floor; @@ -809,7 +1146,7 @@ static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data, ipv4_floor = (twr_ipv4_floor_t *)tower_data; tcp_floor->count_lhs = sizeof(tcp_floor->protid); - tcp_floor->protid = tcp_protid; + tcp_floor->protid = EPM_PROTOCOL_TCP; tcp_floor->count_rhs = sizeof(tcp_floor->port); ipv4_floor->count_lhs = sizeof(ipv4_floor->protid); @@ -854,11 +1191,10 @@ static size_t rpcrt4_ip_tcp_get_top_of_tower(unsigned char *tower_data, return size; } -static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, - size_t tower_size, - char **networkaddr, - unsigned char tcp_protid, - char **endpoint) +static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, + size_t tower_size, + char **networkaddr, + char **endpoint) { const twr_tcp_floor_t *tcp_floor = (const twr_tcp_floor_t *)tower_data; const twr_ipv4_floor_t *ipv4_floor; @@ -878,7 +1214,7 @@ static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_da ipv4_floor = (const twr_ipv4_floor_t *)tower_data; if ((tcp_floor->count_lhs != sizeof(tcp_floor->protid)) || - (tcp_floor->protid != tcp_protid) || + (tcp_floor->protid != EPM_PROTOCOL_TCP) || (tcp_floor->count_rhs != sizeof(tcp_floor->port)) || (ipv4_floor->count_lhs != sizeof(ipv4_floor->protid)) || (ipv4_floor->protid != EPM_PROTOCOL_IP) || @@ -923,528 +1259,6 @@ static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_da return RPC_S_OK; } -typedef struct _RpcConnection_tcp -{ - RpcConnection common; - int sock; -#ifdef HAVE_SOCKETPAIR - int cancel_fds[2]; -#else - HANDLE sock_event; - HANDLE cancel_event; -#endif -} RpcConnection_tcp; - -#ifdef HAVE_SOCKETPAIR - -static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc) -{ - if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0) - { - ERR("socketpair() failed: %s\n", strerror(errno)); - return FALSE; - } - return TRUE; -} - -static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc) -{ - struct pollfd pfds[2]; - pfds[0].fd = tcpc->sock; - pfds[0].events = POLLIN; - pfds[1].fd = tcpc->cancel_fds[0]; - pfds[1].events = POLLIN; - if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR) - { - ERR("poll() failed: %s\n", strerror(errno)); - return FALSE; - } - if (pfds[1].revents & POLLIN) /* canceled */ - { - char dummy; - read(pfds[1].fd, &dummy, sizeof(dummy)); - return FALSE; - } - return TRUE; -} - -static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc) -{ - struct pollfd pfd; - pfd.fd = tcpc->sock; - pfd.events = POLLOUT; - if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR) - { - ERR("poll() failed: %s\n", strerror(errno)); - return FALSE; - } - return TRUE; -} - -static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc) -{ - char dummy = 1; - - write(tcpc->cancel_fds[1], &dummy, 1); -} - -static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc) -{ - close(tcpc->cancel_fds[0]); - close(tcpc->cancel_fds[1]); -} - -#else /* HAVE_SOCKETPAIR */ - -static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc) -{ - static BOOL wsa_inited; - if (!wsa_inited) - { - WSADATA wsadata; - WSAStartup(MAKEWORD(2, 2), &wsadata); - /* Note: WSAStartup can be called more than once so we don't bother with - * making accesses to wsa_inited thread-safe */ - wsa_inited = TRUE; - } - tcpc->sock_event = CreateEventW(NULL, FALSE, FALSE, NULL); - tcpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL); - if (!tcpc->sock_event || !tcpc->cancel_event) - { - ERR("event creation failed\n"); - if (tcpc->sock_event) CloseHandle(tcpc->sock_event); - return FALSE; - } - return TRUE; -} - -static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc) -{ - HANDLE wait_handles[2]; - DWORD res; - if (WSAEventSelect(tcpc->sock, tcpc->sock_event, FD_READ | FD_CLOSE) == SOCKET_ERROR) - { - ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); - return FALSE; - } - wait_handles[0] = tcpc->sock_event; - wait_handles[1] = tcpc->cancel_event; - res = WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE); - switch (res) - { - case WAIT_OBJECT_0: - return TRUE; - case WAIT_OBJECT_0 + 1: - return FALSE; - default: - ERR("WaitForMultipleObjects() failed with error %d\n", GetLastError()); - return FALSE; - } -} - -static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc) -{ - DWORD res; - if (WSAEventSelect(tcpc->sock, tcpc->sock_event, FD_WRITE | FD_CLOSE) == SOCKET_ERROR) - { - ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); - return FALSE; - } - res = WaitForSingleObject(tcpc->sock_event, INFINITE); - switch (res) - { - case WAIT_OBJECT_0: - return TRUE; - default: - ERR("WaitForMultipleObjects() failed with error %d\n", GetLastError()); - return FALSE; - } -} - -static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc) -{ - SetEvent(tcpc->cancel_event); -} - -static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc) -{ - CloseHandle(tcpc->sock_event); - CloseHandle(tcpc->cancel_event); -} - -#endif - -static RpcConnection *rpcrt4_conn_tcp_alloc(void) -{ - RpcConnection_tcp *tcpc; - tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp)); - if (tcpc == NULL) - return NULL; - tcpc->sock = -1; - if (!rpcrt4_sock_wait_init(tcpc)) - { - HeapFree(GetProcessHeap(), 0, tcpc); - return NULL; - } - return &tcpc->common; -} - -static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int sock; - int ret; - struct addrinfo *ai; - struct addrinfo *ai_cur; - struct addrinfo hints; - - TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); - - if (tcpc->sock != -1) - return RPC_S_OK; - - hints.ai_flags = 0; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_addr = NULL; - hints.ai_canonname = NULL; - hints.ai_next = NULL; - - ret = getaddrinfo(Connection->NetworkAddr, Connection->Endpoint, &hints, &ai); - if (ret) - { - ERR("getaddrinfo for %s:%s failed: %s\n", Connection->NetworkAddr, - Connection->Endpoint, gai_strerror(ret)); - return RPC_S_SERVER_UNAVAILABLE; - } - - for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) - { - int val; - u_long nonblocking; - - if (ai_cur->ai_family != AF_INET && ai_cur->ai_family != AF_INET6) - { - TRACE("skipping non-IP/IPv6 address family\n"); - continue; - } - - if (TRACE_ON(rpc)) - { - char host[256]; - char service[256]; - getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, - host, sizeof(host), service, sizeof(service), - NI_NUMERICHOST | NI_NUMERICSERV); - TRACE("trying %s:%s\n", host, service); - } - - sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); - if (sock == -1) - { - WARN("socket() failed: %s\n", strerror(errno)); - continue; - } - - if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen)) - { - WARN("connect() failed: %s\n", strerror(errno)); - closesocket(sock); - continue; - } - - /* RPC depends on having minimal latency so disable the Nagle algorithm */ - val = 1; - setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); - nonblocking = 1; - ioctlsocket(sock, FIONBIO, &nonblocking); - - tcpc->sock = sock; - - freeaddrinfo(ai); - TRACE("connected\n"); - return RPC_S_OK; - } - - freeaddrinfo(ai); - ERR("couldn't connect to %s:%s\n", Connection->NetworkAddr, Connection->Endpoint); - return RPC_S_SERVER_UNAVAILABLE; -} - -static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *protseq, const char *endpoint) -{ - RPC_STATUS status = RPC_S_CANT_CREATE_ENDPOINT; - int sock; - int ret; - struct addrinfo *ai; - struct addrinfo *ai_cur; - struct addrinfo hints; - RpcConnection *first_connection = NULL; - - TRACE("(%p, %s)\n", protseq, endpoint); - - hints.ai_flags = AI_PASSIVE /* for non-localhost addresses */; - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_addrlen = 0; - hints.ai_addr = NULL; - hints.ai_canonname = NULL; - hints.ai_next = NULL; - - ret = getaddrinfo(NULL, endpoint ? endpoint : "0", &hints, &ai); - if (ret) - { - ERR("getaddrinfo for port %s failed: %s\n", endpoint, - gai_strerror(ret)); - if ((ret == EAI_SERVICE) || (ret == EAI_NONAME)) - return RPC_S_INVALID_ENDPOINT_FORMAT; - return RPC_S_CANT_CREATE_ENDPOINT; - } - - for (ai_cur = ai; ai_cur; ai_cur = ai_cur->ai_next) - { - RpcConnection_tcp *tcpc; - RPC_STATUS create_status; - struct sockaddr_storage sa; - socklen_t sa_len; - char service[NI_MAXSERV]; - u_long nonblocking; - - if (ai_cur->ai_family != AF_INET && ai_cur->ai_family != AF_INET6) - { - TRACE("skipping non-IP/IPv6 address family\n"); - continue; - } - - if (TRACE_ON(rpc)) - { - char host[256]; - getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen, - host, sizeof(host), service, sizeof(service), - NI_NUMERICHOST | NI_NUMERICSERV); - TRACE("trying %s:%s\n", host, service); - } - - sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol); - if (sock == -1) - { - WARN("socket() failed: %s\n", strerror(errno)); - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen); - if (ret < 0) - { - WARN("bind failed: %s\n", strerror(errno)); - closesocket(sock); - if (errno == EADDRINUSE) - status = RPC_S_DUPLICATE_ENDPOINT; - else - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - sa_len = sizeof(sa); - if (getsockname(sock, (struct sockaddr *)&sa, &sa_len)) - { - WARN("getsockname() failed: %s\n", strerror(errno)); - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - ret = getnameinfo((struct sockaddr *)&sa, sa_len, - NULL, 0, service, sizeof(service), - NI_NUMERICSERV); - if (ret) - { - WARN("getnameinfo failed: %s\n", gai_strerror(ret)); - status = RPC_S_CANT_CREATE_ENDPOINT; - continue; - } - - create_status = RPCRT4_CreateConnection((RpcConnection **)&tcpc, TRUE, - protseq->Protseq, NULL, - service, NULL, NULL, NULL); - if (create_status != RPC_S_OK) - { - closesocket(sock); - status = create_status; - continue; - } - - tcpc->sock = sock; - ret = listen(sock, protseq->MaxCalls); - if (ret < 0) - { - WARN("listen failed: %s\n", strerror(errno)); - RPCRT4_DestroyConnection(&tcpc->common); - status = RPC_S_OUT_OF_RESOURCES; - continue; - } - /* need a non-blocking socket, otherwise accept() has a potential - * race-condition (poll() says it is readable, connection drops, - * and accept() blocks until the next connection comes...) - */ - nonblocking = 1; - ret = ioctlsocket(sock, FIONBIO, &nonblocking); - if (ret < 0) - { - WARN("couldn't make socket non-blocking, error %d\n", ret); - RPCRT4_DestroyConnection(&tcpc->common); - status = RPC_S_OUT_OF_RESOURCES; - continue; - } - - tcpc->common.Next = first_connection; - first_connection = &tcpc->common; - - /* since IPv4 and IPv6 share the same port space, we only need one - * successful bind to listen for both */ - break; - } - - freeaddrinfo(ai); - - /* if at least one connection was created for an endpoint then - * return success */ - if (first_connection) - { - RpcConnection *conn; - - /* find last element in list */ - for (conn = first_connection; conn->Next; conn = conn->Next) - ; - - EnterCriticalSection(&protseq->cs); - conn->Next = protseq->conn; - protseq->conn = first_connection; - LeaveCriticalSection(&protseq->cs); - - TRACE("listening on %s\n", endpoint); - return RPC_S_OK; - } - - ERR("couldn't listen on port %s\n", endpoint); - return status; -} - -static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection *new_conn) -{ - int ret; - struct sockaddr_in address; - socklen_t addrsize; - RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn; - RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn; - u_long nonblocking; - - addrsize = sizeof(address); - ret = accept(server->sock, (struct sockaddr*) &address, &addrsize); - if (ret < 0) - { - ERR("Failed to accept a TCP connection: error %d\n", ret); - return RPC_S_OUT_OF_RESOURCES; - } - nonblocking = 1; - ioctlsocket(ret, FIONBIO, &nonblocking); - client->sock = ret; - TRACE("Accepted a new TCP connection\n"); - return RPC_S_OK; -} - -static int rpcrt4_conn_tcp_read(RpcConnection *Connection, - void *buffer, unsigned int count) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int bytes_read = 0; - do - { - int r = recv(tcpc->sock, (char *)buffer + bytes_read, count - bytes_read, 0); - if (!r) - return -1; - else if (r > 0) - bytes_read += r; - else if (errno != EAGAIN) - { - WARN("recv() failed: %s\n", strerror(errno)); - return -1; - } - else - { - if (!rpcrt4_sock_wait_for_recv(tcpc)) - return -1; - } - } while (bytes_read != count); - TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_read); - return bytes_read; -} - -static int rpcrt4_conn_tcp_write(RpcConnection *Connection, - const void *buffer, unsigned int count) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - int bytes_written = 0; - do - { - int r = send(tcpc->sock, (const char *)buffer + bytes_written, count - bytes_written, 0); - if (r >= 0) - bytes_written += r; - else if (errno != EAGAIN) - return -1; - else - { - if (!rpcrt4_sock_wait_for_send(tcpc)) - return -1; - } - } while (bytes_written != count); - TRACE("%d %p %u -> %d\n", tcpc->sock, buffer, count, bytes_written); - return bytes_written; -} - -static int rpcrt4_conn_tcp_close(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - - TRACE("%d\n", tcpc->sock); - - if (tcpc->sock != -1) - closesocket(tcpc->sock); - tcpc->sock = -1; - rpcrt4_sock_wait_destroy(tcpc); - return 0; -} - -static void rpcrt4_conn_tcp_cancel_call(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - TRACE("%p\n", Connection); - rpcrt4_sock_wait_cancel(tcpc); -} - -static int rpcrt4_conn_tcp_wait_for_incoming_data(RpcConnection *Connection) -{ - RpcConnection_tcp *tcpc = (RpcConnection_tcp *) Connection; - - TRACE("%p\n", Connection); - - if (!rpcrt4_sock_wait_for_recv(tcpc)) - return -1; - return 0; -} - -static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data, - const char *networkaddr, - const char *endpoint) -{ - return rpcrt4_ip_tcp_get_top_of_tower(tower_data, networkaddr, - EPM_PROTOCOL_TCP, endpoint); -} - -#ifdef HAVE_SOCKETPAIR - typedef struct _RpcServerProtseq_sock { RpcServerProtseq common; @@ -1584,1100 +1398,8 @@ static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq return 1; } -#else /* HAVE_SOCKETPAIR */ - -typedef struct _RpcServerProtseq_sock -{ - RpcServerProtseq common; - HANDLE mgr_event; -} RpcServerProtseq_sock; - -static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void) -{ - RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps)); - if (ps) - { - static BOOL wsa_inited; - if (!wsa_inited) - { - WSADATA wsadata; - WSAStartup(MAKEWORD(2, 2), &wsadata); - /* Note: WSAStartup can be called more than once so we don't bother with - * making accesses to wsa_inited thread-safe */ - wsa_inited = TRUE; - } - ps->mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL); - } - return &ps->common; -} - -static void rpcrt4_protseq_sock_signal_state_changed(RpcServerProtseq *protseq) -{ - RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common); - SetEvent(sockps->mgr_event); -} - -static void *rpcrt4_protseq_sock_get_wait_array(RpcServerProtseq *protseq, void *prev_array, unsigned int *count) -{ - HANDLE *objs = prev_array; - RpcConnection_tcp *conn; - RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common); - - EnterCriticalSection(&protseq->cs); - - /* open and count connections */ - *count = 1; - conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); - while (conn) - { - if (conn->sock != -1) - (*count)++; - conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); - } - - /* make array of connections */ - if (objs) - objs = HeapReAlloc(GetProcessHeap(), 0, objs, *count*sizeof(HANDLE)); - else - objs = HeapAlloc(GetProcessHeap(), 0, *count*sizeof(HANDLE)); - if (!objs) - { - ERR("couldn't allocate objs\n"); - LeaveCriticalSection(&protseq->cs); - return NULL; - } - - objs[0] = sockps->mgr_event; - *count = 1; - conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); - while (conn) - { - if (conn->sock != -1) - { - int res = WSAEventSelect(conn->sock, conn->sock_event, FD_ACCEPT); - if (res == SOCKET_ERROR) - ERR("WSAEventSelect() failed with error %d\n", WSAGetLastError()); - else - { - objs[*count] = conn->sock_event; - (*count)++; - } - } - conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); - } - LeaveCriticalSection(&protseq->cs); - return objs; -} - -static void rpcrt4_protseq_sock_free_wait_array(RpcServerProtseq *protseq, void *array) -{ - HeapFree(GetProcessHeap(), 0, array); -} - -static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq, unsigned int count, void *wait_array) -{ - HANDLE b_handle; - HANDLE *objs = wait_array; - DWORD res; - RpcConnection *cconn; - RpcConnection_tcp *conn; - - if (!objs) - return -1; - - do - { - /* an alertable wait isn't strictly necessary, but due to our - * overlapped I/O implementation in Wine we need to free some memory - * by the file user APC being called, even if no completion routine was - * specified at the time of starting the async operation */ - res = WaitForMultipleObjectsEx(count, objs, FALSE, INFINITE, TRUE); - } while (res == WAIT_IO_COMPLETION); - - if (res == WAIT_OBJECT_0) - return 0; - else if (res == WAIT_FAILED) - { - ERR("wait failed with error %d\n", GetLastError()); - return -1; - } - else - { - b_handle = objs[res - WAIT_OBJECT_0]; - /* find which connection got a RPC */ - EnterCriticalSection(&protseq->cs); - conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common); - while (conn) - { - if (b_handle == conn->sock_event) break; - conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common); - } - cconn = NULL; - if (conn) - RPCRT4_SpawnConnection(&cconn, &conn->common); - else - ERR("failed to locate connection for handle %p\n", b_handle); - LeaveCriticalSection(&protseq->cs); - if (cconn) - { - RPCRT4_new_client(cconn); - return 1; - } - else return -1; - } -} - #endif /* HAVE_SOCKETPAIR */ -static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data, - size_t tower_size, - char **networkaddr, - char **endpoint) -{ - return rpcrt4_ip_tcp_parse_top_of_tower(tower_data, tower_size, - networkaddr, EPM_PROTOCOL_TCP, - endpoint); -} - -/**** ncacn_http support ****/ -#if 0 -/* 60 seconds is the period native uses */ -#define HTTP_IDLE_TIME 60000 - -/* reference counted to avoid a race between a cancelled call's connection - * being destroyed and the asynchronous InternetReadFileEx call being - * completed */ -typedef struct _RpcHttpAsyncData -{ - LONG refs; - HANDLE completion_event; - INTERNET_BUFFERSA inet_buffers; - void *destination_buffer; /* the address that inet_buffers.lpvBuffer will be - * copied into when the call completes */ - CRITICAL_SECTION cs; -} RpcHttpAsyncData; - -static ULONG RpcHttpAsyncData_AddRef(RpcHttpAsyncData *data) -{ - return InterlockedIncrement(&data->refs); -} - -static ULONG RpcHttpAsyncData_Release(RpcHttpAsyncData *data) -{ - ULONG refs = InterlockedDecrement(&data->refs); - if (!refs) - { - TRACE("destroying async data %p\n", data); - CloseHandle(data->completion_event); - HeapFree(GetProcessHeap(), 0, data->inet_buffers.lpvBuffer); - DeleteCriticalSection(&data->cs); - HeapFree(GetProcessHeap(), 0, data); - } - return refs; -} - -typedef struct _RpcConnection_http -{ - RpcConnection common; - HINTERNET app_info; - HINTERNET session; - HINTERNET in_request; - HINTERNET out_request; - HANDLE timer_cancelled; - HANDLE cancel_event; - DWORD last_sent_time; - ULONG bytes_received; - ULONG flow_control_mark; /* send a control packet to the server when this many bytes received */ - ULONG flow_control_increment; /* number of bytes to increment flow_control_mark by */ - UUID connection_uuid; - UUID in_pipe_uuid; - UUID out_pipe_uuid; - RpcHttpAsyncData *async_data; -} RpcConnection_http; - -static RpcConnection *rpcrt4_ncacn_http_alloc(void) -{ - RpcConnection_http *httpc; - httpc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*httpc)); - if (!httpc) return NULL; - httpc->async_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcHttpAsyncData)); - if (!httpc->async_data) - { - HeapFree(GetProcessHeap(), 0, httpc); - return NULL; - } - TRACE("async data = %p\n", httpc->async_data); - httpc->cancel_event = CreateEventW(NULL, FALSE, FALSE, NULL); - httpc->async_data->refs = 1; - httpc->async_data->inet_buffers.dwStructSize = sizeof(INTERNET_BUFFERSA); - httpc->async_data->inet_buffers.lpvBuffer = NULL; - httpc->async_data->destination_buffer = NULL; - InitializeCriticalSection(&httpc->async_data->cs); - return &httpc->common; -} - -typedef struct _HttpTimerThreadData -{ - PVOID timer_param; - DWORD *last_sent_time; - HANDLE timer_cancelled; -} HttpTimerThreadData; - -static VOID rpcrt4_http_keep_connection_active_timer_proc(PVOID param, BOOLEAN dummy) -{ - HINTERNET in_request = param; - RpcPktHdr *idle_pkt; - - idle_pkt = RPCRT4_BuildHttpHeader(NDR_LOCAL_DATA_REPRESENTATION, 0x0001, - 0, 0); - if (idle_pkt) - { - DWORD bytes_written; - InternetWriteFile(in_request, idle_pkt, idle_pkt->common.frag_len, &bytes_written); - RPCRT4_FreeHeader(idle_pkt); - } -} - -static inline DWORD rpcrt4_http_timer_calc_timeout(DWORD *last_sent_time) -{ - DWORD cur_time = GetTickCount(); - DWORD cached_last_sent_time = *last_sent_time; - return HTTP_IDLE_TIME - (cur_time - cached_last_sent_time > HTTP_IDLE_TIME ? 0 : cur_time - cached_last_sent_time); -} - -static DWORD CALLBACK rpcrt4_http_timer_thread(PVOID param) -{ - HttpTimerThreadData *data_in = param; - HttpTimerThreadData data; - DWORD timeout; - - data = *data_in; - HeapFree(GetProcessHeap(), 0, data_in); - - for (timeout = HTTP_IDLE_TIME; - WaitForSingleObject(data.timer_cancelled, timeout) == WAIT_TIMEOUT; - timeout = rpcrt4_http_timer_calc_timeout(data.last_sent_time)) - { - /* are we too soon after last send? */ - if (GetTickCount() - HTTP_IDLE_TIME < *data.last_sent_time) - continue; - rpcrt4_http_keep_connection_active_timer_proc(data.timer_param, TRUE); - } - - CloseHandle(data.timer_cancelled); - return 0; -} - -static VOID WINAPI rpcrt4_http_internet_callback( - HINTERNET hInternet, - DWORD_PTR dwContext, - DWORD dwInternetStatus, - LPVOID lpvStatusInformation, - DWORD dwStatusInformationLength) -{ - RpcHttpAsyncData *async_data = (RpcHttpAsyncData *)dwContext; - - switch (dwInternetStatus) - { - case INTERNET_STATUS_REQUEST_COMPLETE: - TRACE("INTERNET_STATUS_REQUEST_COMPLETED\n"); - if (async_data) - { - if (async_data->inet_buffers.lpvBuffer) - { - EnterCriticalSection(&async_data->cs); - if (async_data->destination_buffer) - { - memcpy(async_data->destination_buffer, - async_data->inet_buffers.lpvBuffer, - async_data->inet_buffers.dwBufferLength); - async_data->destination_buffer = NULL; - } - LeaveCriticalSection(&async_data->cs); - } - HeapFree(GetProcessHeap(), 0, async_data->inet_buffers.lpvBuffer); - async_data->inet_buffers.lpvBuffer = NULL; - SetEvent(async_data->completion_event); - RpcHttpAsyncData_Release(async_data); - } - break; - } -} - -static RPC_STATUS rpcrt4_http_check_response(HINTERNET hor) -{ - BOOL ret; - DWORD status_code; - DWORD size; - DWORD index; - WCHAR buf[32]; - WCHAR *status_text = buf; - TRACE("\n"); - - index = 0; - size = sizeof(status_code); - ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status_code, &size, &index); - if (!ret) - return GetLastError(); - if (status_code < 400) - return RPC_S_OK; - index = 0; - size = sizeof(buf); - ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_TEXT, status_text, &size, &index); - if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - status_text = HeapAlloc(GetProcessHeap(), 0, size); - ret = HttpQueryInfoW(hor, HTTP_QUERY_STATUS_TEXT, status_text, &size, &index); - } - - ERR("server returned: %d %s\n", status_code, ret ? debugstr_w(status_text) : ""); - if(status_text != buf) HeapFree(GetProcessHeap(), 0, status_text); - - if (status_code == HTTP_STATUS_DENIED) - return ERROR_ACCESS_DENIED; - return RPC_S_SERVER_UNAVAILABLE; -} - -static RPC_STATUS rpcrt4_http_internet_connect(RpcConnection_http *httpc) -{ - static const WCHAR wszUserAgent[] = {'M','S','R','P','C',0}; - LPWSTR proxy = NULL; - LPWSTR user = NULL; - LPWSTR password = NULL; - LPWSTR servername = NULL; - const WCHAR *option; - INTERNET_PORT port = INTERNET_INVALID_PORT_NUMBER; /* use default port */ - - if (httpc->common.QOS && - (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP)) - { - const RPC_HTTP_TRANSPORT_CREDENTIALS_W *http_cred = httpc->common.QOS->qos->u.HttpCredentials; - if (http_cred->TransportCredentials) - { - WCHAR *p; - const SEC_WINNT_AUTH_IDENTITY_W *cred = http_cred->TransportCredentials; - ULONG len = cred->DomainLength + 1 + cred->UserLength; - user = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); - if (!user) - return RPC_S_OUT_OF_RESOURCES; - p = user; - if (cred->DomainLength) - { - memcpy(p, cred->Domain, cred->DomainLength * sizeof(WCHAR)); - p += cred->DomainLength; - *p = '\\'; - p++; - } - memcpy(p, cred->User, cred->UserLength * sizeof(WCHAR)); - p[cred->UserLength] = 0; - - password = RPCRT4_strndupW(cred->Password, cred->PasswordLength); - } - } - - for (option = httpc->common.NetworkOptions; option; - option = (strchrW(option, ',') ? strchrW(option, ',')+1 : NULL)) - { - static const WCHAR wszRpcProxy[] = {'R','p','c','P','r','o','x','y','=',0}; - static const WCHAR wszHttpProxy[] = {'H','t','t','p','P','r','o','x','y','=',0}; - - if (!strncmpiW(option, wszRpcProxy, sizeof(wszRpcProxy)/sizeof(wszRpcProxy[0])-1)) - { - const WCHAR *value_start = option + sizeof(wszRpcProxy)/sizeof(wszRpcProxy[0])-1; - const WCHAR *value_end; - const WCHAR *p; - - value_end = strchrW(option, ','); - if (!value_end) - value_end = value_start + strlenW(value_start); - for (p = value_start; p < value_end; p++) - if (*p == ':') - { - port = atoiW(p+1); - value_end = p; - break; - } - TRACE("RpcProxy value is %s\n", debugstr_wn(value_start, value_end-value_start)); - servername = RPCRT4_strndupW(value_start, value_end-value_start); - } - else if (!strncmpiW(option, wszHttpProxy, sizeof(wszHttpProxy)/sizeof(wszHttpProxy[0])-1)) - { - const WCHAR *value_start = option + sizeof(wszHttpProxy)/sizeof(wszHttpProxy[0])-1; - const WCHAR *value_end; - - value_end = strchrW(option, ','); - if (!value_end) - value_end = value_start + strlenW(value_start); - TRACE("HttpProxy value is %s\n", debugstr_wn(value_start, value_end-value_start)); - proxy = RPCRT4_strndupW(value_start, value_end-value_start); - } - else - FIXME("unhandled option %s\n", debugstr_w(option)); - } - - httpc->app_info = InternetOpenW(wszUserAgent, proxy ? INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_PRECONFIG, - NULL, NULL, INTERNET_FLAG_ASYNC); - if (!httpc->app_info) - { - HeapFree(GetProcessHeap(), 0, password); - HeapFree(GetProcessHeap(), 0, user); - ERR("InternetOpenW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - InternetSetStatusCallbackW(httpc->app_info, rpcrt4_http_internet_callback); - - /* if no RpcProxy option specified, set the HTTP server address to the - * RPC server address */ - if (!servername) - { - servername = HeapAlloc(GetProcessHeap(), 0, (strlen(httpc->common.NetworkAddr) + 1)*sizeof(WCHAR)); - if (!servername) - { - HeapFree(GetProcessHeap(), 0, password); - HeapFree(GetProcessHeap(), 0, user); - return RPC_S_OUT_OF_RESOURCES; - } - MultiByteToWideChar(CP_ACP, 0, httpc->common.NetworkAddr, -1, servername, strlen(httpc->common.NetworkAddr) + 1); - } - - httpc->session = InternetConnectW(httpc->app_info, servername, port, user, password, - INTERNET_SERVICE_HTTP, 0, 0); - - HeapFree(GetProcessHeap(), 0, password); - HeapFree(GetProcessHeap(), 0, user); - HeapFree(GetProcessHeap(), 0, servername); - - if (!httpc->session) - { - ERR("InternetConnectW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - - return RPC_S_OK; -} - -/* prepare the in pipe for use by RPC packets */ -static RPC_STATUS rpcrt4_http_prepare_in_pipe(HINTERNET in_request, RpcHttpAsyncData *async_data, - const UUID *connection_uuid, - const UUID *in_pipe_uuid, - const UUID *association_uuid) -{ - BYTE packet[44]; - BOOL ret; - RPC_STATUS status; - RpcPktHdr *hdr; - INTERNET_BUFFERSW buffers_in; - DWORD bytes_read, bytes_written; - - /* prepare in pipe */ - ResetEvent(async_data->completion_event); - RpcHttpAsyncData_AddRef(async_data); - ret = HttpSendRequestW(in_request, NULL, 0, NULL, 0); - if (!ret) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(async_data->completion_event, INFINITE); - else - { - RpcHttpAsyncData_Release(async_data); - ERR("HttpSendRequestW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - } - status = rpcrt4_http_check_response(in_request); - if (status != RPC_S_OK) return status; - - InternetReadFile(in_request, packet, 20, &bytes_read); - /* FIXME: do something with retrieved data */ - - memset(&buffers_in, 0, sizeof(buffers_in)); - buffers_in.dwStructSize = sizeof(buffers_in); - /* FIXME: get this from the registry */ - buffers_in.dwBufferTotal = 1024 * 1024 * 1024; /* 1Gb */ - ResetEvent(async_data->completion_event); - RpcHttpAsyncData_AddRef(async_data); - ret = HttpSendRequestExW(in_request, &buffers_in, NULL, 0, 0); - if (!ret) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(async_data->completion_event, INFINITE); - else - { - RpcHttpAsyncData_Release(async_data); - ERR("HttpSendRequestExW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - } - - TRACE("sending HTTP connect header to server\n"); - hdr = RPCRT4_BuildHttpConnectHeader(0, FALSE, connection_uuid, in_pipe_uuid, association_uuid); - if (!hdr) return RPC_S_OUT_OF_RESOURCES; - ret = InternetWriteFile(in_request, hdr, hdr->common.frag_len, &bytes_written); - RPCRT4_FreeHeader(hdr); - if (!ret) - { - ERR("InternetWriteFile failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - - return RPC_S_OK; -} - -static RPC_STATUS rpcrt4_http_read_http_packet(HINTERNET request, RpcPktHdr *hdr, BYTE **data) -{ - BOOL ret; - DWORD bytes_read; - unsigned short data_len; - - ret = InternetReadFile(request, hdr, sizeof(hdr->common), &bytes_read); - if (!ret) - return RPC_S_SERVER_UNAVAILABLE; - if (hdr->common.ptype != PKT_HTTP || hdr->common.frag_len < sizeof(hdr->http)) - { - ERR("wrong packet type received %d or wrong frag_len %d\n", - hdr->common.ptype, hdr->common.frag_len); - return RPC_S_PROTOCOL_ERROR; - } - - ret = InternetReadFile(request, &hdr->common + 1, sizeof(hdr->http) - sizeof(hdr->common), &bytes_read); - if (!ret) - return RPC_S_SERVER_UNAVAILABLE; - - data_len = hdr->common.frag_len - sizeof(hdr->http); - if (data_len) - { - *data = HeapAlloc(GetProcessHeap(), 0, data_len); - if (!*data) - return RPC_S_OUT_OF_RESOURCES; - ret = InternetReadFile(request, *data, data_len, &bytes_read); - if (!ret) - { - HeapFree(GetProcessHeap(), 0, *data); - return RPC_S_SERVER_UNAVAILABLE; - } - } - else - *data = NULL; - - if (!RPCRT4_IsValidHttpPacket(hdr, *data, data_len)) - { - ERR("invalid http packet\n"); - return RPC_S_PROTOCOL_ERROR; - } - - return RPC_S_OK; -} - -/* prepare the out pipe for use by RPC packets */ -static RPC_STATUS rpcrt4_http_prepare_out_pipe(HINTERNET out_request, - RpcHttpAsyncData *async_data, - const UUID *connection_uuid, - const UUID *out_pipe_uuid, - ULONG *flow_control_increment) -{ - BYTE packet[20]; - BOOL ret; - RPC_STATUS status; - RpcPktHdr *hdr; - DWORD bytes_read; - BYTE *data_from_server; - RpcPktHdr pkt_from_server; - ULONG field1, field3; - - ResetEvent(async_data->completion_event); - RpcHttpAsyncData_AddRef(async_data); - ret = HttpSendRequestW(out_request, NULL, 0, NULL, 0); - if (!ret) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(async_data->completion_event, INFINITE); - else - { - RpcHttpAsyncData_Release(async_data); - ERR("HttpSendRequestW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - } - status = rpcrt4_http_check_response(out_request); - if (status != RPC_S_OK) return status; - - InternetReadFile(out_request, packet, 20, &bytes_read); - /* FIXME: do something with retrieved data */ - - hdr = RPCRT4_BuildHttpConnectHeader(0, TRUE, connection_uuid, out_pipe_uuid, NULL); - if (!hdr) return RPC_S_OUT_OF_RESOURCES; - ResetEvent(async_data->completion_event); - RpcHttpAsyncData_AddRef(async_data); - ret = HttpSendRequestW(out_request, NULL, 0, hdr, hdr->common.frag_len); - if (!ret) - { - if (GetLastError() == ERROR_IO_PENDING) - WaitForSingleObject(async_data->completion_event, INFINITE); - else - { - RpcHttpAsyncData_Release(async_data); - ERR("HttpSendRequestW failed with error %d\n", GetLastError()); - RPCRT4_FreeHeader(hdr); - return RPC_S_SERVER_UNAVAILABLE; - } - } - RPCRT4_FreeHeader(hdr); - status = rpcrt4_http_check_response(out_request); - if (status != RPC_S_OK) return status; - - status = rpcrt4_http_read_http_packet(out_request, &pkt_from_server, - &data_from_server); - if (status != RPC_S_OK) return status; - status = RPCRT4_ParseHttpPrepareHeader1(&pkt_from_server, data_from_server, - &field1); - HeapFree(GetProcessHeap(), 0, data_from_server); - if (status != RPC_S_OK) return status; - TRACE("received (%d) from first prepare header\n", field1); - - status = rpcrt4_http_read_http_packet(out_request, &pkt_from_server, - &data_from_server); - if (status != RPC_S_OK) return status; - status = RPCRT4_ParseHttpPrepareHeader2(&pkt_from_server, data_from_server, - &field1, flow_control_increment, - &field3); - HeapFree(GetProcessHeap(), 0, data_from_server); - if (status != RPC_S_OK) return status; - TRACE("received (0x%08x 0x%08x %d) from second prepare header\n", field1, *flow_control_increment, field3); - - return RPC_S_OK; -} - -static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection) -{ - RpcConnection_http *httpc = (RpcConnection_http *)Connection; - static const WCHAR wszVerbIn[] = {'R','P','C','_','I','N','_','D','A','T','A',0}; - static const WCHAR wszVerbOut[] = {'R','P','C','_','O','U','T','_','D','A','T','A',0}; - static const WCHAR wszRpcProxyPrefix[] = {'/','r','p','c','/','r','p','c','p','r','o','x','y','.','d','l','l','?',0}; - static const WCHAR wszColon[] = {':',0}; - static const WCHAR wszAcceptType[] = {'a','p','p','l','i','c','a','t','i','o','n','/','r','p','c',0}; - LPCWSTR wszAcceptTypes[] = { wszAcceptType, NULL }; - WCHAR *url; - RPC_STATUS status; - BOOL secure; - HttpTimerThreadData *timer_data; - HANDLE thread; - - TRACE("(%s, %s)\n", Connection->NetworkAddr, Connection->Endpoint); - - if (Connection->server) - { - ERR("ncacn_http servers not supported yet\n"); - return RPC_S_SERVER_UNAVAILABLE; - } - - if (httpc->in_request) - return RPC_S_OK; - - httpc->async_data->completion_event = CreateEventW(NULL, FALSE, FALSE, NULL); - - status = UuidCreate(&httpc->connection_uuid); - status = UuidCreate(&httpc->in_pipe_uuid); - status = UuidCreate(&httpc->out_pipe_uuid); - - status = rpcrt4_http_internet_connect(httpc); - if (status != RPC_S_OK) - return status; - - url = HeapAlloc(GetProcessHeap(), 0, sizeof(wszRpcProxyPrefix) + (strlen(Connection->NetworkAddr) + 1 + strlen(Connection->Endpoint))*sizeof(WCHAR)); - if (!url) - return RPC_S_OUT_OF_MEMORY; - memcpy(url, wszRpcProxyPrefix, sizeof(wszRpcProxyPrefix)); - MultiByteToWideChar(CP_ACP, 0, Connection->NetworkAddr, -1, url+sizeof(wszRpcProxyPrefix)/sizeof(wszRpcProxyPrefix[0])-1, strlen(Connection->NetworkAddr)+1); - strcatW(url, wszColon); - MultiByteToWideChar(CP_ACP, 0, Connection->Endpoint, -1, url+strlenW(url), strlen(Connection->Endpoint)+1); - - secure = httpc->common.QOS && - (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) && - (httpc->common.QOS->qos->u.HttpCredentials->Flags & RPC_C_HTTP_FLAG_USE_SSL); - - httpc->in_request = HttpOpenRequestW(httpc->session, wszVerbIn, url, NULL, NULL, - wszAcceptTypes, - (secure ? INTERNET_FLAG_SECURE : 0)|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE, - (DWORD_PTR)httpc->async_data); - if (!httpc->in_request) - { - ERR("HttpOpenRequestW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - httpc->out_request = HttpOpenRequestW(httpc->session, wszVerbOut, url, NULL, NULL, - wszAcceptTypes, - (secure ? INTERNET_FLAG_SECURE : 0)|INTERNET_FLAG_KEEP_CONNECTION|INTERNET_FLAG_PRAGMA_NOCACHE, - (DWORD_PTR)httpc->async_data); - if (!httpc->out_request) - { - ERR("HttpOpenRequestW failed with error %d\n", GetLastError()); - return RPC_S_SERVER_UNAVAILABLE; - } - - status = rpcrt4_http_prepare_in_pipe(httpc->in_request, - httpc->async_data, - &httpc->connection_uuid, - &httpc->in_pipe_uuid, - &Connection->assoc->http_uuid); - if (status != RPC_S_OK) - return status; - - status = rpcrt4_http_prepare_out_pipe(httpc->out_request, - httpc->async_data, - &httpc->connection_uuid, - &httpc->out_pipe_uuid, - &httpc->flow_control_increment); - if (status != RPC_S_OK) - return status; - - httpc->flow_control_mark = httpc->flow_control_increment / 2; - httpc->last_sent_time = GetTickCount(); - httpc->timer_cancelled = CreateEventW(NULL, FALSE, FALSE, NULL); - - timer_data = HeapAlloc(GetProcessHeap(), 0, sizeof(*timer_data)); - if (!timer_data) - return ERROR_OUTOFMEMORY; - timer_data->timer_param = httpc->in_request; - timer_data->last_sent_time = &httpc->last_sent_time; - timer_data->timer_cancelled = httpc->timer_cancelled; - /* FIXME: should use CreateTimerQueueTimer when implemented */ - thread = CreateThread(NULL, 0, rpcrt4_http_timer_thread, timer_data, 0, NULL); - if (!thread) - { - HeapFree(GetProcessHeap(), 0, timer_data); - return GetLastError(); - } - CloseHandle(thread); - - return RPC_S_OK; -} - -static RPC_STATUS rpcrt4_ncacn_http_handoff(RpcConnection *old_conn, RpcConnection *new_conn) -{ - assert(0); - return RPC_S_SERVER_UNAVAILABLE; -} - -static int rpcrt4_ncacn_http_read(RpcConnection *Connection, - void *buffer, unsigned int count) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - char *buf = buffer; - BOOL ret = TRUE; - unsigned int bytes_left = count; - - ResetEvent(httpc->async_data->completion_event); - while (bytes_left) - { - RpcHttpAsyncData_AddRef(httpc->async_data); - httpc->async_data->inet_buffers.dwBufferLength = bytes_left; - httpc->async_data->inet_buffers.lpvBuffer = HeapAlloc(GetProcessHeap(), 0, bytes_left); - httpc->async_data->destination_buffer = buf; - ret = InternetReadFileExA(httpc->out_request, &httpc->async_data->inet_buffers, IRF_ASYNC, 0); - if (ret) - { - /* INTERNET_STATUS_REQUEST_COMPLETED won't be sent, so release our - * async ref now */ - RpcHttpAsyncData_Release(httpc->async_data); - memcpy(buf, httpc->async_data->inet_buffers.lpvBuffer, - httpc->async_data->inet_buffers.dwBufferLength); - HeapFree(GetProcessHeap(), 0, httpc->async_data->inet_buffers.lpvBuffer); - httpc->async_data->inet_buffers.lpvBuffer = NULL; - httpc->async_data->destination_buffer = NULL; - } - else - { - if (GetLastError() == ERROR_IO_PENDING) - { - HANDLE handles[2] = { httpc->async_data->completion_event, httpc->cancel_event }; - DWORD result = WaitForMultipleObjects(2, handles, FALSE, DEFAULT_NCACN_HTTP_TIMEOUT); - if (result == WAIT_OBJECT_0) - ret = TRUE; - else - { - TRACE("call cancelled\n"); - EnterCriticalSection(&httpc->async_data->cs); - httpc->async_data->destination_buffer = NULL; - LeaveCriticalSection(&httpc->async_data->cs); - break; - } - } - else - { - HeapFree(GetProcessHeap(), 0, httpc->async_data->inet_buffers.lpvBuffer); - httpc->async_data->inet_buffers.lpvBuffer = NULL; - httpc->async_data->destination_buffer = NULL; - RpcHttpAsyncData_Release(httpc->async_data); - break; - } - } - if (!httpc->async_data->inet_buffers.dwBufferLength) - break; - bytes_left -= httpc->async_data->inet_buffers.dwBufferLength; - buf += httpc->async_data->inet_buffers.dwBufferLength; - } - TRACE("%p %p %u -> %s\n", httpc->out_request, buffer, count, ret ? "TRUE" : "FALSE"); - return ret ? count : -1; -} - -static RPC_STATUS rpcrt4_ncacn_http_receive_fragment(RpcConnection *Connection, RpcPktHdr **Header, void **Payload) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - RPC_STATUS status; - DWORD hdr_length; - LONG dwRead; - RpcPktCommonHdr common_hdr; - - *Header = NULL; - - TRACE("(%p, %p, %p)\n", Connection, Header, Payload); - -again: - /* read packet common header */ - dwRead = rpcrt4_ncacn_http_read(Connection, &common_hdr, sizeof(common_hdr)); - if (dwRead != sizeof(common_hdr)) { - WARN("Short read of header, %d bytes\n", dwRead); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - if (!memcmp(&common_hdr, "HTTP/1.1", sizeof("HTTP/1.1")) || - !memcmp(&common_hdr, "HTTP/1.0", sizeof("HTTP/1.0"))) - { - FIXME("server returned %s\n", debugstr_a((const char *)&common_hdr)); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - status = RPCRT4_ValidateCommonHeader(&common_hdr); - if (status != RPC_S_OK) goto fail; - - hdr_length = RPCRT4_GetHeaderSize((RpcPktHdr*)&common_hdr); - if (hdr_length == 0) { - WARN("header length == 0\n"); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - *Header = HeapAlloc(GetProcessHeap(), 0, hdr_length); - if (!*Header) - { - status = RPC_S_OUT_OF_RESOURCES; - goto fail; - } - memcpy(*Header, &common_hdr, sizeof(common_hdr)); - - /* read the rest of packet header */ - dwRead = rpcrt4_ncacn_http_read(Connection, &(*Header)->common + 1, hdr_length - sizeof(common_hdr)); - if (dwRead != hdr_length - sizeof(common_hdr)) { - WARN("bad header length, %d bytes, hdr_length %d\n", dwRead, hdr_length); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - - if (common_hdr.frag_len - hdr_length) - { - *Payload = HeapAlloc(GetProcessHeap(), 0, common_hdr.frag_len - hdr_length); - if (!*Payload) - { - status = RPC_S_OUT_OF_RESOURCES; - goto fail; - } - - dwRead = rpcrt4_ncacn_http_read(Connection, *Payload, common_hdr.frag_len - hdr_length); - if (dwRead != common_hdr.frag_len - hdr_length) - { - WARN("bad data length, %d/%d\n", dwRead, common_hdr.frag_len - hdr_length); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - } - else - *Payload = NULL; - - if ((*Header)->common.ptype == PKT_HTTP) - { - if (!RPCRT4_IsValidHttpPacket(*Header, *Payload, common_hdr.frag_len - hdr_length)) - { - ERR("invalid http packet of length %d bytes\n", (*Header)->common.frag_len); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - if ((*Header)->http.flags == 0x0001) - { - TRACE("http idle packet, waiting for real packet\n"); - if ((*Header)->http.num_data_items != 0) - { - ERR("HTTP idle packet should have no data items instead of %d\n", (*Header)->http.num_data_items); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - } - else if ((*Header)->http.flags == 0x0002) - { - ULONG bytes_transmitted; - ULONG flow_control_increment; - UUID pipe_uuid; - status = RPCRT4_ParseHttpFlowControlHeader(*Header, *Payload, - Connection->server, - &bytes_transmitted, - &flow_control_increment, - &pipe_uuid); - if (status != RPC_S_OK) - goto fail; - TRACE("received http flow control header (0x%x, 0x%x, %s)\n", - bytes_transmitted, flow_control_increment, debugstr_guid(&pipe_uuid)); - /* FIXME: do something with parsed data */ - } - else - { - FIXME("unrecognised http packet with flags 0x%04x\n", (*Header)->http.flags); - status = RPC_S_PROTOCOL_ERROR; - goto fail; - } - RPCRT4_FreeHeader(*Header); - *Header = NULL; - HeapFree(GetProcessHeap(), 0, *Payload); - *Payload = NULL; - goto again; - } - - /* success */ - status = RPC_S_OK; - - httpc->bytes_received += common_hdr.frag_len; - - TRACE("httpc->bytes_received = 0x%x\n", httpc->bytes_received); - - if (httpc->bytes_received > httpc->flow_control_mark) - { - RpcPktHdr *hdr = RPCRT4_BuildHttpFlowControlHeader(httpc->common.server, - httpc->bytes_received, - httpc->flow_control_increment, - &httpc->out_pipe_uuid); - if (hdr) - { - DWORD bytes_written; - BOOL ret2; - TRACE("sending flow control packet at 0x%x\n", httpc->bytes_received); - ret2 = InternetWriteFile(httpc->in_request, hdr, hdr->common.frag_len, &bytes_written); - RPCRT4_FreeHeader(hdr); - if (ret2) - httpc->flow_control_mark = httpc->bytes_received + httpc->flow_control_increment / 2; - } - } - -fail: - if (status != RPC_S_OK) { - RPCRT4_FreeHeader(*Header); - *Header = NULL; - HeapFree(GetProcessHeap(), 0, *Payload); - *Payload = NULL; - } - return status; -} - -static int rpcrt4_ncacn_http_write(RpcConnection *Connection, - const void *buffer, unsigned int count) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - DWORD bytes_written; - BOOL ret; - - httpc->last_sent_time = ~0U; /* disable idle packet sending */ - ret = InternetWriteFile(httpc->in_request, buffer, count, &bytes_written); - httpc->last_sent_time = GetTickCount(); - TRACE("%p %p %u -> %s\n", httpc->in_request, buffer, count, ret ? "TRUE" : "FALSE"); - return ret ? bytes_written : -1; -} - -static int rpcrt4_ncacn_http_close(RpcConnection *Connection) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - - TRACE("\n"); - - SetEvent(httpc->timer_cancelled); - if (httpc->in_request) - InternetCloseHandle(httpc->in_request); - httpc->in_request = NULL; - if (httpc->out_request) - InternetCloseHandle(httpc->out_request); - httpc->out_request = NULL; - if (httpc->app_info) - InternetCloseHandle(httpc->app_info); - httpc->app_info = NULL; - if (httpc->session) - InternetCloseHandle(httpc->session); - httpc->session = NULL; - RpcHttpAsyncData_Release(httpc->async_data); - if (httpc->cancel_event) - CloseHandle(httpc->cancel_event); - - return 0; -} - -static void rpcrt4_ncacn_http_cancel_call(RpcConnection *Connection) -{ - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - - SetEvent(httpc->cancel_event); -} - -static int rpcrt4_ncacn_http_wait_for_incoming_data(RpcConnection *Connection) -{ - BOOL ret; - RpcConnection_http *httpc = (RpcConnection_http *) Connection; - - RpcHttpAsyncData_AddRef(httpc->async_data); - ret = InternetQueryDataAvailable(httpc->out_request, - &httpc->async_data->inet_buffers.dwBufferLength, IRF_ASYNC, 0); - if (ret) - { - /* INTERNET_STATUS_REQUEST_COMPLETED won't be sent, so release our - * async ref now */ - RpcHttpAsyncData_Release(httpc->async_data); - } - else - { - if (GetLastError() == ERROR_IO_PENDING) - { - HANDLE handles[2] = { httpc->async_data->completion_event, httpc->cancel_event }; - DWORD result = WaitForMultipleObjects(2, handles, FALSE, DEFAULT_NCACN_HTTP_TIMEOUT); - if (result != WAIT_OBJECT_0) - { - TRACE("call cancelled\n"); - return -1; - } - } - else - { - RpcHttpAsyncData_Release(httpc->async_data); - return -1; - } - } - - /* success */ - return 0; -} - -static size_t rpcrt4_ncacn_http_get_top_of_tower(unsigned char *tower_data, - const char *networkaddr, - const char *endpoint) -{ - return rpcrt4_ip_tcp_get_top_of_tower(tower_data, networkaddr, - EPM_PROTOCOL_HTTP, endpoint); -} - -static RPC_STATUS rpcrt4_ncacn_http_parse_top_of_tower(const unsigned char *tower_data, - size_t tower_size, - char **networkaddr, - char **endpoint) -{ - return rpcrt4_ip_tcp_parse_top_of_tower(tower_data, tower_size, - networkaddr, EPM_PROTOCOL_HTTP, - endpoint); -} -#endif static const struct connection_ops conn_protseq_list[] = { { "ncacn_np", { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_SMB }, @@ -2691,7 +1413,6 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_wait_for_incoming_data, rpcrt4_ncacn_np_get_top_of_tower, rpcrt4_ncacn_np_parse_top_of_tower, - NULL, }, { "ncalrpc", { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE }, @@ -2705,8 +1426,8 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_np_wait_for_incoming_data, rpcrt4_ncalrpc_get_top_of_tower, rpcrt4_ncalrpc_parse_top_of_tower, - NULL, }, +#ifdef HAVE_SOCKETPAIR { "ncacn_ip_tcp", { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP }, rpcrt4_conn_tcp_alloc, @@ -2719,23 +1440,7 @@ static const struct connection_ops conn_protseq_list[] = { rpcrt4_conn_tcp_wait_for_incoming_data, rpcrt4_ncacn_ip_tcp_get_top_of_tower, rpcrt4_ncacn_ip_tcp_parse_top_of_tower, - NULL, - }, -#if 0 - { "ncacn_http", - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP }, - rpcrt4_ncacn_http_alloc, - rpcrt4_ncacn_http_open, - rpcrt4_ncacn_http_handoff, - rpcrt4_ncacn_http_read, - rpcrt4_ncacn_http_write, - rpcrt4_ncacn_http_close, - rpcrt4_ncacn_http_cancel_call, - rpcrt4_ncacn_http_wait_for_incoming_data, - rpcrt4_ncacn_http_get_top_of_tower, - rpcrt4_ncacn_http_parse_top_of_tower, - rpcrt4_ncacn_http_receive_fragment, - }, + } #endif }; @@ -2760,6 +1465,7 @@ static const struct protseq_ops protseq_list[] = rpcrt4_protseq_np_wait_for_new_connection, rpcrt4_protseq_ncalrpc_open_endpoint, }, +#ifdef HAVE_SOCKETPAIR { "ncacn_ip_tcp", rpcrt4_protseq_sock_alloc, @@ -2769,6 +1475,7 @@ static const struct protseq_ops protseq_list[] = rpcrt4_protseq_sock_wait_for_new_connection, rpcrt4_protseq_ncacn_ip_tcp_open_endpoint, }, +#endif }; #define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) @@ -2817,7 +1524,6 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, LPCSTR Protseq, LPCSTR NetworkAddr, LPCSTR Endpoint, LPCWSTR NetworkOptions, RpcAuthInfo* AuthInfo, RpcQualityOfService *QOS) { - static LONG next_id; const struct connection_ops *ops; RpcConnection* NewConnection; @@ -2845,7 +1551,6 @@ RPC_STATUS RPCRT4_CreateConnection(RpcConnection** Connection, BOOL server, NewConnection->attr = 0; if (AuthInfo) RpcAuthInfo_AddRef(AuthInfo); NewConnection->AuthInfo = AuthInfo; - NewConnection->auth_context_id = InterlockedIncrement( &next_id ); NewConnection->encryption_auth_len = 0; NewConnection->signature_auth_len = 0; if (QOS) RpcQualityOfService_AddRef(QOS); diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild index 59f9fe29ea4..67f05aebcfb 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.rbuild +++ b/reactos/dll/win32/rpcrt4/rpcrt4.rbuild @@ -14,7 +14,6 @@ user32 advapi32 secur32 - iphlpapi ws2_32 ntdll diff --git a/reactos/dll/win32/rpcrt4/rpcrt4.spec b/reactos/dll/win32/rpcrt4/rpcrt4.spec index 0a047691822..4550889f62a 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4.spec +++ b/reactos/dll/win32/rpcrt4/rpcrt4.spec @@ -116,9 +116,8 @@ @ stdcall NDRSContextUnmarshallEx(ptr ptr ptr) @ stub NDRcopy @ stdcall NdrAllocate(ptr long) -@ varargs NdrAsyncClientCall(ptr ptr) +@ stub NdrAsyncClientCall @ stub NdrAsyncServerCall -@ stdcall NdrAsyncStubCall(ptr ptr ptr ptr) @ stdcall NdrByteCountPointerBufferSize(ptr ptr ptr) @ stdcall NdrByteCountPointerFree(ptr ptr ptr) @ stdcall NdrByteCountPointerMarshall(ptr ptr ptr) @@ -371,7 +370,7 @@ @ stdcall RpcEpRegisterA(ptr ptr ptr str) @ stub RpcEpRegisterNoReplaceA @ stub RpcEpRegisterNoReplaceW -@ stdcall RpcEpRegisterW(ptr ptr ptr wstr) +@ stub RpcEpRegisterW @ stdcall RpcEpResolveBinding(ptr ptr) @ stdcall RpcEpUnregister(ptr ptr ptr) @ stub RpcErrorAddRecord # wxp diff --git a/reactos/dll/win32/rpcrt4/rpcrt4_main.c b/reactos/dll/win32/rpcrt4/rpcrt4_main.c index 2cc7429bf29..537a00537bc 100644 --- a/reactos/dll/win32/rpcrt4/rpcrt4_main.c +++ b/reactos/dll/win32/rpcrt4/rpcrt4_main.c @@ -43,10 +43,8 @@ #include "winuser.h" #include "winnt.h" #include "winternl.h" -#define _NTDEF_ -typedef NTSTATUS *PNTSTATUS; -#include "ntsecapi.h" -#undef _NTDEF_ +#include "iptypes.h" +#include "iphlpapi.h" #include "wine/unicode.h" #include "rpc.h" @@ -55,7 +53,6 @@ typedef NTSTATUS *PNTSTATUS; #include "rpcproxy.h" #include "rpc_binding.h" -#include "rpc_server.h" #include "wine/debug.h" @@ -63,6 +60,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(rpc); static UUID uuid_nil; +static CRITICAL_SECTION uuid_cs; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &uuid_cs, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": uuid_cs") } +}; +static CRITICAL_SECTION uuid_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; + static CRITICAL_SECTION threaddata_cs; static CRITICAL_SECTION_DEBUG threaddata_cs_debug = { @@ -129,7 +135,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) break; case DLL_PROCESS_DETACH: - RPCRT4_destroy_all_protseqs(); break; } @@ -275,6 +280,61 @@ RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid) return RPC_S_OK; } +/* Number of 100ns ticks per clock tick. To be safe, assume that the clock + resolution is at least 1000 * 100 * (1/1000000) = 1/10 of a second */ +#define TICKS_PER_CLOCK_TICK 1000 +#define SECSPERDAY 86400 +#define TICKSPERSEC 10000000 +/* UUID system time starts at October 15, 1582 */ +#define SECS_15_OCT_1582_TO_1601 ((17 + 30 + 31 + 365 * 18 + 5) * SECSPERDAY) +#define TICKS_15_OCT_1582_TO_1601 ((ULONGLONG)SECS_15_OCT_1582_TO_1601 * TICKSPERSEC) + +static void RPC_UuidGetSystemTime(ULONGLONG *time) +{ + FILETIME ft; + + GetSystemTimeAsFileTime(&ft); + + *time = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime; + *time += TICKS_15_OCT_1582_TO_1601; +} + +/* Assume that a hardware address is at least 6 bytes long */ +#define ADDRESS_BYTES_NEEDED 6 + +static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) +{ + int i; + DWORD status = RPC_S_OK; + + ULONG buflen = sizeof(IP_ADAPTER_INFO); + PIP_ADAPTER_INFO adapter = HeapAlloc(GetProcessHeap(), 0, buflen); + + if (GetAdaptersInfo(adapter, &buflen) == ERROR_BUFFER_OVERFLOW) { + HeapFree(GetProcessHeap(), 0, adapter); + adapter = HeapAlloc(GetProcessHeap(), 0, buflen); + } + + if (GetAdaptersInfo(adapter, &buflen) == NO_ERROR) { + for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { + address[i] = adapter->Address[i]; + } + } + /* We can't get a hardware address, just use random numbers. + Set the multicast bit to prevent conflicts with real cards. */ + else { + for (i = 0; i < ADDRESS_BYTES_NEEDED; i++) { + address[i] = rand() & 0xff; + } + + address[0] |= 0x01; + status = RPC_S_UUID_LOCAL_ONLY; + } + + HeapFree(GetProcessHeap(), 0, adapter); + return status; +} + /************************************************************************* * UuidCreate [RPCRT4.@] * @@ -285,26 +345,83 @@ RPC_STATUS WINAPI UuidCreateNil(UUID *Uuid) * RPC_S_OK if successful. * RPC_S_UUID_LOCAL_ONLY if UUID is only locally unique. * - * NOTES - * - * Follows RFC 4122, section 4.4 (Algorithms for Creating a UUID from - * Truly Random or Pseudo-Random Numbers) + * FIXME: No compensation for changes across reloading + * this dll or across reboots (e.g. clock going + * backwards and swapped network cards). The RFC + * suggests using NVRAM for storing persistent + * values. */ RPC_STATUS WINAPI UuidCreate(UUID *Uuid) { - RtlGenRandom(Uuid, sizeof(*Uuid)); - /* Clear the version bits and set the version (4) */ - Uuid->Data3 &= 0x0fff; - Uuid->Data3 |= (4 << 12); - /* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as - * specified in RFC 4122, section 4.4. - */ - Uuid->Data4[0] &= 0x3f; - Uuid->Data4[0] |= 0x80; + static int initialised, count; + + ULONGLONG time; + static ULONGLONG timelast; + static WORD sequence; + + static DWORD status; + static BYTE address[MAX_ADAPTER_ADDRESS_LENGTH]; + + EnterCriticalSection(&uuid_cs); + + if (!initialised) { + RPC_UuidGetSystemTime(&timelast); + count = TICKS_PER_CLOCK_TICK; + + sequence = ((rand() & 0xff) << 8) + (rand() & 0xff); + sequence &= 0x1fff; + + status = RPC_UuidGetNodeAddress(address); + initialised = 1; + } + + /* Generate time element of the UUID. Account for going faster + than our clock as well as the clock going backwards. */ + while (1) { + RPC_UuidGetSystemTime(&time); + if (time > timelast) { + count = 0; + break; + } + if (time < timelast) { + sequence = (sequence + 1) & 0x1fff; + count = 0; + break; + } + if (count < TICKS_PER_CLOCK_TICK) { + count++; + break; + } + } + + timelast = time; + time += count; + + /* Pack the information into the UUID structure. */ + + Uuid->Data1 = (unsigned long)(time & 0xffffffff); + Uuid->Data2 = (unsigned short)((time >> 32) & 0xffff); + Uuid->Data3 = (unsigned short)((time >> 48) & 0x0fff); + + /* This is a version 1 UUID */ + Uuid->Data3 |= (1 << 12); + + Uuid->Data4[0] = sequence & 0xff; + Uuid->Data4[1] = (sequence & 0x3f00) >> 8; + Uuid->Data4[1] |= 0x80; + + Uuid->Data4[2] = address[0]; + Uuid->Data4[3] = address[1]; + Uuid->Data4[4] = address[2]; + Uuid->Data4[5] = address[3]; + Uuid->Data4[6] = address[4]; + Uuid->Data4[7] = address[5]; + + LeaveCriticalSection(&uuid_cs); TRACE("%s\n", debugstr_guid(Uuid)); - return RPC_S_OK; + return status; } /************************************************************************* From 212d5ee24e37ad44c8083d768b46e97eec0d47d8 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 28 Nov 2009 14:45:21 +0000 Subject: [PATCH 094/140] - Revert the oskit locking rewrite in trunk, it's better to test/debug it in the branch first. Reverted revisions numbers: 44268, 44267, 44266, 44250, 44199, 44166-163, 44021, 44010, 43926, 43922, 43883. svn path=/trunk/; revision=44301 --- reactos/drivers/network/tcpip/datalink/lan.c | 34 +- .../drivers/network/tcpip/include/address.h | 1 + .../drivers/network/tcpip/include/datagram.h | 2 +- reactos/drivers/network/tcpip/include/debug.h | 2 + .../drivers/network/tcpip/include/dispatch.h | 2 - .../drivers/network/tcpip/include/fileobjs.h | 3 + reactos/drivers/network/tcpip/include/ip.h | 3 + reactos/drivers/network/tcpip/include/irp.h | 13 + reactos/drivers/network/tcpip/include/lock.h | 4 + .../drivers/network/tcpip/include/memtrack.h | 79 +++ .../drivers/network/tcpip/include/neighbor.h | 1 + .../drivers/network/tcpip/include/precomp.h | 4 +- .../drivers/network/tcpip/include/routines.h | 7 +- reactos/drivers/network/tcpip/include/tags.h | 39 -- reactos/drivers/network/tcpip/include/tcp.h | 21 +- .../drivers/network/tcpip/include/titypes.h | 40 +- .../drivers/network/tcpip/recmutex/recmutex.c | 61 ++ .../drivers/network/tcpip/recmutex/recmutex.h | 21 + reactos/drivers/network/tcpip/tcpip.rbuild | 4 + reactos/drivers/network/tcpip/tcpip/ainfo.c | 5 - reactos/drivers/network/tcpip/tcpip/buffer.c | 30 +- .../drivers/network/tcpip/tcpip/dispatch.c | 216 +++--- .../drivers/network/tcpip/tcpip/fileobjs.c | 105 ++- reactos/drivers/network/tcpip/tcpip/iinfo.c | 8 +- reactos/drivers/network/tcpip/tcpip/irp.c | 37 + reactos/drivers/network/tcpip/tcpip/lock.c | 13 + reactos/drivers/network/tcpip/tcpip/main.c | 206 ++++-- .../drivers/network/tcpip/tcpip/mocklock.c | 9 + reactos/drivers/network/tcpip/tcpip/ninfo.c | 16 +- reactos/lib/drivers/ip/ip.rbuild | 1 + reactos/lib/drivers/ip/network/address.c | 2 +- reactos/lib/drivers/ip/network/ip.c | 29 +- reactos/lib/drivers/ip/network/memtrack.c | 153 ++++ reactos/lib/drivers/ip/network/neighbor.c | 20 +- reactos/lib/drivers/ip/network/ports.c | 5 +- reactos/lib/drivers/ip/network/receive.c | 30 +- reactos/lib/drivers/ip/network/router.c | 6 +- reactos/lib/drivers/ip/network/routines.c | 4 +- reactos/lib/drivers/ip/network/transmit.c | 12 +- .../drivers/ip/transport/datagram/datagram.c | 120 ++-- .../lib/drivers/ip/transport/rawip/rawip.c | 13 - reactos/lib/drivers/ip/transport/tcp/accept.c | 31 +- reactos/lib/drivers/ip/transport/tcp/event.c | 126 +++- reactos/lib/drivers/ip/transport/tcp/if.c | 4 + reactos/lib/drivers/ip/transport/tcp/tcp.c | 658 +++++++++--------- reactos/lib/drivers/ip/transport/udp/udp.c | 11 - .../lib/drivers/oskittcp/include/memtrack.h | 80 +++ .../lib/drivers/oskittcp/include/oskittcp.h | 29 +- .../lib/drivers/oskittcp/oskittcp/interface.c | 159 ++--- 49 files changed, 1555 insertions(+), 924 deletions(-) create mode 100644 reactos/drivers/network/tcpip/include/irp.h create mode 100644 reactos/drivers/network/tcpip/include/memtrack.h delete mode 100644 reactos/drivers/network/tcpip/include/tags.h create mode 100644 reactos/drivers/network/tcpip/recmutex/recmutex.c create mode 100644 reactos/drivers/network/tcpip/recmutex/recmutex.h create mode 100644 reactos/drivers/network/tcpip/tcpip/irp.c create mode 100644 reactos/lib/drivers/ip/network/memtrack.c create mode 100644 reactos/lib/drivers/oskittcp/include/memtrack.h diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index fd0b818ac1b..fef1690dfa2 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -108,7 +108,7 @@ VOID FreeAdapter( * Adapter = Pointer to LAN_ADAPTER structure to free */ { - ExFreePoolWithTag(Adapter, LAN_ADAPTER_TAG); + exFreePool(Adapter); } @@ -249,7 +249,7 @@ VOID LanReceiveWorker( PVOID Context ) { Adapter = WorkItem->Adapter; BytesTransferred = WorkItem->BytesTransferred; - ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG); + exFreePool(WorkItem); IPInitializePacket(&IPPacket, 0); @@ -300,8 +300,7 @@ VOID LanSubmitReceiveWork( PNDIS_PACKET Packet, NDIS_STATUS Status, UINT BytesTransferred) { - PLAN_WQ_ITEM WQItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_WQ_ITEM), - WQ_CONTEXT_TAG); + PLAN_WQ_ITEM WQItem = exAllocatePool(NonPagedPool, sizeof(LAN_WQ_ITEM)); PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; TI_DbgPrint(DEBUG_DATALINK,("called\n")); @@ -313,7 +312,7 @@ VOID LanSubmitReceiveWork( WQItem->BytesTransferred = BytesTransferred; if (!ChewCreate( LanReceiveWorker, WQItem )) - ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG); + exFreePool(WQItem); } VOID NTAPI ProtocolTransferDataComplete( @@ -769,9 +768,9 @@ NTSTATUS NTAPI AppendUnicodeString(PUNICODE_STRING ResultFirst, BOOLEAN Deallocate) { NTSTATUS Status; UNICODE_STRING Ustr = *ResultFirst; - PWSTR new_string = ExAllocatePool + PWSTR new_string = ExAllocatePoolWithTag (PagedPool, - (ResultFirst->Length + Second->Length + sizeof(WCHAR))); + (ResultFirst->Length + Second->Length + sizeof(WCHAR)), TAG_STRING); if( !new_string ) { return STATUS_NO_MEMORY; } @@ -992,11 +991,6 @@ BOOLEAN BindAdapter( GetName( RegistryPath, &IF->Name ); Status = FindDeviceDescForAdapter( &IF->Name, &IF->Description ); - if (!NT_SUCCESS(Status)) { - TI_DbgPrint(MIN_TRACE, ("Failed to get device description.\n")); - IPDestroyInterface(IF); - return FALSE; - } TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n", &IF->Description)); @@ -1088,7 +1082,7 @@ NDIS_STATUS LANRegisterAdapter( TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); - IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_ADAPTER), LAN_ADAPTER_TAG); + IF = exAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER)); if (!IF) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NDIS_STATUS_RESOURCES; @@ -1126,7 +1120,7 @@ NDIS_STATUS LANRegisterAdapter( KeWaitForSingleObject(&IF->Event, UserRequest, KernelMode, FALSE, NULL); else if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ\n", AdapterName)); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1151,7 +1145,7 @@ NDIS_STATUS LANRegisterAdapter( default: /* Unsupported media */ TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NDIS_STATUS_NOT_SUPPORTED; } @@ -1163,7 +1157,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (NDISCall)\n", AdapterName)); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1175,7 +1169,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1198,7 +1192,7 @@ NDIS_STATUS LANRegisterAdapter( IF->HWAddressLength); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1210,7 +1204,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1220,7 +1214,7 @@ NDIS_STATUS LANRegisterAdapter( /* Bind adapter to IP layer */ if( !BindAdapter(IF, RegistryPath) ) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName)); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NDIS_STATUS_NOT_ACCEPTED; } diff --git a/reactos/drivers/network/tcpip/include/address.h b/reactos/drivers/network/tcpip/include/address.h index 1bd1dbd5c15..71a0f876499 100644 --- a/reactos/drivers/network/tcpip/include/address.h +++ b/reactos/drivers/network/tcpip/include/address.h @@ -15,6 +15,7 @@ */ #define AddrInitIPv4(IPAddress, RawAddress) \ { \ + INIT_TAG((IPAddress), '4VPI'); \ (IPAddress)->Type = IP_ADDRESS_V4; \ (IPAddress)->Address.IPv4Address = (RawAddress); \ } diff --git a/reactos/drivers/network/tcpip/include/datagram.h b/reactos/drivers/network/tcpip/include/datagram.h index f05107a7de1..760ba3a85be 100644 --- a/reactos/drivers/network/tcpip/include/datagram.h +++ b/reactos/drivers/network/tcpip/include/datagram.h @@ -21,7 +21,7 @@ NTSTATUS DGReceiveDatagram( PVOID Context, PIRP Irp); -BOOLEAN DGRemoveIRP( +VOID DGRemoveIRP( PADDRESS_FILE AddrFile, PIRP Irp); diff --git a/reactos/drivers/network/tcpip/include/debug.h b/reactos/drivers/network/tcpip/include/debug.h index 7f6d86b8e27..3bf4fb303c2 100644 --- a/reactos/drivers/network/tcpip/include/debug.h +++ b/reactos/drivers/network/tcpip/include/debug.h @@ -71,6 +71,8 @@ #define CP CHECKPOINT +#include + #define ASSERT_KM_POINTER(_x) \ ASSERT(((PVOID)_x) != (PVOID)0xcccccccc); \ ASSERT(((PVOID)_x) >= (PVOID)0x80000000); diff --git a/reactos/drivers/network/tcpip/include/dispatch.h b/reactos/drivers/network/tcpip/include/dispatch.h index 6be0f269aed..f9344252a8a 100644 --- a/reactos/drivers/network/tcpip/include/dispatch.h +++ b/reactos/drivers/network/tcpip/include/dispatch.h @@ -72,8 +72,6 @@ NTSTATUS DispTdiDeleteIPAddress( VOID DispDoDisconnect( PVOID Data); -NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ); - #endif /* __DISPATCH_H */ /* EOF */ diff --git a/reactos/drivers/network/tcpip/include/fileobjs.h b/reactos/drivers/network/tcpip/include/fileobjs.h index 12327701db8..bff07a64b40 100644 --- a/reactos/drivers/network/tcpip/include/fileobjs.h +++ b/reactos/drivers/network/tcpip/include/fileobjs.h @@ -13,6 +13,7 @@ extern KSPIN_LOCK AddressFileListLock; extern LIST_ENTRY ConnectionEndpointListHead; extern KSPIN_LOCK ConnectionEndpointListLock; + NTSTATUS FileOpenAddress( PTDI_REQUEST Request, PTA_IP_ADDRESS AddrList, @@ -26,6 +27,8 @@ NTSTATUS FileOpenConnection( PTDI_REQUEST Request, PVOID ClientContext); +PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ); + NTSTATUS FileCloseConnection( PTDI_REQUEST Request); diff --git a/reactos/drivers/network/tcpip/include/ip.h b/reactos/drivers/network/tcpip/include/ip.h index 068992f4839..61f8e7a2414 100644 --- a/reactos/drivers/network/tcpip/include/ip.h +++ b/reactos/drivers/network/tcpip/include/ip.h @@ -21,6 +21,7 @@ typedef IPv6_RAW_ADDRESS *PIPv6_RAW_ADDRESS; /* IP style address */ typedef struct IP_ADDRESS { + DEFINE_TAG UCHAR Type; /* Type of IP address */ union { IPv4_RAW_ADDRESS IPv4Address;/* IPv4 address (in network byte order) */ @@ -75,6 +76,7 @@ typedef VOID (*PACKET_COMPLETION_ROUTINE)( /* Structure for an IP packet */ typedef struct _IP_PACKET { + DEFINE_TAG OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */ UCHAR Type; /* Type of IP packet (see IP_ADDRESS_xx above) */ UCHAR Flags; /* Flags for packet (see IP_PACKET_FLAG_xx below)*/ @@ -148,6 +150,7 @@ typedef struct _SEND_RECV_STATS { /* Information about an IP interface */ typedef struct _IP_INTERFACE { + DEFINE_TAG LIST_ENTRY ListEntry; /* Entry on list */ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources used by the object */ KSPIN_LOCK Lock; /* Spin lock for this object */ diff --git a/reactos/drivers/network/tcpip/include/irp.h b/reactos/drivers/network/tcpip/include/irp.h new file mode 100644 index 00000000000..532200980ab --- /dev/null +++ b/reactos/drivers/network/tcpip/include/irp.h @@ -0,0 +1,13 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: include/irp.h + * PURPOSE: IRP routines + */ +#ifndef __IRP_H +#define __IRP_H + +VOID IRPRemember( PIRP Irp, PCHAR File, UINT Line ); +NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ); + +#endif/*__IRP_H*/ diff --git a/reactos/drivers/network/tcpip/include/lock.h b/reactos/drivers/network/tcpip/include/lock.h index 31ed91a8495..f5c15f5aefa 100644 --- a/reactos/drivers/network/tcpip/include/lock.h +++ b/reactos/drivers/network/tcpip/include/lock.h @@ -12,5 +12,9 @@ extern VOID TcpipInterlockedInsertTailList( PLIST_ENTRY ListHead, PKSPIN_LOCK Lock ); extern VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ); extern VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ); +extern VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ); +extern VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, + BOOLEAN ToWrite ); +extern VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ); #endif/*_LOCK_H*/ diff --git a/reactos/drivers/network/tcpip/include/memtrack.h b/reactos/drivers/network/tcpip/include/memtrack.h new file mode 100644 index 00000000000..778d7b75cc4 --- /dev/null +++ b/reactos/drivers/network/tcpip/include/memtrack.h @@ -0,0 +1,79 @@ +#ifndef MEMTRACK_H +#define MEMTRACK_H + +#include + +#ifndef FOURCC +#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) +#endif + +#define FBSD_MALLOC FOURCC('d','s','b','f') +#define EXALLOC_TAG FOURCC('E','x','A','l') +#define IRP_TAG FOURCC('P','I','R','P') +#define NPLOOK_TAG FOURCC('N','P','L','A') + +#define AllocatePacketWithBuffer(x,y,z) AllocatePacketWithBufferX(x,y,z,__FILE__,__LINE__) +#define FreeNdisPacket(x) FreeNdisPacketX(x,__FILE__,__LINE__) + +#if DBG +#define MTMARK() TrackDumpFL(__FILE__, __LINE__) +#define exAllocatePool(x,y) ExAllocatePoolX(x,y,__FILE__,__LINE__) +#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolX(x,y,__FILE__,__LINE__) +#define exFreePool(x) ExFreePoolX(x,__FILE__,__LINE__) +#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideListX(x,__FILE__,__LINE__) +#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideListX(x,y,__FILE__,__LINE__) + +typedef struct _ALLOCATION_TRACKER { + LIST_ENTRY Entry; + ULONG Tag; + PVOID Thing; + PCHAR FileName; + ULONG LineNo; +} ALLOCATION_TRACKER, *PALLOCATION_TRACKER; + +VOID TrackingInit(); +VOID TrackWithTag( ULONG Tag, PVOID Thing, PCHAR File, ULONG Line ); +#define Track(Tag,Thing) TrackWithTag(Tag,Thing,__FILE__,__LINE__) +VOID UntrackFL( PCHAR File, ULONG Line, PVOID Thing, ULONG Tag ); +#define Untrack(Thing) UntrackFL(__FILE__,__LINE__,Thing) +VOID TrackDumpFL( PCHAR File, ULONG Line ); +#define TrackDump() TrackDumpFL(__FILE__,__LINE__) + +static __inline PVOID ExAllocateFromNPagedLookasideListX( PNPAGED_LOOKASIDE_LIST List, PCHAR File, ULONG Line ) { + PVOID Out = ExAllocateFromNPagedLookasideList( List ); + if( Out ) TrackWithTag( NPLOOK_TAG, Out, File, Line ); + return Out; +} + +static __inline VOID ExFreeToNPagedLookasideListX( PNPAGED_LOOKASIDE_LIST List, PVOID Thing, PCHAR File, ULONG Line ) { + UntrackFL(File, Line, Thing, NPLOOK_TAG); + ExFreeToNPagedLookasideList( List, Thing ); +} + +static __inline PVOID ExAllocatePoolX( POOL_TYPE type, SIZE_T size, PCHAR File, ULONG Line ) { + PVOID Out = ExAllocatePool( type, size ); + if( Out ) TrackWithTag( EXALLOC_TAG, Out, File, Line ); + return Out; +} + +static __inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) { + UntrackFL(File, Line, Data, EXALLOC_TAG); + ExFreePool( Data ); +} + +#else +#define MTMARK() +#define Track(x,y) +#define TrackingInit() +#define TrackDump() +#define Untrack(x) +#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolWithTag(x,y,z) +#define exAllocatePool(x,y) ExAllocatePool(x,y) +#define exFreePool(x) ExFreePool(x) +#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideList(x) +#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideList(x,y) +#define TrackWithTag(w,x,y,z) +#define UntrackFL(w,x,y,z) +#endif + +#endif/*MEMMTRAC_H*/ diff --git a/reactos/drivers/network/tcpip/include/neighbor.h b/reactos/drivers/network/tcpip/include/neighbor.h index 6f125f06c51..95ea1f92769 100644 --- a/reactos/drivers/network/tcpip/include/neighbor.h +++ b/reactos/drivers/network/tcpip/include/neighbor.h @@ -27,6 +27,7 @@ typedef struct NEIGHBOR_CACHE_TABLE { /* Information about a neighbor */ typedef struct NEIGHBOR_CACHE_ENTRY { + DEFINE_TAG struct NEIGHBOR_CACHE_ENTRY *Next; /* Pointer to next entry */ UCHAR State; /* State of NCE */ UINT EventTimer; /* Ticks since last event */ diff --git a/reactos/drivers/network/tcpip/include/precomp.h b/reactos/drivers/network/tcpip/include/precomp.h index f37046d128e..ec563ac4b68 100644 --- a/reactos/drivers/network/tcpip/include/precomp.h +++ b/reactos/drivers/network/tcpip/include/precomp.h @@ -1,9 +1,9 @@ #include #include #include -#include #include #include +#include <../recmutex/recmutex.h> #include #include #include @@ -24,11 +24,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include diff --git a/reactos/drivers/network/tcpip/include/routines.h b/reactos/drivers/network/tcpip/include/routines.h index 1fda0e5aee8..31d7075abca 100644 --- a/reactos/drivers/network/tcpip/include/routines.h +++ b/reactos/drivers/network/tcpip/include/routines.h @@ -49,10 +49,9 @@ UINT ResizePacket( PNDIS_PACKET Packet, UINT Size); -NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket, - PCHAR Data, UINT Len ); - -VOID FreeNdisPacket( PNDIS_PACKET Packet ); +NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, + PCHAR Data, UINT Len, + PCHAR File, UINT Line ); void GetDataPtr( PNDIS_PACKET Packet, UINT Offset, diff --git a/reactos/drivers/network/tcpip/include/tags.h b/reactos/drivers/network/tcpip/include/tags.h deleted file mode 100644 index 52c16a45cc9..00000000000 --- a/reactos/drivers/network/tcpip/include/tags.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS TCP/IP protocol driver - * FILE: include/tags.h - * PURPOSE: Memory tags - */ -#ifndef __TAGS_H -#define __TAGS_H - -#define CONN_ENDPT_TAG 'pEnC' -#define ADDR_FILE_TAG 'FrdA' -#define CONTROL_CHANNEL_TAG 'CnoC' -#define TRANS_CONTEXT_TAG 'noCT' -#define TDI_ENTITY_TAG 'EidT' -#define DATAGRAM_SEND_TAG 'StaD' -#define DATAGRAM_RECV_TAG 'RtaD' -#define QUERY_CONTEXT_TAG 'noCQ' -#define IP_ADDRESS_TAG 'dAPI' -#define IP_INTERFACE_TAG 'FIPI' -#define DATAGRAM_REASSEMBLY_TAG 'RDPI' -#define DATAGRAM_FRAGMENT_TAG 'GFPI' -#define DATAGRAM_HOLE_TAG 'LHPI' -#define OSKITTCP_CONTEXT_TAG 'TKSO' -#define NEIGHBOR_PACKET_TAG 'kPbN' -#define NCE_TAG ' ECN' -#define PORT_SET_TAG 'teSP' -#define PACKET_BUFFER_TAG 'fuBP' -#define FRAGMENT_DATA_TAG 'taDF' -#define FIB_TAG ' BIF' -#define IFC_TAG ' CFI' -#define TDI_BUCKET_TAG 'BidT' -#define FBSD_TAG 'DSBF' -#define OSK_OTHER_TAG 'OKSO' -#define OSK_LARGE_TAG 'LKSO' -#define OSK_SMALL_TAG 'SKSO' -#define LAN_ADAPTER_TAG ' NAL' -#define WQ_CONTEXT_TAG 'noCW' - -#endif diff --git a/reactos/drivers/network/tcpip/include/tcp.h b/reactos/drivers/network/tcpip/include/tcp.h index a02c03b796e..5caa86e7637 100644 --- a/reactos/drivers/network/tcpip/include/tcp.h +++ b/reactos/drivers/network/tcpip/include/tcp.h @@ -59,11 +59,6 @@ typedef struct _SLEEPING_THREAD { KEVENT Event; } SLEEPING_THREAD, *PSLEEPING_THREAD; -typedef struct _CLIENT_DATA { - BOOLEAN Unlocked; - KSPIN_LOCK Lock; -} CLIENT_DATA, *PCLIENT_DATA; - /* Retransmission timeout constants */ /* Lower bound for retransmission timeout in TCP timer ticks */ @@ -89,15 +84,19 @@ typedef struct _CLIENT_DATA { #define SRF_FIN TCP_FIN extern LONG TCP_IPIdentification; -extern CLIENT_DATA ClientInfo; +extern LIST_ENTRY SignalledConnectionsList; +extern KSPIN_LOCK SignalledConnectionsLock; +extern LIST_ENTRY SleepingThreadsList; +extern FAST_MUTEX SleepingThreadsLock; +extern RECURSIVE_MUTEX TCPLock; /* accept.c */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection, PTDI_REQUEST_KERNEL Request ); NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ); -BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, - PCONNECTION_ENDPOINT Connection ); +VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, + PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPAccept ( PTDI_REQUEST Request, PCONNECTION_ENDPOINT Listener, @@ -112,8 +111,6 @@ VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ); -VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection); - PTCP_SEGMENT TCPCreateSegment( PIP_PACKET IPPacket, PTCPv4_HEADER TCPHeader, @@ -164,6 +161,8 @@ NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPTranslateError( int OskitError ); +VOID TCPTimeout(); + UINT TCPAllocatePort( UINT HintPort ); VOID TCPFreePort( UINT Port ); @@ -179,6 +178,6 @@ NTSTATUS TCPStartup( NTSTATUS TCPShutdown( VOID); -BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp ); +VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp ); #endif /* __TCP_H */ diff --git a/reactos/drivers/network/tcpip/include/titypes.h b/reactos/drivers/network/tcpip/include/titypes.h index 78584fb1391..ef985775088 100644 --- a/reactos/drivers/network/tcpip/include/titypes.h +++ b/reactos/drivers/network/tcpip/include/titypes.h @@ -10,6 +10,10 @@ #if DBG +#define DEFINE_TAG ULONG Tag; +#define INIT_TAG(_Object, _Tag) \ + ((_Object)->Tag = (_Tag)) + #define DEBUG_REFCHECK(Object) { \ if ((Object)->RefCount <= 0) { \ TI_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \ @@ -60,6 +64,9 @@ #else /* DBG */ +#define DEFINE_TAG +#define INIT_TAG(Object, Tag) + /* * VOID ReferenceObject( * PVOID Object) @@ -142,9 +149,11 @@ typedef struct _DATAGRAM_SEND_REQUEST { /* Transport address file context structure. The FileObject->FsContext2 field holds a pointer to this structure */ typedef struct _ADDRESS_FILE { + DEFINE_TAG LIST_ENTRY ListEntry; /* Entry on list */ KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ + USHORT Flags; /* Flags for address file (see below) */ IP_ADDRESS Address; /* Address of this address file */ USHORT Family; /* Address family */ USHORT Protocol; /* Protocol number */ @@ -204,6 +213,29 @@ typedef struct _ADDRESS_FILE { BOOLEAN RegisteredChainedReceiveExpeditedHandler; } ADDRESS_FILE, *PADDRESS_FILE; +/* Address File Flag constants */ +#define AFF_VALID 0x0001 /* Address file object is valid for use */ +#define AFF_BUSY 0x0002 /* Address file object is exclusive to someone */ +#define AFF_DELETE 0x0004 /* Address file object is sheduled to be deleted */ +#define AFF_SEND 0x0008 /* A send request is pending */ +#define AFF_RECEIVE 0x0010 /* A receive request is pending */ +#define AFF_PENDING 0x001C /* A request is pending */ + +/* Macros for manipulating address file object flags */ + +#define AF_IS_VALID(ADF) ((ADF)->Flags & AFF_VALID) +#define AF_SET_VALID(ADF) ((ADF)->Flags |= AFF_VALID) +#define AF_CLR_VALID(ADF) ((ADF)->Flags &= ~AFF_VALID) + +#define AF_IS_BUSY(ADF) ((ADF)->Flags & AFF_BUSY) +#define AF_SET_BUSY(ADF) ((ADF)->Flags |= AFF_BUSY) +#define AF_CLR_BUSY(ADF) ((ADF)->Flags &= ~AFF_BUSY) + +#define AF_IS_PENDING(ADF, X) (ADF->Flags & X) +#define AF_SET_PENDING(ADF, X) (ADF->Flags |= X) +#define AF_CLR_PENDING(ADF, X) (ADF->Flags &= ~X) + + /* Structure used to search through Address Files */ typedef struct _AF_SEARCH { PLIST_ENTRY Next; /* Next address file to check */ @@ -255,8 +287,6 @@ typedef struct _TDI_BUCKET { LIST_ENTRY Entry; struct _CONNECTION_ENDPOINT *AssociatedEndpoint; TDI_REQUEST Request; - NTSTATUS Status; - ULONG Information; } TDI_BUCKET, *PTDI_BUCKET; /* Transport connection context structure A.K.A. Transmission Control Block @@ -269,15 +299,19 @@ typedef struct _CONNECTION_ENDPOINT { PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */ PVOID SocketContext; /* Context for lower layer */ + UINT State; /* Socket state W.R.T. oskit */ + /* Requests */ LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */ LIST_ENTRY ListenRequest; /* Queued listen requests */ LIST_ENTRY ReceiveRequest; /* Queued receive requests */ LIST_ENTRY SendRequest; /* Queued send requests */ - LIST_ENTRY CompletionQueue;/* Completed requests to finish */ /* Signals */ + LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for + * notification service to the client */ UINT SignalState; /* Active signals from oskit */ + BOOLEAN Signalled; /* Are we a member of the signal list */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; diff --git a/reactos/drivers/network/tcpip/recmutex/recmutex.c b/reactos/drivers/network/tcpip/recmutex/recmutex.c new file mode 100644 index 00000000000..3450ab8567f --- /dev/null +++ b/reactos/drivers/network/tcpip/recmutex/recmutex.c @@ -0,0 +1,61 @@ +#include +#include "recmutex.h" + +VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { + RtlZeroMemory( RecMutex, sizeof(*RecMutex) ); + ExInitializeFastMutex( &RecMutex->Mutex ); + KeInitializeEvent( &RecMutex->StateLockedEvent, + NotificationEvent, FALSE ); +} + +/* NOTE: When we leave, the FAST_MUTEX must have been released. The result +* is that we always exit in the same irql as entering */ +VOID RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) { + NTSTATUS Status = STATUS_SUCCESS; + PVOID CurrentThread = KeGetCurrentThread(); + + ASSERT(RecMutex); + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* Wait for the previous user to unlock the RecMutex state. There might be + * multiple waiters waiting to change the state. We need to check each + * time we get the event whether somebody still has the state locked */ + + ExAcquireFastMutex( &RecMutex->Mutex ); + + if( CurrentThread == RecMutex->CurrentThread ) { + RecMutex->LockCount++; + ExReleaseFastMutex( &RecMutex->Mutex ); + return; + } + + while( RecMutex->LockCount != 0 ) { + ExReleaseFastMutex( &RecMutex->Mutex ); + Status = KeWaitForSingleObject( &RecMutex->StateLockedEvent, + UserRequest, + KernelMode, + FALSE, + NULL ); + ExAcquireFastMutex( &RecMutex->Mutex ); + } + RecMutex->CurrentThread = CurrentThread; + RecMutex->LockCount++; + ExReleaseFastMutex( &RecMutex->Mutex ); +} + +VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { + ASSERT(RecMutex); + + ExAcquireFastMutex( &RecMutex->Mutex ); + + ASSERT(RecMutex->LockCount > 0); + RecMutex->LockCount--; + + if( !RecMutex->LockCount ) { + KePulseEvent( &RecMutex->StateLockedEvent, IO_NETWORK_INCREMENT, + FALSE ); + } + + ExReleaseFastMutex( &RecMutex->Mutex ); +} + diff --git a/reactos/drivers/network/tcpip/recmutex/recmutex.h b/reactos/drivers/network/tcpip/recmutex/recmutex.h new file mode 100644 index 00000000000..3479268e3bd --- /dev/null +++ b/reactos/drivers/network/tcpip/recmutex/recmutex.h @@ -0,0 +1,21 @@ +#ifndef _ROSRTL_RECMUTEX_H +#define _ROSRTL_RECMUTEX_H + +typedef struct _RECURSIVE_MUTEX { + /* Lock. */ + FAST_MUTEX Mutex; + /* Number of times this object was locked */ + SIZE_T LockCount; + /* CurrentThread */ + PVOID CurrentThread; + /* Notification event which signals that another thread can take over */ + KEVENT StateLockedEvent; +} RECURSIVE_MUTEX, *PRECURSIVE_MUTEX; + +extern VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ); +extern VOID RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ); +extern VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ); + +#define ASSERT_LOCKED(x) + +#endif/*_ROSRTL_RECMUTEX_H*/ diff --git a/reactos/drivers/network/tcpip/tcpip.rbuild b/reactos/drivers/network/tcpip/tcpip.rbuild index ea9d3a6d5e1..2a9f91cc52e 100644 --- a/reactos/drivers/network/tcpip/tcpip.rbuild +++ b/reactos/drivers/network/tcpip/tcpip.rbuild @@ -21,6 +21,9 @@ lan.c + + recmutex.c + ainfo.c buffer.c @@ -28,6 +31,7 @@ fileobjs.c iinfo.c info.c + irp.c lock.c main.c ninfo.c diff --git a/reactos/drivers/network/tcpip/tcpip/ainfo.c b/reactos/drivers/network/tcpip/tcpip/ainfo.c index 0c1b11e717f..a3ea2e8889c 100644 --- a/reactos/drivers/network/tcpip/tcpip/ainfo.c +++ b/reactos/drivers/network/tcpip/tcpip/ainfo.c @@ -13,8 +13,6 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, PVOID Buffer, UINT BufferSize) { - //KIRQL OldIrql; - switch (ID->toi_id) { #if 0 @@ -22,10 +20,7 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, if (BufferSize < sizeof(UCHAR)) return TDI_INVALID_PARAMETER; - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); AddrFile->TTL = *((PUCHAR)Buffer); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - return TDI_SUCCESS; #endif default: diff --git a/reactos/drivers/network/tcpip/tcpip/buffer.c b/reactos/drivers/network/tcpip/tcpip/buffer.c index 6858ddea984..e604c7bcacc 100644 --- a/reactos/drivers/network/tcpip/tcpip/buffer.c +++ b/reactos/drivers/network/tcpip/tcpip/buffer.c @@ -318,16 +318,13 @@ NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Length, PCHAR NewBuf; if( Copy ) { - NewBuf = ExAllocatePoolWithTag( NonPagedPool, Length, PACKET_BUFFER_TAG ); + NewBuf = exAllocatePool( NonPagedPool, Length ); if( !NewBuf ) return NDIS_STATUS_RESOURCES; RtlCopyMemory( NewBuf, Data, Length ); } else NewBuf = Data; NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewBuf, Length ); - if( Status != NDIS_STATUS_SUCCESS ) { - if (Copy) ExFreePoolWithTag(NewBuf, PACKET_BUFFER_TAG); - return Status; - } + if( Status != NDIS_STATUS_SUCCESS ) return Status; NdisChainBufferAtFront( Packet, Buffer ); @@ -345,30 +342,33 @@ void GetDataPtr( PNDIS_PACKET Packet, SkipToOffset( Buffer, Offset, DataOut, Size ); } -NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket, - PCHAR Data, UINT Len ) { +NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, + PCHAR Data, UINT Len, + PCHAR File, UINT Line ) { PNDIS_PACKET Packet; PNDIS_BUFFER Buffer; NDIS_STATUS Status; PCHAR NewData; - NewData = ExAllocatePoolWithTag( NonPagedPool, Len, PACKET_BUFFER_TAG ); + NewData = exAllocatePool( NonPagedPool, Len ); if( !NewData ) return NDIS_STATUS_RESOURCES; if( Data ) RtlCopyMemory(NewData, Data, Len); NdisAllocatePacket( &Status, &Packet, GlobalPacketPool ); if( Status != NDIS_STATUS_SUCCESS ) { - ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG ); + exFreePool( NewData ); return Status; } + TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line); NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len ); if( Status != NDIS_STATUS_SUCCESS ) { - ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG ); + exFreePool( NewData ); FreeNdisPacket( Packet ); return Status; } + TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line); NdisChainBufferAtFront( Packet, Buffer ); *NdisPacket = Packet; @@ -377,8 +377,10 @@ NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket, } -VOID FreeNdisPacket -( PNDIS_PACKET Packet ) +VOID FreeNdisPacketX +( PNDIS_PACKET Packet, + PCHAR File, + UINT Line ) /* * FUNCTION: Frees an NDIS packet * ARGUMENTS: @@ -398,11 +400,13 @@ VOID FreeNdisPacket NdisGetNextBuffer(Buffer, &NextBuffer); NdisQueryBuffer(Buffer, &Data, &Length); TI_DbgPrint(DEBUG_PBUFFER, ("Freeing ndis buffer (0x%X)\n", Buffer)); + UntrackFL(File,Line,Buffer,NDIS_BUFFER_TAG); NdisFreeBuffer(Buffer); TI_DbgPrint(DEBUG_PBUFFER, ("Freeing exal buffer (0x%X)\n", Data)); - ExFreePoolWithTag(Data, PACKET_BUFFER_TAG); + exFreePool(Data); } /* Finally free the NDIS packet discriptor */ + UntrackFL(File,Line,Packet,NDIS_PACKET_TAG); NdisFreePacket(Packet); } diff --git a/reactos/drivers/network/tcpip/tcpip/dispatch.c b/reactos/drivers/network/tcpip/tcpip/dispatch.c index c6f2d2a55e9..237149520b3 100644 --- a/reactos/drivers/network/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/network/tcpip/tcpip/dispatch.c @@ -12,25 +12,6 @@ #include "precomp.h" #include - -NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) { - KIRQL OldIrql; - - Irp->IoStatus.Status = Status; - - if( Status == STATUS_PENDING ) - IoMarkIrpPending( Irp ); - else { - IoAcquireCancelSpinLock(&OldIrql); - (void)IoSetCancelRoutine( Irp, NULL ); - IoReleaseCancelSpinLock(OldIrql); - - IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); - } - - return Status; -} - NTSTATUS DispPrepareIrpForCancel( PTRANSPORT_CONTEXT Context, PIRP Irp, @@ -91,6 +72,7 @@ VOID DispDataRequestComplete( { PIRP Irp; PIO_STACK_LOCATION IrpSp; + PTRANSPORT_CONTEXT TranContext; KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n", @@ -98,6 +80,7 @@ VOID DispDataRequestComplete( Irp = Context; IrpSp = IoGetCurrentIrpStackLocation(Irp); + TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; IoAcquireCancelSpinLock(&OldIrql); @@ -119,6 +102,26 @@ VOID DispDataRequestComplete( TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n")); } +VOID DispDoDisconnect( PVOID Data ) { + PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data; + + TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect\n")); + TcpipRecursiveMutexEnter(&TCPLock, TRUE); + TCPDisconnect + ( DisType->Context, + DisType->Type, + NULL, + NULL, + DispDataRequestComplete, + DisType->Irp ); + TcpipRecursiveMutexLeave(&TCPLock); + TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n")); + + DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0); + + exFreePool(DisType); +} + VOID NTAPI DispCancelRequest( PDEVICE_OBJECT Device, PIRP Irp) @@ -133,9 +136,7 @@ VOID NTAPI DispCancelRequest( PTRANSPORT_CONTEXT TranContext; PFILE_OBJECT FileObject; UCHAR MinorFunction; - BOOLEAN DequeuedIrp = TRUE; - - IoReleaseCancelSpinLock(Irp->CancelIrql); + PDISCONNECT_TYPE DisType; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -158,8 +159,22 @@ VOID NTAPI DispCancelRequest( switch(MinorFunction) { case TDI_SEND: case TDI_RECEIVE: - DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp ); - break; + DisType = exAllocatePool(NonPagedPool, sizeof(DISCONNECT_TYPE)); + if (DisType) + { + DisType->Type = TDI_DISCONNECT_RELEASE | + ((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0); + DisType->Context = TranContext->Handle.ConnectionContext; + DisType->Irp = Irp; + + TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp ); + + if (!ChewCreate(DispDoDisconnect, DisType)) + exFreePool(DisType); + } + + IoReleaseCancelSpinLock(Irp->CancelIrql); + return; case TDI_SEND_DATAGRAM: if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { @@ -167,7 +182,7 @@ VOID NTAPI DispCancelRequest( break; } - DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); + DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); break; case TDI_RECEIVE_DATAGRAM: @@ -176,21 +191,20 @@ VOID NTAPI DispCancelRequest( break; } - DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); + DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); break; case TDI_CONNECT: - DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp); + TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp); break; default: TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction)); - ASSERT(FALSE); break; } - if (DequeuedIrp) - IRPFinish(Irp, STATUS_CANCELLED); + IoReleaseCancelSpinLock(Irp->CancelIrql); + IRPFinish(Irp, STATUS_CANCELLED); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } @@ -210,8 +224,7 @@ VOID NTAPI DispCancelListenRequest( PTRANSPORT_CONTEXT TranContext; PFILE_OBJECT FileObject; PCONNECTION_ENDPOINT Connection; - - IoReleaseCancelSpinLock(Irp->CancelIrql); + /*NTSTATUS Status = STATUS_SUCCESS;*/ TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -230,12 +243,16 @@ VOID NTAPI DispCancelListenRequest( /* Try canceling the request */ Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; - if (TCPAbortListenForSocket(Connection->AddressFile->Listener, - Connection)) - { - Irp->IoStatus.Information = 0; - IRPFinish(Irp, STATUS_CANCELLED); - } + TCPRemoveIRP(Connection, Irp); + + TCPAbortListenForSocket( + Connection->AddressFile->Listener, + Connection ); + + IoReleaseCancelSpinLock(Irp->CancelIrql); + + Irp->IoStatus.Information = 0; + IRPFinish(Irp, STATUS_CANCELLED); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } @@ -274,7 +291,6 @@ NTSTATUS DispTdiAssociateAddress( PFILE_OBJECT FileObject; PADDRESS_FILE AddrFile = NULL; NTSTATUS Status; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -294,6 +310,11 @@ NTSTATUS DispTdiAssociateAddress( return STATUS_INVALID_PARAMETER; } + if (Connection->AddressFile) { + TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n")); + return STATUS_INVALID_PARAMETER; + } + Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters; Status = ObReferenceObjectByHandle( @@ -309,18 +330,8 @@ NTSTATUS DispTdiAssociateAddress( return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - - if (Connection->AddressFile) { - ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n")); - return STATUS_INVALID_PARAMETER; - } - if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n", FileObject->FsContext2)); return STATUS_INVALID_PARAMETER; @@ -331,21 +342,17 @@ NTSTATUS DispTdiAssociateAddress( TranContext = FileObject->FsContext; if (!TranContext) { ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); return STATUS_INVALID_PARAMETER; } AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; if (!AddrFile) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); ObDereferenceObject(FileObject); TI_DbgPrint(MID_TRACE, ("No address file object.\n")); return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLockAtDpcLevel(&AddrFile->Lock); - Connection->AddressFile = AddrFile; /* Add connection endpoint to the address file */ @@ -354,9 +361,6 @@ NTSTATUS DispTdiAssociateAddress( /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */ ObDereferenceObject(FileObject); - KeReleaseSpinLockFromDpcLevel(&AddrFile->Lock); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - return Status; } @@ -383,6 +387,8 @@ NTSTATUS DispTdiConnect( /* Get associated connection endpoint file object. Quit if none exists */ + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (!TranContext) { TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); @@ -413,6 +419,8 @@ NTSTATUS DispTdiConnect( } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); } else @@ -437,7 +445,6 @@ NTSTATUS DispTdiDisassociateAddress( PCONNECTION_ENDPOINT Connection; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -457,26 +464,17 @@ NTSTATUS DispTdiDisassociateAddress( return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - if (!Connection->AddressFile) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n")); return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock); - /* Remove this connection from the address file */ Connection->AddressFile->Connection = NULL; - KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock); - /* Remove the address file from this connection */ Connection->AddressFile = NULL; - KeReleaseSpinLock(&Connection->Lock, OldIrql); - return STATUS_SUCCESS; } @@ -502,6 +500,8 @@ NTSTATUS DispTdiDisconnect( IrpSp = IoGetCurrentIrpStackLocation(Irp); DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters; + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + /* Get associated connection endpoint file object. Quit if none exists */ TranContext = IrpSp->FileObject->FsContext; @@ -527,6 +527,8 @@ NTSTATUS DispTdiDisconnect( Irp ); done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); } else @@ -553,7 +555,6 @@ NTSTATUS DispTdiListen( PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; NTSTATUS Status = STATUS_SUCCESS; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -561,6 +562,8 @@ NTSTATUS DispTdiListen( /* Get associated connection endpoint file object. Quit if none exists */ + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -579,23 +582,15 @@ NTSTATUS DispTdiListen( Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters; + TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n", + Connection->AddressFile )); + ASSERT(Connection->AddressFile); + Status = DispPrepareIrpForCancel (TranContext->Handle.ConnectionContext, Irp, (PDRIVER_CANCEL)DispCancelListenRequest); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - - if (Connection->AddressFile == NULL) - { - TI_DbgPrint(MID_TRACE, ("No associated address file\n")); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - Status = STATUS_INVALID_PARAMETER; - goto done; - } - - KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock); - /* Listening will require us to create a listening socket and store it in * the address file. It will be signalled, and attempt to complete an irp * when a new connection arrives. */ @@ -632,10 +627,9 @@ NTSTATUS DispTdiListen( Irp ); } - KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); } else @@ -662,15 +656,19 @@ NTSTATUS DispTdiQueryInformation( PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; + NTSTATUS Status; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters; + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (!TranContext) { TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_INVALID_PARAMETER; } @@ -688,6 +686,7 @@ NTSTATUS DispTdiQueryInformation( (FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) + sizeof(TDI_ADDRESS_IP))) { TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_BUFFER_TOO_SMALL; } @@ -706,18 +705,23 @@ NTSTATUS DispTdiQueryInformation( RtlZeroMemory( &Address->Address[0].Address[0].sin_zero, sizeof(Address->Address[0].Address[0].sin_zero)); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_SUCCESS; case TDI_CONNECTION_FILE: Endpoint = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; + TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE ); + DbgPrint("Returning socket address %x\n", Address->Address[0].Address[0].in_addr); RtlZeroMemory( &Address->Address[0].Address[0].sin_zero, sizeof(Address->Address[0].Address[0].sin_zero)); - return TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE ); + TcpipRecursiveMutexLeave(&TCPLock); + return STATUS_SUCCESS; default: TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_INVALID_PARAMETER; } } @@ -732,6 +736,7 @@ NTSTATUS DispTdiQueryInformation( (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) + sizeof(PVOID))) { TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_BUFFER_TOO_SMALL; } @@ -751,18 +756,24 @@ NTSTATUS DispTdiQueryInformation( default: TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_INVALID_PARAMETER; } if (!Endpoint) { TI_DbgPrint(MID_TRACE, ("No connection object.\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_INVALID_PARAMETER; } - return TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE ); + Status = TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE ); + + TcpipRecursiveMutexLeave(&TCPLock); + return Status; } } + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_NOT_IMPLEMENTED; } @@ -788,6 +799,8 @@ NTSTATUS DispTdiReceive( IrpSp = IoGetCurrentIrpStackLocation(Irp); ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -823,6 +836,8 @@ NTSTATUS DispTdiReceive( } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesReceived); } else @@ -856,6 +871,8 @@ NTSTATUS DispTdiReceiveDatagram( IrpSp = IoGetCurrentIrpStackLocation(Irp); DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -897,6 +914,8 @@ NTSTATUS DispTdiReceiveDatagram( } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesReceived); } else @@ -929,6 +948,8 @@ NTSTATUS DispTdiSend( IrpSp = IoGetCurrentIrpStackLocation(Irp); SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -969,6 +990,8 @@ NTSTATUS DispTdiSend( } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesSent); } else @@ -1001,6 +1024,8 @@ NTSTATUS DispTdiSendDatagram( IrpSp = IoGetCurrentIrpStackLocation(Irp); DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -1042,13 +1067,13 @@ NTSTATUS DispTdiSendDatagram( DataBuffer, BufferSize, &Irp->IoStatus.Information); - else { + else Status = STATUS_UNSUCCESSFUL; - ASSERT(FALSE); - } } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information); } else @@ -1097,7 +1122,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters; Status = STATUS_SUCCESS; - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); /* Set the event handler. if an event handler is associated with a specific event, it's flag (RegisteredXxxHandler) is TRUE. @@ -1218,7 +1243,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Status = STATUS_INVALID_PARAMETER; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; } @@ -1253,10 +1278,11 @@ VOID DispTdiQueryInformationExComplete( */ { PTI_QUERY_CONTEXT QueryContext; + UINT Count = 0; QueryContext = (PTI_QUERY_CONTEXT)Context; if (NT_SUCCESS(Status)) { - CopyBufferToBufferChain( + Count = CopyBufferToBufferChain( QueryContext->InputMdl, FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context), (PCHAR)&QueryContext->QueryInfo.Context, @@ -1273,7 +1299,7 @@ VOID DispTdiQueryInformationExComplete( QueryContext->Irp->IoStatus.Information = ByteCount; QueryContext->Irp->IoStatus.Status = Status; - ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); + exFreePool(QueryContext); } @@ -1336,7 +1362,7 @@ NTSTATUS DispTdiQueryInformationEx( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; OutputBuffer = Irp->UserBuffer; - QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); + QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT)); if (QueryContext) { _SEH2_TRY { InputMdl = IoAllocateMdl(InputBuffer, @@ -1399,7 +1425,7 @@ NTSTATUS DispTdiQueryInformationEx( IoFreeMdl(OutputMdl); } - ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); + exFreePool(QueryContext); } else Status = STATUS_INSUFFICIENT_RESOURCES; } else if( InputBufferLength == @@ -1412,7 +1438,7 @@ NTSTATUS DispTdiQueryInformationEx( Size = 0; - QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); + QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT)); if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES; _SEH2_TRY { @@ -1432,7 +1458,7 @@ NTSTATUS DispTdiQueryInformationEx( if( !NT_SUCCESS(Status) || !InputMdl ) { if( InputMdl ) IoFreeMdl( InputMdl ); - ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); + exFreePool(QueryContext); return Status; } diff --git a/reactos/drivers/network/tcpip/tcpip/fileobjs.c b/reactos/drivers/network/tcpip/tcpip/fileobjs.c index 88ac1858b1e..866e9ff0694 100644 --- a/reactos/drivers/network/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/network/tcpip/tcpip/fileobjs.c @@ -153,7 +153,7 @@ VOID AddrFileFree( * Object = Pointer to address file object to free */ { - ExFreePoolWithTag(Object, ADDR_FILE_TAG); + exFreePool(Object); } @@ -165,7 +165,7 @@ VOID ControlChannelFree( * Object = Pointer to address file object to free */ { - ExFreePoolWithTag(Object, CONTROL_CHANNEL_TAG); + exFreePool(Object); } @@ -189,8 +189,7 @@ NTSTATUS FileOpenAddress( TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol)); - AddrFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(ADDRESS_FILE), - ADDR_FILE_TAG); + AddrFile = exAllocatePool(NonPagedPool, sizeof(ADDRESS_FILE)); if (!AddrFile) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; @@ -213,7 +212,7 @@ NTSTATUS FileOpenAddress( if (!AddrIsUnspecified(&AddrFile->Address) && !AddrLocateInterface(&AddrFile->Address)) { - ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); + exFreePool(AddrFile); TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", A2S(&AddrFile->Address))); return STATUS_INVALID_PARAMETER; } @@ -231,7 +230,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port != Address->Address[0].Address[0].sin_port) || AddrFile->Port == 0xffff) { - ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); + exFreePool(AddrFile); return STATUS_INVALID_PARAMETER; } @@ -249,7 +248,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port != Address->Address[0].Address[0].sin_port) || AddrFile->Port == 0xffff) { - ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); + exFreePool(AddrFile); return STATUS_INVALID_PARAMETER; } @@ -296,6 +295,9 @@ NTSTATUS FileOpenAddress( /* Initialize spin lock that protects the address file object */ KeInitializeSpinLock(&AddrFile->Lock); + /* Set valid flag so the address can be used */ + AF_SET_VALID(AddrFile); + /* Return address file object */ Request->Handle.AddressHandle = AddrFile; @@ -326,7 +328,7 @@ NTSTATUS FileCloseAddress( KIRQL OldIrql; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; PDATAGRAM_SEND_REQUEST SendRequest; - PLIST_ENTRY CurrentEntry; + PLIST_ENTRY CurrentEntry, NextEntry; AddrFile = Request->Handle.AddressHandle; @@ -337,6 +339,8 @@ NTSTATUS FileCloseAddress( RemoveEntryList(&AddrFile->ListEntry); TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + /* FIXME: Kill TCP connections on this address file object */ /* Return pending requests with error */ @@ -344,27 +348,45 @@ NTSTATUS FileCloseAddress( TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile)); /* Go through pending receive request list and cancel them all */ - while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { + CurrentEntry = AddrFile->ReceiveQueue.Flink; + while (CurrentEntry != &AddrFile->ReceiveQueue) { + NextEntry = CurrentEntry->Flink; ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); + /* Abort the request and free its resources */ + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0); - /* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */ + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + CurrentEntry = NextEntry; } TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile)); /* Go through pending send request list and cancel them all */ - while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { - SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry); + CurrentEntry = AddrFile->TransmitQueue.Flink; + while (CurrentEntry != &AddrFile->TransmitQueue) { + NextEntry = CurrentEntry->Flink; + SendRequest = CONTAINING_RECORD(CurrentEntry, + DATAGRAM_SEND_REQUEST, ListEntry); + /* Abort the request and free its resources */ + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0); - ExFreePoolWithTag(SendRequest, DATAGRAM_SEND_TAG); + exFreePool(SendRequest); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + CurrentEntry = NextEntry; } + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + /* Protocol specific handling */ switch (AddrFile->Protocol) { case IPPROTO_TCP: TCPFreePort( AddrFile->Port ); - if( AddrFile->Listener ) - TCPClose( AddrFile->Listener ); + if( AddrFile->Listener ) { + TcpipRecursiveMutexEnter(&TCPLock, TRUE); + TCPClose( AddrFile->Listener ); + TcpipRecursiveMutexLeave(&TCPLock); + exFreePool( AddrFile->Listener ); + } break; case IPPROTO_UDP: @@ -403,7 +425,9 @@ NTSTATUS FileOpenConnection( if( !Connection ) return STATUS_NO_MEMORY; + TcpipRecursiveMutexEnter(&TCPLock, TRUE); Status = TCPSocket( Connection, AF_INET, SOCK_STREAM, IPPROTO_TCP ); + TcpipRecursiveMutexLeave(&TCPLock); if( !NT_SUCCESS(Status) ) { TCPFreeConnectionEndpoint( Connection ); @@ -413,11 +437,48 @@ NTSTATUS FileOpenConnection( /* Return connection endpoint file object */ Request->Handle.ConnectionContext = Connection; + /* Add connection endpoint to global list */ + ExInterlockedInsertTailList( + &ConnectionEndpointListHead, + &Connection->ListEntry, + &ConnectionEndpointListLock); + TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); return STATUS_SUCCESS; } + +/* + * FUNCTION: Find a connection by examining the context field. This + * is needed in some situations where a FIN reply is needed after a + * socket is formally broken. + * ARGUMENTS: + * Request = Pointer to TDI request structure for this request + * RETURNS: + * Status of operation + */ +PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) { + PLIST_ENTRY Entry; + KIRQL OldIrql; + PCONNECTION_ENDPOINT Connection = NULL; + + TcpipAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql ); + + for( Entry = ConnectionEndpointListHead.Flink; + Entry != &ConnectionEndpointListHead; + Entry = Entry->Flink ) { + Connection = + CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry ); + if( Connection->SocketContext == Context ) break; + else Connection = NULL; + } + + TcpipReleaseSpinLock( &ConnectionEndpointListLock, OldIrql ); + + return Connection; +} + /* * FUNCTION: Closes an connection file object * ARGUMENTS: @@ -429,12 +490,21 @@ NTSTATUS FileCloseConnection( PTDI_REQUEST Request) { PCONNECTION_ENDPOINT Connection; + KIRQL OldIrql; TI_DbgPrint(MID_TRACE, ("Called.\n")); Connection = Request->Handle.ConnectionContext; + TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + RemoveEntryList(&Connection->ListEntry); + TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); + + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); TCPClose( Connection ); + TcpipRecursiveMutexLeave( &TCPLock ); + + TCPFreeConnectionEndpoint(Connection); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); @@ -455,8 +525,7 @@ NTSTATUS FileOpenControlChannel( PCONTROL_CHANNEL ControlChannel; TI_DbgPrint(MID_TRACE, ("Called.\n")); - ControlChannel = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ControlChannel), - CONTROL_CHANNEL_TAG); + ControlChannel = exAllocatePool(NonPagedPool, sizeof(*ControlChannel)); if (!ControlChannel) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); @@ -496,7 +565,7 @@ NTSTATUS FileCloseControlChannel( PCONTROL_CHANNEL ControlChannel = Request->Handle.ControlChannel; NTSTATUS Status = STATUS_SUCCESS; - ExFreePoolWithTag(ControlChannel, CONTROL_CHANNEL_TAG); + exFreePool(ControlChannel); Request->Handle.ControlChannel = NULL; return Status; diff --git a/reactos/drivers/network/tcpip/tcpip/iinfo.c b/reactos/drivers/network/tcpip/tcpip/iinfo.c index 7a9f35c794f..7494d0a8113 100644 --- a/reactos/drivers/network/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/network/tcpip/tcpip/iinfo.c @@ -32,7 +32,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID ID, Interface, IF, ID.tei_entity, ID.tei_instance)); OutData = - (PIFENTRY)ExAllocatePool( NonPagedPool, + (PIFENTRY)exAllocatePool( NonPagedPool, sizeof(IFENTRY) + MAX_IFDESCR_LEN ); if( !OutData ) return TDI_NO_RESOURCES; /* Out of memory */ @@ -99,7 +99,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID ID, ID.tei_entity, ID.tei_instance, Size)); Status = InfoCopyOut( (PCHAR)OutData, Size, Buffer, BufferSize ); - ExFreePool( OutData ); + exFreePool( OutData ); TI_DbgPrint(DEBUG_INFO,("Returning %x\n", Status)); @@ -117,14 +117,14 @@ TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID ID, if (MemSize != 0) { - ArpEntries = ExAllocatePool( NonPagedPool, MemSize ); + ArpEntries = exAllocatePoolWithTag( NonPagedPool, MemSize, FOURCC('A','R','P','t') ); if( !ArpEntries ) return STATUS_NO_MEMORY; NBCopyNeighbors( Interface, ArpEntries ); Status = InfoCopyOut( (PVOID)ArpEntries, MemSize, Buffer, BufferSize ); - ExFreePool( ArpEntries ); + exFreePool( ArpEntries ); } else { diff --git a/reactos/drivers/network/tcpip/tcpip/irp.c b/reactos/drivers/network/tcpip/tcpip/irp.c new file mode 100644 index 00000000000..f2fc589d19b --- /dev/null +++ b/reactos/drivers/network/tcpip/tcpip/irp.c @@ -0,0 +1,37 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: tcpip/dispatch.h + * PURPOSE: TDI dispatch routines + * PROGRAMMERS: arty + * REVISIONS: + * CSH 01/08-2000 Created + * TODO: Validate device object in all dispatch routines + */ + +#include "precomp.h" + +VOID IRPRemember( PIRP Irp, PCHAR File, UINT Line ) { + TrackWithTag( IRP_TAG, Irp, File, Line ); +} + +NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) { + KIRQL OldIrql; + + UntrackFL( __FILE__, __LINE__, Irp, IRP_TAG ); + + Irp->IoStatus.Status = Status; + + if( Status == STATUS_PENDING ) + IoMarkIrpPending( Irp ); + else { + IoAcquireCancelSpinLock(&OldIrql); + (void)IoSetCancelRoutine( Irp, NULL ); + IoReleaseCancelSpinLock(OldIrql); + + IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); + } + + return Status; +} + diff --git a/reactos/drivers/network/tcpip/tcpip/lock.c b/reactos/drivers/network/tcpip/tcpip/lock.c index 9a6cdc95fa3..db8ef244f33 100644 --- a/reactos/drivers/network/tcpip/tcpip/lock.c +++ b/reactos/drivers/network/tcpip/tcpip/lock.c @@ -44,3 +44,16 @@ VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) { ExReleaseFastMutex( Mutex ); } +VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { + RecursiveMutexInit( RecMutex ); +} + +VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOLEAN ToWrite ) { + //TI_DbgPrint(DEBUG_LOCK,("Locking\n")); + RecursiveMutexEnter( RecMutex ); +} + +VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { + //TI_DbgPrint(DEBUG_LOCK,("Unlocking\n")); + RecursiveMutexLeave( RecMutex ); +} diff --git a/reactos/drivers/network/tcpip/tcpip/main.c b/reactos/drivers/network/tcpip/tcpip/main.c index d1ce6c73c1d..f8aa2225bde 100644 --- a/reactos/drivers/network/tcpip/tcpip/main.c +++ b/reactos/drivers/network/tcpip/tcpip/main.c @@ -119,25 +119,30 @@ NTSTATUS TiCreateFileObject( TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp)); EaInfo = Irp->AssociatedIrp.SystemBuffer; - +CP /* Parameter check */ /* No EA information means that we're opening for SET/QUERY_INFORMATION * style calls. */ - +#if 0 + if (!EaInfo) { + TI_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n")); + return STATUS_INVALID_PARAMETER; + } +#endif +CP /* Allocate resources here. We release them again if something failed */ - Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSPORT_CONTEXT), - TRANS_CONTEXT_TAG); + Context = exAllocatePool(NonPagedPool, sizeof(TRANSPORT_CONTEXT)); if (!Context) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; } - +CP Context->CancelIrps = FALSE; - +CP IrpSp = IoGetCurrentIrpStackLocation(Irp); IrpSp->FileObject->FsContext = Context; Request.RequestContext = Irp; - +CP /* Branch to the right handler */ if (EaInfo && (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) && @@ -145,7 +150,7 @@ NTSTATUS TiCreateFileObject( (&EaInfo->EaName, TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH)) { /* This is a request to open an address */ - +CP /* XXX This should probably be done in IoCreateFile() */ /* Parameter checks */ @@ -164,10 +169,10 @@ NTSTATUS TiCreateFileObject( TI_DbgPrint(MIN_TRACE, ("AddressType: %\n", Address->Address[0].AddressType)); } - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } - +CP /* Open address file object */ /* Protocol depends on device object so find the protocol */ @@ -181,21 +186,21 @@ NTSTATUS TiCreateFileObject( Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n")); - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } } else { TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject)); - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } - +CP Status = FileOpenAddress(&Request, Address, Protocol, NULL); if (NT_SUCCESS(Status)) { IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE; Context->Handle.AddressHandle = Request.Handle.AddressHandle; } - +CP } else if (EaInfo && (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) && (RtlCompareMemory @@ -203,12 +208,12 @@ NTSTATUS TiCreateFileObject( TDI_CONNECTION_CONTEXT_LENGTH) == TDI_CONNECTION_CONTEXT_LENGTH)) { /* This is a request to open a connection endpoint */ - +CP /* Parameter checks */ if (EaInfo->EaValueLength < sizeof(PVOID)) { TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n")); - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } @@ -216,7 +221,7 @@ NTSTATUS TiCreateFileObject( if (DeviceObject != TCPDeviceObject) { TI_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } @@ -239,7 +244,7 @@ NTSTATUS TiCreateFileObject( } if (!NT_SUCCESS(Status)) - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status)); @@ -317,6 +322,9 @@ TiDispatchOpenClose( { PIO_STACK_LOCATION IrpSp; NTSTATUS Status; + PTRANSPORT_CONTEXT Context; + + IRPRemember(Irp, __FILE__, __LINE__); // DbgPrint("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp); @@ -330,7 +338,8 @@ TiDispatchOpenClose( /* Close an address file, connection endpoint, or control connection */ case IRP_MJ_CLOSE: - Status = TiCloseFileObject(DeviceObject, Irp); + Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; + Status = TiCloseFileObject(DeviceObject, Irp); break; default: @@ -360,6 +369,8 @@ TiDispatchInternal( BOOLEAN Complete = TRUE; PIO_STACK_LOCATION IrpSp; + IRPRemember(Irp, __FILE__, __LINE__); + IrpSp = IoGetCurrentIrpStackLocation(Irp); TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n", @@ -462,6 +473,8 @@ TiDispatch( NTSTATUS Status; PIO_STACK_LOCATION IrpSp; + IRPRemember(Irp, __FILE__, __LINE__); + IrpSp = IoGetCurrentIrpStackLocation(Irp); TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp)); @@ -530,6 +543,8 @@ VOID NTAPI TiUnload( } TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); #endif + ChewShutdown(); + /* Cancel timer */ KeCancelTimer(&IPTimer); @@ -567,13 +582,11 @@ VOID NTAPI TiUnload( if (RawIPDeviceObject) IoDeleteDevice(RawIPDeviceObject); - if (IPDeviceObject) { - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - } + if (IPDeviceObject) + IoDeleteDevice(IPDeviceObject); if (EntityList) - ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG); + exFreePool(EntityList); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } @@ -624,22 +637,17 @@ DriverEntry( TI_DbgPrint(MAX_TRACE, ("Called.\n")); + TrackingInit(); + /* TdiInitialize() ? */ /* FIXME: Create symbolic links in Win32 namespace */ - /* Initialize our periodic timer and its associated DPC object. When the - timer expires, the IPTimeout deferred procedure call (DPC) is queued */ - ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL ); - KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL); - KeInitializeTimer(&IPTimer); - /* Create IP device object */ Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status)); - TiUnload(DriverObject); return Status; } @@ -650,7 +658,8 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status)); - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); return Status; } @@ -659,7 +668,9 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status)); - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); return Status; } @@ -668,18 +679,23 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status)); - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); return Status; } /* Setup network layer and transport layer entities */ KeInitializeSpinLock(&EntityListLock); - EntityList = ExAllocatePoolWithTag(NonPagedPool, - sizeof(TDIEntityID) * MAX_TDI_ENTITIES, - TDI_ENTITY_TAG ); + EntityList = exAllocatePool(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES ); if (!EntityList) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } @@ -689,14 +705,25 @@ DriverEntry( /* Allocate NDIS packet descriptors */ NdisAllocatePacketPool(&NdisStatus, &GlobalPacketPool, 100, sizeof(PACKET_CONTEXT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate NDIS buffer descriptors */ NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 100); if (NdisStatus != NDIS_STATUS_SUCCESS) { - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); return STATUS_INSUFFICIENT_RESOURCES; } @@ -718,26 +745,64 @@ DriverEntry( /* Initialize transport level protocol subsystems */ Status = RawIPStartup(); if( !NT_SUCCESS(Status) ) { - TiUnload(DriverObject); - return Status; + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } Status = UDPStartup(); if( !NT_SUCCESS(Status) ) { - TiUnload(DriverObject); - return Status; + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } Status = TCPStartup(); if( !NT_SUCCESS(Status) ) { - TiUnload(DriverObject); - return Status; + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } Status = ICMPStartup(); if( !NT_SUCCESS(Status) ) { - TiUnload(DriverObject); - return Status; + TCPShutdown(); + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } /* Use direct I/O */ @@ -754,11 +819,33 @@ DriverEntry( DriverObject->DriverUnload = TiUnload; + /* Initialize our periodic timer and its associated DPC object. When the + timer expires, the IPTimeout deferred procedure call (DPC) is queued */ + ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL ); + KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL); + KeInitializeTimer(&IPTimer); + + /* Start the periodic timer with an initial and periodic + relative expiration time of IP_TIMEOUT milliseconds */ + DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000; + KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc); + /* Open loopback adapter */ Status = LoopRegisterAdapter(NULL, NULL); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status)); - TiUnload(DriverObject); + TCPShutdown(); + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); return Status; } @@ -775,18 +862,25 @@ DriverEntry( NULL, 0, NULL); - TiUnload(DriverObject); - return Status; + TCPShutdown(); + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } - /* Start the periodic timer with an initial and periodic - relative expiration time of IP_TIMEOUT milliseconds */ - DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000; - KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc); - return STATUS_SUCCESS; } + VOID NTAPI IPAddInterface( ULONG Unknown0, diff --git a/reactos/drivers/network/tcpip/tcpip/mocklock.c b/reactos/drivers/network/tcpip/tcpip/mocklock.c index 0aa957c4035..d2ef46b3a56 100644 --- a/reactos/drivers/network/tcpip/tcpip/mocklock.c +++ b/reactos/drivers/network/tcpip/tcpip/mocklock.c @@ -45,3 +45,12 @@ VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ) { VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) { } +VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { +} + +UINT TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOL ToWrite ) { + return 0; +} + +VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { +} diff --git a/reactos/drivers/network/tcpip/tcpip/ninfo.c b/reactos/drivers/network/tcpip/tcpip/ninfo.c index 293eb19a027..af4fb99723e 100644 --- a/reactos/drivers/network/tcpip/tcpip/ninfo.c +++ b/reactos/drivers/network/tcpip/tcpip/ninfo.c @@ -22,9 +22,9 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI UINT RtCount = CountFIBs(IF); UINT Size = sizeof( IPROUTE_ENTRY ) * RtCount; PFIB_ENTRY RCache = - ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ), + exAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ), RCacheCur = RCache; - PIPROUTE_ENTRY RouteEntries = ExAllocatePool( NonPagedPool, Size ), + PIPROUTE_ENTRY RouteEntries = exAllocatePool( NonPagedPool, Size ), RtCurrent = RouteEntries; UINT i; @@ -32,8 +32,8 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI RtCount, RCache)); if( !RCache || !RouteEntries ) { - if( RCache ) ExFreePool( RCache ); - if( RouteEntries ) ExFreePool( RouteEntries ); + if( RCache ) exFreePool( RCache ); + if( RouteEntries ) exFreePool( RouteEntries ); return TDI_NO_RESOURCES; } @@ -83,8 +83,8 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize ); - ExFreePool( RouteEntries ); - ExFreePool( RCache ); + exFreePool( RouteEntries ); + exFreePool( RCache ); TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status)); @@ -118,7 +118,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID, return TDI_INVALID_PARAMETER; } - IPEntry = ExAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY)); + IPEntry = exAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY)); if (!IPEntry) { TcpipReleaseSpinLock(&EntityListLock, OldIrql); @@ -143,7 +143,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID, InfoCopyOut((PCHAR)IPEntry, sizeof(IPADDR_ENTRY), Buffer, BufferSize); - ExFreePool(IPEntry); + exFreePool(IPEntry); return TDI_SUCCESS; } diff --git a/reactos/lib/drivers/ip/ip.rbuild b/reactos/lib/drivers/ip/ip.rbuild index 6a3e5500c30..d6ee690692a 100644 --- a/reactos/lib/drivers/ip/ip.rbuild +++ b/reactos/lib/drivers/ip/ip.rbuild @@ -17,6 +17,7 @@ interface.c ip.c loopback.c + memtrack.c neighbor.c ports.c receive.c diff --git a/reactos/lib/drivers/ip/network/address.c b/reactos/lib/drivers/ip/network/address.c index 6ddbfd97e6d..974dc7103a8 100644 --- a/reactos/lib/drivers/ip/network/address.c +++ b/reactos/lib/drivers/ip/network/address.c @@ -106,7 +106,7 @@ VOID IPAddressFree( * Nothing */ { - ExFreePoolWithTag(Object, IP_ADDRESS_TAG); + exFreePool(Object); } diff --git a/reactos/lib/drivers/ip/network/ip.c b/reactos/lib/drivers/ip/network/ip.c index 2d3621ba60f..f13dd614e8c 100644 --- a/reactos/lib/drivers/ip/network/ip.c +++ b/reactos/lib/drivers/ip/network/ip.c @@ -39,7 +39,7 @@ VOID FreeIF( * Object = Pointer to an interface structure */ { - ExFreePoolWithTag(Object, IP_INTERFACE_TAG); + exFreePool(Object); } PIP_PACKET IPInitializePacket( @@ -56,6 +56,8 @@ PIP_PACKET IPInitializePacket( /* FIXME: Is this needed? */ RtlZeroMemory(IPPacket, sizeof(IP_PACKET)); + INIT_TAG(IPPacket, 'TKPI'); + IPPacket->Free = DontFreePacket; IPPacket->Type = Type; @@ -71,6 +73,9 @@ void NTAPI IPTimeout( PVOID Context ) { /* Clean possible outdated cached neighbor addresses */ NBTimeout(); + + /* Call upper layer timeout routines */ + TCPTimeout(); } @@ -137,13 +142,14 @@ PIP_INTERFACE IPCreateInterface( } #endif - IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(IP_INTERFACE), - IP_INTERFACE_TAG); + IF = exAllocatePool(NonPagedPool, sizeof(IP_INTERFACE)); if (!IF) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } + INIT_TAG(IF, 'ECAF'); + RtlZeroMemory(IF, sizeof(IP_INTERFACE)); IF->Free = FreeIF; @@ -162,11 +168,10 @@ PIP_INTERFACE IPCreateInterface( TcpipInitializeSpinLock(&IF->Lock); - IF->TCPContext = ExAllocatePoolWithTag - ( NonPagedPool, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in ), - OSKITTCP_CONTEXT_TAG ); + IF->TCPContext = exAllocatePool + ( NonPagedPool, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in ) ); if (!IF->TCPContext) { - ExFreePoolWithTag(IF, IP_INTERFACE_TAG); + exFreePool(IF); return NULL; } @@ -192,8 +197,8 @@ VOID IPDestroyInterface( RemoveTDIInterfaceEntity( IF ); #endif - ExFreePoolWithTag(IF->TCPContext, OSKITTCP_CONTEXT_TAG); - ExFreePoolWithTag(IF, IP_INTERFACE_TAG); + exFreePool(IF->TCPContext); + exFreePool(IF); } VOID IPAddInterfaceRoute( PIP_INTERFACE IF ) { @@ -359,7 +364,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IPDATAGRAM_REASSEMBLY), /* Size of each entry */ - DATAGRAM_REASSEMBLY_TAG, /* Tag */ + 'RDPI', /* Tag */ 0); /* Depth */ ExInitializeNPagedLookasideList( @@ -368,7 +373,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IP_FRAGMENT), /* Size of each entry */ - DATAGRAM_FRAGMENT_TAG, /* Tag */ + 'GFPI', /* Tag */ 0); /* Depth */ ExInitializeNPagedLookasideList( @@ -377,7 +382,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IPDATAGRAM_HOLE), /* Size of each entry */ - DATAGRAM_HOLE_TAG, /* Tag */ + 'LHPI', /* Tag */ 0); /* Depth */ /* Start routing subsystem */ diff --git a/reactos/lib/drivers/ip/network/memtrack.c b/reactos/lib/drivers/ip/network/memtrack.c new file mode 100644 index 00000000000..5e8304f913b --- /dev/null +++ b/reactos/lib/drivers/ip/network/memtrack.c @@ -0,0 +1,153 @@ +#define MEMTRACK_NO_POOL +#include "precomp.h" + + +#if DBG +#define TRACK_TAG 'KCrT' + +static LIST_ENTRY AllocatedObjectsList; +static KSPIN_LOCK AllocatedObjectsLock; +static NPAGED_LOOKASIDE_LIST AllocatedObjectsLookasideList; + +VOID TrackingInit() { + TcpipInitializeSpinLock( &AllocatedObjectsLock ); + InitializeListHead( &AllocatedObjectsList ); + ExInitializeNPagedLookasideList(&AllocatedObjectsLookasideList, + NULL, + NULL, + 0, + sizeof(ALLOCATION_TRACKER), + TRACK_TAG, + 0 ); +} + +VOID ShowTrackedThing( PCHAR What, PALLOCATION_TRACKER Thing, BOOLEAN ForceShow ) { + + if (ForceShow) + { + DbgPrint("[%s] Thing %08x %c%c%c%c (%s:%d)\n", + What, + Thing->Thing, + ((PCHAR)&Thing->Tag)[3], + ((PCHAR)&Thing->Tag)[2], + ((PCHAR)&Thing->Tag)[1], + ((PCHAR)&Thing->Tag)[0], + Thing->FileName, + Thing->LineNo); + } + else + { + TI_DbgPrint(MAX_TRACE, + ("[%s] Thing %08x %c%c%c%c (%s:%d)\n", + What, + Thing->Thing, + ((PCHAR)&Thing->Tag)[3], + ((PCHAR)&Thing->Tag)[2], + ((PCHAR)&Thing->Tag)[1], + ((PCHAR)&Thing->Tag)[0], + Thing->FileName, + Thing->LineNo)); + } +} + +VOID TrackWithTag( ULONG Tag, PVOID Thing, PCHAR FileName, ULONG LineNo ) { + PALLOCATION_TRACKER TrackedThing = + ExAllocateFromNPagedLookasideList( &AllocatedObjectsLookasideList ); + + KIRQL OldIrql; + PLIST_ENTRY Entry; + PALLOCATION_TRACKER ThingInList; + + if (!TrackedThing) return; + + TrackedThing->Tag = Tag; + TrackedThing->Thing = Thing; + TrackedThing->FileName = FileName; + TrackedThing->LineNo = LineNo; + + ShowTrackedThing( "Alloc", TrackedThing, FALSE ); + + TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); + Entry = AllocatedObjectsList.Flink; + while( Entry != &AllocatedObjectsList ) { + ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); + if( ThingInList->Thing == Thing ) { + RemoveEntryList(Entry); + + ShowTrackedThing( "Double Alloc (Item in list)", ThingInList, TRUE ); + ShowTrackedThing( "Double Alloc (Item not in list)", TrackedThing, TRUE ); + + ExFreeToNPagedLookasideList( &AllocatedObjectsLookasideList, + ThingInList ); + + break; + } + Entry = Entry->Flink; + } + + InsertHeadList( &AllocatedObjectsList, &TrackedThing->Entry ); + + TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); +} + +VOID UntrackFL( PCHAR File, ULONG Line, PVOID Thing, ULONG Tag ) { + KIRQL OldIrql; + PLIST_ENTRY Entry; + PALLOCATION_TRACKER ThingInList; + + TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); + Entry = AllocatedObjectsList.Flink; + while( Entry != &AllocatedObjectsList ) { + ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); + if( ThingInList->Thing == Thing ) { + RemoveEntryList(Entry); + + ShowTrackedThing( "Free ", ThingInList, FALSE ); + + if ( ThingInList->Tag != Tag ) { + DbgPrint("UNTRACK: TAG DOES NOT MATCH (%x)\n", Thing); + ShowTrackedThing("Tag Mismatch (Item in list)", ThingInList, TRUE); + ASSERT( FALSE ); + } + + ExFreeToNPagedLookasideList( &AllocatedObjectsLookasideList, + ThingInList ); + + TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); + + return; + } + Entry = Entry->Flink; + } + TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); + + DbgPrint("[Double Free] Thing %08x %c%c%c%c (%s:%d)\n", + Thing, + ((PCHAR)&Tag)[3], + ((PCHAR)&Tag)[2], + ((PCHAR)&Tag)[1], + ((PCHAR)&Tag)[0], + File, + Line); + + ASSERT( FALSE ); +} + +VOID TrackDumpFL( PCHAR File, ULONG Line ) { + KIRQL OldIrql; + PLIST_ENTRY Entry; + PALLOCATION_TRACKER Thing; + + TI_DbgPrint(MAX_TRACE,("Dump: %s:%d\n", File, Line)); + + TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); + Entry = AllocatedObjectsList.Flink; + while( Entry != &AllocatedObjectsList ) { + Thing = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); + ShowTrackedThing( "Dump ", Thing, FALSE ); + Entry = Entry->Flink; + } + TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); +} + +#endif /* DBG */ diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index ae5e3a5bb19..375aac19457 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -21,7 +21,7 @@ VOID NBCompleteSend( PVOID Context, ASSERT_KM_POINTER(Packet->Complete); Packet->Complete( Packet->Context, Packet->Packet, Status ); TI_DbgPrint(MID_TRACE, ("Completed\n")); - ExFreePoolWithTag( Packet, NEIGHBOR_PACKET_TAG ); + exFreePool( Packet ); TI_DbgPrint(MID_TRACE, ("Freed\n")); } @@ -84,7 +84,7 @@ VOID NBFlushPacketQueue( PNEIGHBOR_CACHE_ENTRY NCE, Packet->Packet, ErrorCode ); - ExFreePoolWithTag( Packet, NEIGHBOR_PACKET_TAG ); + exFreePool( Packet ); } } @@ -128,7 +128,7 @@ VOID NBTimeout(VOID) *PrevNCE = NCE->Next; NBFlushPacketQueue(NCE, NDIS_STATUS_REQUEST_ABORTED); - ExFreePoolWithTag(NCE, NCE_TAG); + exFreePool(NCE); continue; } @@ -179,7 +179,7 @@ VOID NBShutdown(VOID) /* Flush wait queue */ NBFlushPacketQueue( CurNCE, NDIS_STATUS_NOT_ACCEPTED ); - ExFreePoolWithTag(CurNCE, NCE_TAG); + exFreePool(CurNCE); CurNCE = NextNCE; } @@ -241,15 +241,16 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor( "LinkAddress (0x%X) LinkAddressLength (%d) State (0x%X)\n", Interface, Address, LinkAddress, LinkAddressLength, State)); - NCE = ExAllocatePoolWithTag - (NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength, - NCE_TAG); + NCE = exAllocatePool + (NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength); if (NCE == NULL) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } + INIT_TAG(NCE, ' ECN'); + NCE->Interface = Interface; NCE->Address = *Address; NCE->LinkAddressLength = LinkAddressLength; @@ -451,8 +452,7 @@ BOOLEAN NBQueuePacket( (DEBUG_NCACHE, ("Called. NCE (0x%X) NdisPacket (0x%X).\n", NCE, NdisPacket)); - Packet = ExAllocatePoolWithTag( NonPagedPool, sizeof(NEIGHBOR_PACKET), - NEIGHBOR_PACKET_TAG ); + Packet = exAllocatePool( NonPagedPool, sizeof(NEIGHBOR_PACKET) ); if( !Packet ) return FALSE; /* FIXME: Should we limit the number of queued packets? */ @@ -514,7 +514,7 @@ VOID NBRemoveNeighbor( *PrevNCE = CurNCE->Next; NBFlushPacketQueue( CurNCE, NDIS_STATUS_REQUEST_ABORTED ); - ExFreePoolWithTag(CurNCE, NCE_TAG); + exFreePool(CurNCE); break; } diff --git a/reactos/lib/drivers/ip/network/ports.c b/reactos/lib/drivers/ip/network/ports.c index cd9dbd2f05f..c8b0835c0f1 100644 --- a/reactos/lib/drivers/ip/network/ports.c +++ b/reactos/lib/drivers/ip/network/ports.c @@ -17,8 +17,7 @@ NTSTATUS PortsStartup( PPORT_SET PortSet, PortSet->PortsToOversee = PortsToManage; PortSet->ProtoBitBuffer = - ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8, - PORT_SET_TAG ); + exAllocatePool( NonPagedPool, (PortSet->PortsToOversee + 7) / 8 ); if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES; RtlInitializeBitMap( &PortSet->ProtoBitmap, PortSet->ProtoBitBuffer, @@ -29,7 +28,7 @@ NTSTATUS PortsStartup( PPORT_SET PortSet, } VOID PortsShutdown( PPORT_SET PortSet ) { - ExFreePoolWithTag( PortSet->ProtoBitBuffer, PORT_SET_TAG ); + exFreePool( PortSet->ProtoBitBuffer ); } VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) { diff --git a/reactos/lib/drivers/ip/network/receive.c b/reactos/lib/drivers/ip/network/receive.c index afdca21600f..174b647abfd 100644 --- a/reactos/lib/drivers/ip/network/receive.c +++ b/reactos/lib/drivers/ip/network/receive.c @@ -35,7 +35,7 @@ PIPDATAGRAM_HOLE CreateHoleDescriptor( TI_DbgPrint(DEBUG_IP, ("Called. First (%d) Last (%d).\n", First, Last)); - Hole = ExAllocateFromNPagedLookasideList(&IPHoleList); + Hole = exAllocateFromNPagedLookasideList(&IPHoleList); if (!Hole) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; @@ -76,7 +76,7 @@ VOID FreeIPDR( TI_DbgPrint(DEBUG_IP, ("Freeing hole descriptor at (0x%X).\n", CurrentH)); /* And free the hole descriptor */ - ExFreeToNPagedLookasideList(&IPHoleList, CurrentH); + exFreeToNPagedLookasideList(&IPHoleList, CurrentH); CurrentEntry = NextEntry; } @@ -92,18 +92,18 @@ VOID FreeIPDR( TI_DbgPrint(DEBUG_IP, ("Freeing fragment data at (0x%X).\n", CurrentF->Data)); /* Free the fragment data buffer */ - ExFreePoolWithTag(CurrentF->Data, FRAGMENT_DATA_TAG); + exFreePool(CurrentF->Data); TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF)); /* And free the fragment descriptor */ - ExFreeToNPagedLookasideList(&IPFragmentList, CurrentF); + exFreeToNPagedLookasideList(&IPFragmentList, CurrentF); CurrentEntry = NextEntry; } TI_DbgPrint(DEBUG_IP, ("Freeing IPDR data at (0x%X).\n", IPDR)); - ExFreeToNPagedLookasideList(&IPDRList, IPDR); + exFreeToNPagedLookasideList(&IPDRList, IPDR); } @@ -205,7 +205,7 @@ ReassembleDatagram( RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS)); /* Allocate space for full IP datagram */ - IPPacket->Header = ExAllocatePoolWithTag(NonPagedPool, IPPacket->TotalSize, PACKET_BUFFER_TAG); + IPPacket->Header = exAllocatePool(NonPagedPool, IPPacket->TotalSize); if (!IPPacket->Header) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); (*IPPacket->Free)(IPPacket); @@ -297,7 +297,7 @@ VOID ProcessFragment( TI_DbgPrint(DEBUG_IP, ("Starting new assembly.\n")); /* We don't have a reassembly structure, create one */ - IPDR = ExAllocateFromNPagedLookasideList(&IPDRList); + IPDR = exAllocateFromNPagedLookasideList(&IPDRList); if (!IPDR) /* We don't have the resources to process this packet, discard it */ return; @@ -308,7 +308,7 @@ VOID ProcessFragment( Hole = CreateHoleDescriptor(0, 65536); if (!Hole) { /* We don't have the resources to process this packet, discard it */ - ExFreeToNPagedLookasideList(&IPDRList, IPDR); + exFreeToNPagedLookasideList(&IPDRList, IPDR); return; } AddrInitIPv4(&IPDR->SrcAddr, IPv4Header->SrcAddr); @@ -361,7 +361,7 @@ VOID ProcessFragment( NewHole = CreateHoleDescriptor(Hole->First, FragFirst - 1); if (!NewHole) { /* We don't have the resources to process this packet, discard it */ - ExFreeToNPagedLookasideList(&IPHoleList, Hole); + exFreeToNPagedLookasideList(&IPHoleList, Hole); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -374,7 +374,7 @@ VOID ProcessFragment( NewHole = CreateHoleDescriptor(FragLast + 1, Hole->Last); if (!NewHole) { /* We don't have the resources to process this packet, discard it */ - ExFreeToNPagedLookasideList(&IPHoleList, Hole); + exFreeToNPagedLookasideList(&IPHoleList, Hole); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -383,7 +383,7 @@ VOID ProcessFragment( InsertTailList(&IPDR->HoleListHead, &NewHole->ListEntry); } - ExFreeToNPagedLookasideList(&IPHoleList, Hole); + exFreeToNPagedLookasideList(&IPHoleList, Hole); /* If this is the first fragment, save the IP header */ if (FragFirst == 0) { @@ -397,7 +397,7 @@ VOID ProcessFragment( /* Create a buffer, copy the data into it and put it in the fragment list */ - Fragment = ExAllocateFromNPagedLookasideList(&IPFragmentList); + Fragment = exAllocateFromNPagedLookasideList(&IPFragmentList); if (!Fragment) { /* We don't have the resources to process this packet, discard it */ Cleanup(&IPDR->Lock, OldIrql, IPDR); @@ -407,10 +407,10 @@ VOID ProcessFragment( TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment)); Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize; - Fragment->Data = ExAllocatePoolWithTag(NonPagedPool, Fragment->Size, FRAGMENT_DATA_TAG); + Fragment->Data = exAllocatePool(NonPagedPool, Fragment->Size); if (!Fragment->Data) { /* We don't have the resources to process this packet, discard it */ - ExFreeToNPagedLookasideList(&IPFragmentList, Fragment); + exFreeToNPagedLookasideList(&IPFragmentList, Fragment); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -465,7 +465,7 @@ VOID ProcessFragment( IF->Stats.InBytes += Datagram.TotalSize; /* We're done with this datagram */ - ExFreePoolWithTag(Datagram.Header, PACKET_BUFFER_TAG); + exFreePool(Datagram.Header); TI_DbgPrint(MAX_TRACE, ("Freeing datagram at (0x%X).\n", Datagram)); (*Datagram.Free)(&Datagram); } else diff --git a/reactos/lib/drivers/ip/network/router.c b/reactos/lib/drivers/ip/network/router.c index d5411240549..c2b79a2f968 100644 --- a/reactos/lib/drivers/ip/network/router.c +++ b/reactos/lib/drivers/ip/network/router.c @@ -51,7 +51,7 @@ VOID FreeFIB( * Object = Pointer to an forward information base structure */ { - ExFreePoolWithTag(Object, FIB_TAG); + exFreePool(Object); } @@ -217,12 +217,14 @@ PFIB_ENTRY RouterAddRoute( A2S(Netmask), A2S(&Router->Address))); - FIBE = ExAllocatePoolWithTag(NonPagedPool, sizeof(FIB_ENTRY), FIB_TAG); + FIBE = exAllocatePool(NonPagedPool, sizeof(FIB_ENTRY)); if (!FIBE) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } + INIT_TAG(Router, 'TUOR'); + RtlCopyMemory( &FIBE->NetworkAddress, NetworkAddress, sizeof(FIBE->NetworkAddress) ); RtlCopyMemory( &FIBE->Netmask, Netmask, diff --git a/reactos/lib/drivers/ip/network/routines.c b/reactos/lib/drivers/ip/network/routines.c index 44aa2761076..6407ecb25c7 100644 --- a/reactos/lib/drivers/ip/network/routines.c +++ b/reactos/lib/drivers/ip/network/routines.c @@ -115,11 +115,11 @@ VOID DisplayTCPPacket( if (IPPacket->NdisPacket) { NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length); - Buffer = ExAllocatePool(NonPagedPool, Length); + Buffer = exAllocatePool(NonPagedPool, Length); if (Buffer) { Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, 0, Length); DisplayTCPHeader(Buffer, Length); - ExFreePool(Buffer); + exFreePool(Buffer); } } else { Buffer = IPPacket->Header; diff --git a/reactos/lib/drivers/ip/network/transmit.c b/reactos/lib/drivers/ip/network/transmit.c index b97318223f2..554f5778cbf 100644 --- a/reactos/lib/drivers/ip/network/transmit.c +++ b/reactos/lib/drivers/ip/network/transmit.c @@ -42,7 +42,7 @@ VOID IPSendComplete { FreeNdisPacket(IFC->NdisPacket); IFC->Complete(IFC->Context, IFC->Datagram, Status); - ExFreePoolWithTag(IFC, IFC_TAG); + exFreePool(IFC); } } else { TI_DbgPrint(MAX_TRACE, ("Calling completion handler.\n")); @@ -50,7 +50,7 @@ VOID IPSendComplete /* There are no more fragments to transmit, so call completion handler */ FreeNdisPacket(IFC->NdisPacket); IFC->Complete(IFC->Context, IFC->Datagram, NdisStatus); - ExFreePoolWithTag(IFC, IFC_TAG); + exFreePool(IFC); } } @@ -178,7 +178,7 @@ NTSTATUS SendFragments( TI_DbgPrint(MAX_TRACE, ("Fragment buffer is %d bytes\n", BufferSize)); - IFC = ExAllocatePoolWithTag(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT), IFC_TAG); + IFC = exAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT)); if (IFC == NULL) return STATUS_INSUFFICIENT_RESOURCES; @@ -187,7 +187,7 @@ NTSTATUS SendFragments( ( &IFC->NdisPacket, NULL, BufferSize ); if( !NT_SUCCESS(NdisStatus) ) { - ExFreePoolWithTag( IFC, IFC_TAG ); + exFreePool( IFC ); return NdisStatus; } @@ -215,14 +215,14 @@ NTSTATUS SendFragments( if (!PrepareNextFragment(IFC)) { FreeNdisPacket(IFC->NdisPacket); - ExFreePoolWithTag(IFC, IFC_TAG); + exFreePool(IFC); return NDIS_STATUS_FAILURE; } if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC)))) { FreeNdisPacket(IFC->NdisPacket); - ExFreePoolWithTag(IFC, IFC_TAG); + exFreePool(IFC); } return NdisStatus; diff --git a/reactos/lib/drivers/ip/transport/datagram/datagram.c b/reactos/lib/drivers/ip/transport/datagram/datagram.c index 3c92aa26002..70660605950 100644 --- a/reactos/lib/drivers/ip/transport/datagram/datagram.c +++ b/reactos/lib/drivers/ip/transport/datagram/datagram.c @@ -10,14 +10,13 @@ #include "precomp.h" -BOOLEAN DGRemoveIRP( +VOID DGRemoveIRP( PADDRESS_FILE AddrFile, PIRP Irp) { PLIST_ENTRY ListEntry; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; KIRQL OldIrql; - BOOLEAN Found = FALSE; TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n", Irp, AddrFile)); @@ -36,8 +35,7 @@ BOOLEAN DGRemoveIRP( if (ReceiveRequest->Irp == Irp) { RemoveEntryList(&ReceiveRequest->ListEntry); - ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); - Found = TRUE; + exFreePool(ReceiveRequest); break; } } @@ -45,8 +43,6 @@ BOOLEAN DGRemoveIRP( KeReleaseSpinLock(&AddrFile->Lock, OldIrql); TI_DbgPrint(MAX_TRACE, ("Done.\n")); - - return Found; } VOID DGDeliverData( @@ -83,7 +79,7 @@ VOID DGDeliverData( TI_DbgPrint(MAX_TRACE, ("Called.\n")); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); if (AddrFile->Protocol == IPPROTO_UDP) { @@ -140,7 +136,7 @@ VOID DGDeliverData( &SrcAddress->Address.IPv4Address, sizeof(SrcAddress->Address.IPv4Address) ); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); /* Complete the receive request */ if (Current->BufferSize < DataSize) @@ -148,11 +144,11 @@ VOID DGDeliverData( else Current->Complete(Current->Context, STATUS_SUCCESS, DataSize); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); } } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); } else if (AddrFile->RegisteredReceiveDatagramHandler) { @@ -161,6 +157,8 @@ VOID DGDeliverData( ReceiveHandler = AddrFile->ReceiveDatagramHandler; HandlerContext = AddrFile->ReceiveDatagramHandlerContext; + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + if (SrcAddress->Type == IP_ADDRESS_V4) { AddressLength = sizeof(IPv4_RAW_ADDRESS); @@ -172,8 +170,6 @@ VOID DGDeliverData( SourceAddress = SrcAddress->Address.IPv6Address; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - Status = (*ReceiveHandler)(HandlerContext, AddressLength, SourceAddress, @@ -188,7 +184,7 @@ VOID DGDeliverData( } else { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n")); } @@ -201,7 +197,7 @@ VOID DGReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count) { (PDATAGRAM_RECEIVE_REQUEST)Context; TI_DbgPrint(MAX_TRACE,("Called (%08x:%08x)\n", Status, Count)); ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status, Count ); - ExFreePoolWithTag( ReceiveRequest, DATAGRAM_RECV_TAG ); + exFreePool( ReceiveRequest ); TI_DbgPrint(MAX_TRACE,("Done\n")); } @@ -232,68 +228,76 @@ NTSTATUS DGReceiveDatagram( * This is the high level interface for receiving DG datagrams */ { + KIRQL OldIrql; NTSTATUS Status; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; - KIRQL OldIrql; TI_DbgPrint(MAX_TRACE, ("Called.\n")); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - ReceiveRequest = ExAllocatePoolWithTag(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST), - DATAGRAM_RECV_TAG); - if (ReceiveRequest) + if (AF_IS_VALID(AddrFile)) { - /* Initialize a receive request */ - - /* Extract the remote address filter from the request (if any) */ - if ((ConnInfo->RemoteAddressLength != 0) && - (ConnInfo->RemoteAddress)) + ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST)); + if (ReceiveRequest) { - Status = AddrGetAddress(ConnInfo->RemoteAddress, - &ReceiveRequest->RemoteAddress, - &ReceiveRequest->RemotePort); - if (!NT_SUCCESS(Status)) + /* Initialize a receive request */ + + /* Extract the remote address filter from the request (if any) */ + if ((ConnInfo->RemoteAddressLength != 0) && + (ConnInfo->RemoteAddress)) { - ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - return Status; + Status = AddrGetAddress(ConnInfo->RemoteAddress, + &ReceiveRequest->RemoteAddress, + &ReceiveRequest->RemotePort); + if (!NT_SUCCESS(Status)) + { + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + exFreePool(ReceiveRequest); + return Status; + } } - } + else + { + ReceiveRequest->RemotePort = 0; + AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0); + } + + IoMarkIrpPending(Irp); + + ReceiveRequest->ReturnInfo = ReturnInfo; + ReceiveRequest->Buffer = BufferData; + ReceiveRequest->BufferSize = ReceiveLength; + ReceiveRequest->UserComplete = Complete; + ReceiveRequest->UserContext = Context; + ReceiveRequest->Complete = + (PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete; + ReceiveRequest->Context = ReceiveRequest; + ReceiveRequest->AddressFile = AddrFile; + ReceiveRequest->Irp = Irp; + + /* Queue receive request */ + InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry); + AF_SET_PENDING(AddrFile, AFF_RECEIVE); + + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + + TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); + + return STATUS_PENDING; + } else { - ReceiveRequest->RemotePort = 0; - AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0); + Status = STATUS_INSUFFICIENT_RESOURCES; } - - IoMarkIrpPending(Irp); - - ReceiveRequest->ReturnInfo = ReturnInfo; - ReceiveRequest->Buffer = BufferData; - ReceiveRequest->BufferSize = ReceiveLength; - ReceiveRequest->UserComplete = Complete; - ReceiveRequest->UserContext = Context; - ReceiveRequest->Complete = - (PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete; - ReceiveRequest->Context = ReceiveRequest; - ReceiveRequest->AddressFile = AddrFile; - ReceiveRequest->Irp = Irp; - - /* Queue receive request */ - InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry); - - TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); - - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - - return STATUS_PENDING; } else { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - Status = STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_INVALID_ADDRESS; } + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status)); return Status; diff --git a/reactos/lib/drivers/ip/transport/rawip/rawip.c b/reactos/lib/drivers/ip/transport/rawip/rawip.c index 328337cdb38..f7b9b6dbec9 100644 --- a/reactos/lib/drivers/ip/transport/rawip/rawip.c +++ b/reactos/lib/drivers/ip/transport/rawip/rawip.c @@ -195,9 +195,6 @@ NTSTATUS RawIPSendDatagram( USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; - - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -212,17 +209,13 @@ NTSTATUS RawIPSendDatagram( break; default: - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_UNSUCCESSFUL; } TI_DbgPrint(MID_TRACE,("About to get route to destination\n")); if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) - { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_NETWORK_UNREACHABLE; - } LocalAddress = AddrFile->Address; if (AddrIsUnspecified(&LocalAddress)) @@ -244,24 +237,18 @@ NTSTATUS RawIPSendDatagram( DataSize ); if( !NT_SUCCESS(Status) ) - { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; - } TI_DbgPrint(MID_TRACE,("About to send datagram\n")); if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } TI_DbgPrint(MID_TRACE,("Leaving\n")); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - return STATUS_SUCCESS; } diff --git a/reactos/lib/drivers/ip/transport/tcp/accept.c b/reactos/lib/drivers/ip/transport/tcp/accept.c index 059d109af73..ee1f3bf38d0 100644 --- a/reactos/lib/drivers/ip/transport/tcp/accept.c +++ b/reactos/lib/drivers/ip/transport/tcp/accept.c @@ -10,7 +10,6 @@ #include "precomp.h" -/* Listener->Lock MUST be acquired */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection, PTDI_REQUEST_KERNEL Request ) { @@ -20,6 +19,8 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PTA_IP_ADDRESS RequestAddressReturn; PTDI_CONNECTION_INFORMATION WhoIsConnecting; + ASSERT_LOCKED(&TCPLock); + /* Unpack TDI info -- We need the return connection information * struct to return the address so it can be filtered if needed * by WSAAccept -- The returned address will be passed on to @@ -30,7 +31,6 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, Status = TCPTranslateError ( OskitTCPAccept( Listener->SocketContext, &Connection->SocketContext, - Connection, &OutAddr, sizeof(OutAddr), &OutAddrLen, @@ -69,14 +69,13 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { NTSTATUS Status = STATUS_SUCCESS; SOCKADDR_IN AddressToBind; - KIRQL OldIrql; + + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); ASSERT(Connection); ASSERT_KM_POINTER(Connection->SocketContext); ASSERT_KM_POINTER(Connection->AddressFile); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - TI_DbgPrint(DEBUG_TCP,("TCPListen started\n")); TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", @@ -97,19 +96,18 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { if (NT_SUCCESS(Status)) Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + TcpipRecursiveMutexLeave( &TCPLock ); TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status)); return Status; } -BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, +VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection ) { PLIST_ENTRY ListEntry; PTDI_BUCKET Bucket; KIRQL OldIrql; - BOOLEAN Found = FALSE; KeAcquireSpinLock(&Listener->Lock, &OldIrql); @@ -119,8 +117,7 @@ BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, if( Bucket->AssociatedEndpoint == Connection ) { RemoveEntryList( &Bucket->Entry ); - ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG ); - Found = TRUE; + exFreePool( Bucket ); break; } @@ -128,8 +125,6 @@ BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, } KeReleaseSpinLock(&Listener->Lock, OldIrql); - - return Found; } NTSTATUS TCPAccept ( PTDI_REQUEST Request, @@ -140,27 +135,25 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request, { NTSTATUS Status; PTDI_BUCKET Bucket; - KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n")); - KeAcquireSpinLock(&Listener->Lock, &OldIrql); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); Status = TCPServiceListeningSocket( Listener, Connection, (PTDI_REQUEST_KERNEL)Request ); - KeReleaseSpinLock(&Listener->Lock, OldIrql); + TcpipRecursiveMutexLeave( &TCPLock ); if( Status == STATUS_PENDING ) { - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), - TDI_BUCKET_TAG ); + Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); if( Bucket ) { Bucket->AssociatedEndpoint = Connection; Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; - ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, - &Listener->Lock ); + IoMarkIrpPending((PIRP)Context); + ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, &Listener->Lock ); } else Status = STATUS_NO_MEMORY; } diff --git a/reactos/lib/drivers/ip/transport/tcp/event.c b/reactos/lib/drivers/ip/transport/tcp/event.c index f3d5a145597..81cdbbb0ffd 100644 --- a/reactos/lib/drivers/ip/transport/tcp/event.c +++ b/reactos/lib/drivers/ip/transport/tcp/event.c @@ -16,33 +16,36 @@ int TCPSocketState(void *ClientData, OSK_UINT NewState ) { PCONNECTION_ENDPOINT Connection = WhichConnection; - TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n", - Connection, + ASSERT_LOCKED(&TCPLock); + + TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n", NewState & SEL_CONNECT ? 'C' : 'c', NewState & SEL_READ ? 'R' : 'r', NewState & SEL_FIN ? 'F' : 'f', - NewState & SEL_ACCEPT ? 'A' : 'a', - NewState & SEL_WRITE ? 'W' : 'w')); - - if (!Connection) - { - return 0; - } - - if (ClientInfo.Unlocked) - KeAcquireSpinLockAtDpcLevel(&Connection->Lock); + NewState & SEL_ACCEPT ? 'A' : 'a')); TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n", NewState, Connection, - Connection->SignalState ^ NewState, + Connection ? Connection->State ^ NewState : NewState)); + if( !Connection ) { + TI_DbgPrint(DEBUG_TCP,("Socket closing.\n")); + Connection = FileFindConnectionByContext( WhichSocket ); + if( !Connection ) + return 0; + else + TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection)); + } + + TI_DbgPrint(MID_TRACE,("Connection signalled: %d\n", + Connection->Signalled)); + Connection->SignalState |= NewState; - - HandleSignalledConnection(Connection); - - if (ClientInfo.Unlocked) - KeReleaseSpinLockFromDpcLevel(&Connection->Lock); + if( !Connection->Signalled ) { + Connection->Signalled = TRUE; + ExInterlockedInsertTailList( &SignalledConnectionsList, &Connection->SignalList, &SignalledConnectionsLock ); + } return 0; } @@ -64,6 +67,8 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { IP_ADDRESS RemoteAddress, LocalAddress; PIPv4_HEADER Header; + ASSERT_LOCKED(&TCPLock); + if( *data == 0x45 ) { /* IPv4 */ Header = (PIPv4_HEADER)data; LocalAddress.Type = IP_ADDRESS_V4; @@ -107,6 +112,74 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { return 0; } +int TCPSleep( void *ClientData, void *token, int priority, char *msg, + int tmio ) { + PSLEEPING_THREAD SleepingThread; + LARGE_INTEGER Timeout; + + ASSERT_LOCKED(&TCPLock); + + TI_DbgPrint(DEBUG_TCP, + ("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n", + token, priority, msg, tmio)); + + SleepingThread = exAllocatePool( NonPagedPool, sizeof( *SleepingThread ) ); + if( SleepingThread ) { + KeInitializeEvent( &SleepingThread->Event, NotificationEvent, FALSE ); + SleepingThread->SleepToken = token; + + /* We're going to sleep and need to release the lock, otherwise + it's impossible to re-enter oskittcp to deliver the event that's + going to wake us */ + TcpipRecursiveMutexLeave( &TCPLock ); + + TcpipAcquireFastMutex( &SleepingThreadsLock ); + InsertTailList( &SleepingThreadsList, &SleepingThread->Entry ); + TcpipReleaseFastMutex( &SleepingThreadsLock ); + + Timeout.QuadPart = Int32x32To64(tmio, -10000); + + TI_DbgPrint(DEBUG_TCP,("Waiting on %x\n", token)); + KeWaitForSingleObject( &SleepingThread->Event, + Executive, + KernelMode, + TRUE, + (tmio != 0) ? &Timeout : NULL ); + + TcpipAcquireFastMutex( &SleepingThreadsLock ); + RemoveEntryList( &SleepingThread->Entry ); + TcpipReleaseFastMutex( &SleepingThreadsLock ); + + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + + exFreePool( SleepingThread ); + } else + return OSK_ENOBUFS; + + TI_DbgPrint(DEBUG_TCP,("Waiting finished: %x\n", token)); + return 0; +} + +void TCPWakeup( void *ClientData, void *token ) { + PLIST_ENTRY Entry; + PSLEEPING_THREAD SleepingThread; + + ASSERT_LOCKED(&TCPLock); + + TcpipAcquireFastMutex( &SleepingThreadsLock ); + Entry = SleepingThreadsList.Flink; + while( Entry != &SleepingThreadsList ) { + SleepingThread = CONTAINING_RECORD(Entry, SLEEPING_THREAD, Entry); + TI_DbgPrint(DEBUG_TCP,("Sleeper @ %x\n", SleepingThread)); + if( SleepingThread->SleepToken == token ) { + TI_DbgPrint(DEBUG_TCP,("Setting event to wake %x\n", token)); + KeSetEvent( &SleepingThread->Event, IO_NETWORK_INCREMENT, FALSE ); + } + Entry = Entry->Flink; + } + TcpipReleaseFastMutex( &SleepingThreadsLock ); +} + /* Memory management routines * * By far the most requests for memory are either for 128 or 2048 byte blocks, @@ -126,6 +199,8 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { #define SIGNATURE_LARGE 'LLLL' #define SIGNATURE_SMALL 'SSSS' #define SIGNATURE_OTHER 'OOOO' +#define TCP_TAG ' PCT' + static NPAGED_LOOKASIDE_LIST LargeLookasideList; static NPAGED_LOOKASIDE_LIST SmallLookasideList; @@ -137,14 +212,14 @@ TCPMemStartup( void ) NULL, 0, LARGE_SIZE + sizeof( ULONG ), - OSK_LARGE_TAG, + TCP_TAG, 0 ); ExInitializeNPagedLookasideList( &SmallLookasideList, NULL, NULL, 0, SMALL_SIZE + sizeof( ULONG ), - OSK_SMALL_TAG, + TCP_TAG, 0 ); return STATUS_SUCCESS; @@ -155,6 +230,8 @@ void *TCPMalloc( void *ClientData, void *v; ULONG Signature; + ASSERT_LOCKED(&TCPLock); + #if 0 != MEM_PROFILE static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0; static OSK_UINT ArrayUsed = 0, AllocationCount = 0; @@ -214,13 +291,13 @@ void *TCPMalloc( void *ClientData, v = ExAllocateFromNPagedLookasideList( &LargeLookasideList ); Signature = SIGNATURE_LARGE; } else { - v = ExAllocatePoolWithTag( NonPagedPool, Bytes + sizeof(ULONG), - OSK_OTHER_TAG ); + v = ExAllocatePool( NonPagedPool, Bytes + sizeof(ULONG) ); Signature = SIGNATURE_OTHER; } if( v ) { *((ULONG *) v) = Signature; v = (void *)((char *) v + sizeof(ULONG)); + TrackWithTag( FOURCC('f','b','s','d'), v, (PCHAR)File, Line ); } return v; @@ -230,6 +307,9 @@ void TCPFree( void *ClientData, void *data, OSK_PCHAR File, OSK_UINT Line ) { ULONG Signature; + ASSERT_LOCKED(&TCPLock); + + UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') ); data = (void *)((char *) data - sizeof(ULONG)); Signature = *((ULONG *) data); if ( SIGNATURE_SMALL == Signature ) { @@ -237,7 +317,7 @@ void TCPFree( void *ClientData, } else if ( SIGNATURE_LARGE == Signature ) { ExFreeToNPagedLookasideList( &LargeLookasideList, data ); } else if ( SIGNATURE_OTHER == Signature ) { - ExFreePoolWithTag( data, OSK_OTHER_TAG ); + ExFreePool( data ); } else { ASSERT( FALSE ); } diff --git a/reactos/lib/drivers/ip/transport/tcp/if.c b/reactos/lib/drivers/ip/transport/tcp/if.c index 0e5296425d1..d9598aff798 100644 --- a/reactos/lib/drivers/ip/transport/tcp/if.c +++ b/reactos/lib/drivers/ip/transport/tcp/if.c @@ -37,6 +37,8 @@ POSK_IFADDR TCPGetInterfaceData( PIP_INTERFACE IF ) { struct sockaddr_in *dstaddr_in; ASSERT(ifaddr); + ASSERT_LOCKED(&TCPLock); + RtlZeroMemory(ifaddr, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in )); addr_in = (struct sockaddr_in *)&ifaddr[1]; @@ -79,6 +81,8 @@ POSK_IFADDR TCPFindInterface( void *ClientData, struct sockaddr_in *addr_in = (struct sockaddr_in *)ReqAddr; POSK_IFADDR InterfaceData; + ASSERT_LOCKED(&TCPLock); + TI_DbgPrint(DEBUG_TCPIF,("called for type %d\n", FindType)); if( !ReqAddr ) { diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index fe571126379..67685366bcf 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -15,308 +15,291 @@ LONG TCP_IPIdentification = 0; static BOOLEAN TCPInitialized = FALSE; static NPAGED_LOOKASIDE_LIST TCPSegmentList; +LIST_ENTRY SignalledConnectionsList; +KSPIN_LOCK SignalledConnectionsLock; +LIST_ENTRY SleepingThreadsList; +FAST_MUTEX SleepingThreadsLock; +RECURSIVE_MUTEX TCPLock; PORT_SET TCPPorts; -CLIENT_DATA ClientInfo; -static VOID -ProcessCompletions(PCONNECTION_ENDPOINT Connection) -{ - PLIST_ENTRY CurrentEntry; - PTDI_BUCKET Bucket; +static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { + NTSTATUS Status = STATUS_SUCCESS; PTCP_COMPLETION_ROUTINE Complete; + PTDI_BUCKET Bucket; + PLIST_ENTRY Entry; + PIRP Irp; + PMDL Mdl; - while ((CurrentEntry = ExInterlockedRemoveHeadList(&Connection->CompletionQueue, - &Connection->Lock))) - { - Bucket = CONTAINING_RECORD(CurrentEntry, TDI_BUCKET, Entry); - Complete = Bucket->Request.RequestNotifyObject; + ASSERT_LOCKED(&TCPLock); - Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information); + TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", + Connection, Connection->SocketContext)); - ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG); - } + if( Connection->SignalState & SEL_FIN ) { + TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - if (!Connection->SocketContext) - TCPFreeConnectionEndpoint(Connection); -} + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; -VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) -{ - PTDI_BUCKET Bucket; - PLIST_ENTRY Entry; - NTSTATUS Status; - PIRP Irp; - PMDL Mdl; - ULONG SocketError = 0; + /* We have to notify oskittcp of the abortion */ + TCPDisconnect + ( Connection, + TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT, + NULL, + NULL, + Bucket->Request.RequestNotifyObject, + (PIRP)Bucket->Request.RequestContext ); - TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", - Connection, Connection->SocketContext)); + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) { - TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - - /* If OskitTCP initiated the disconnect, try to read the socket error that occurred */ - if (Connection->SocketContext) - SocketError = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext)); - - /* Default to STATUS_CANCELLED if we initiated the disconnect or no socket error was reported */ - if (!Connection->SocketContext || !SocketError) - SocketError = STATUS_CANCELLED; - - while (!IsListEmpty(&Connection->ReceiveRequest)) - { - Entry = RemoveHeadList( &Connection->ReceiveRequest ); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = SocketError; - Bucket->Information = 0; - - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - - while (!IsListEmpty(&Connection->SendRequest)) - { - Entry = RemoveHeadList( &Connection->SendRequest ); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = SocketError; - Bucket->Information = 0; - - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - - while (!IsListEmpty(&Connection->ListenRequest)) - { - Entry = RemoveHeadList( &Connection->ListenRequest ); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = SocketError; - Bucket->Information = 0; - - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - - while (!IsListEmpty(&Connection->ConnectRequest)) - { - Entry = RemoveHeadList( &Connection->ConnectRequest ); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = SocketError; - Bucket->Information = 0; - - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - - Connection->SignalState = 0; + exFreePool(Bucket); } - /* Things that can happen when we try the initial connection */ - if( Connection->SignalState & SEL_CONNECT ) { - while (!IsListEmpty(&Connection->ConnectRequest)) { - Entry = RemoveHeadList( &Connection->ConnectRequest ); + while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + /* We have to notify oskittcp of the abortion */ + TCPDisconnect + ( Connection, + TDI_DISCONNECT_RELEASE, + NULL, + NULL, + Bucket->Request.RequestNotifyObject, + (PIRP)Bucket->Request.RequestContext ); - Bucket->Status = STATUS_SUCCESS; - Bucket->Information = 0; + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - } + exFreePool(Bucket); + } - if( Connection->SignalState & SEL_ACCEPT ) { - /* Handle readable on a listening socket -- - * TODO: Implement filtering - */ - TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", - Connection, - IsListEmpty(&Connection->ListenRequest) ? - "empty" : "nonempty")); + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - while (!IsListEmpty(&Connection->ListenRequest)) { - PIO_STACK_LOCATION IrpSp; + /* We have to notify oskittcp of the abortion */ + TCPAbortListenForSocket(Connection->AddressFile->Listener, + Connection); - Entry = RemoveHeadList( &Connection->ListenRequest ); + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + } - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - Irp = Bucket->Request.RequestContext; - IrpSp = IoGetCurrentIrpStackLocation( Irp ); + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + } - TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); + Connection->SignalState = 0; + } - Status = TCPServiceListeningSocket - ( Connection->AddressFile->Listener, - Bucket->AssociatedEndpoint, - (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); + /* Things that can happen when we try the initial connection */ + if( Connection->SignalState & SEL_CONNECT ) { + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, + &Connection->Lock )) != NULL ) { + + TI_DbgPrint(DEBUG_TCP, ("Connect Event\n")); - TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + TI_DbgPrint(DEBUG_TCP, + ("Completing Request %x\n", Bucket->Request.RequestContext)); - if( Status == STATUS_PENDING ) { - InsertHeadList( &Connection->ListenRequest, &Bucket->Entry ); - break; - } else { - Bucket->Status = Status; - Bucket->Information = 0; + Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - } - } + /* Frees the bucket allocated in TCPConnect */ + exFreePool( Bucket ); + } + } - /* Things that happen after we're connected */ - if( Connection->SignalState & SEL_READ ) { - TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", - IsListEmpty(&Connection->ReceiveRequest) ? - "empty" : "nonempty")); + if( Connection->SignalState & SEL_ACCEPT ) { + /* Handle readable on a listening socket -- + * TODO: Implement filtering + */ - while (!IsListEmpty(&Connection->ReceiveRequest)) { - OSK_UINT RecvLen = 0, Received = 0; - PVOID RecvBuffer = 0; + TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", + Connection, + IsListEmpty(&Connection->ListenRequest) ? + "empty" : "nonempty")); - Entry = RemoveHeadList( &Connection->ReceiveRequest ); + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, + &Connection->Lock )) != NULL ) { + PIO_STACK_LOCATION IrpSp; - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; + Irp = Bucket->Request.RequestContext; + IrpSp = IoGetCurrentIrpStackLocation( Irp ); - TI_DbgPrint(DEBUG_TCP, - ("Getting the user buffer from %x\n", Mdl)); + TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); + Status = TCPServiceListeningSocket + ( Connection->AddressFile->Listener, + Bucket->AssociatedEndpoint, + (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); - NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); + TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); - TI_DbgPrint(DEBUG_TCP, - ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); + if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock ); + break; + } else { + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + } - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint - (DEBUG_TCP, - ("Connection->SocketContext: %x\n", - Connection->SocketContext)); - TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); + /* Things that happen after we're connected */ + if( Connection->SignalState & SEL_READ ) { + TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", + IsListEmpty(&Connection->ReceiveRequest) ? + "empty" : "nonempty")); - Status = TCPTranslateError - ( OskitTCPRecv( Connection->SocketContext, - RecvBuffer, - RecvLen, - &Received, - 0 ) ); + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, + &Connection->Lock )) != NULL ) { + OSK_UINT RecvLen = 0, Received = 0; + PVOID RecvBuffer = 0; - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - if( Status == STATUS_PENDING ) { - InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry ); - break; - } else { - TI_DbgPrint(DEBUG_TCP, - ("Completing Receive request: %x %x\n", - Bucket->Request, Status)); + Irp = Bucket->Request.RequestContext; + Mdl = Irp->MdlAddress; - Bucket->Status = Status; - Bucket->Information = (Status == STATUS_SUCCESS) ? Received : 0; + TI_DbgPrint(DEBUG_TCP, + ("Getting the user buffer from %x\n", Mdl)); - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - } - } - if( Connection->SignalState & SEL_WRITE ) { - TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", - IsListEmpty(&Connection->SendRequest) ? - "empty" : "nonempty")); + NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); - while (!IsListEmpty(&Connection->SendRequest)) { - OSK_UINT SendLen = 0, Sent = 0; - PVOID SendBuffer = 0; + TI_DbgPrint(DEBUG_TCP, + ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); - Entry = RemoveHeadList( &Connection->SendRequest ); + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint + (DEBUG_TCP, + ("Connection->SocketContext: %x\n", + Connection->SocketContext)); + TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Status = TCPTranslateError + ( OskitTCPRecv( Connection->SocketContext, + RecvBuffer, + RecvLen, + &Received, + 0 ) ); - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); - TI_DbgPrint(DEBUG_TCP, - ("Getting the user buffer from %x\n", Mdl)); + if( Status == STATUS_SUCCESS ) { + TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", + Received, Status)); - NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Received ); + exFreePool( Bucket ); + } else if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList + ( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Receive request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + } + if( Connection->SignalState & SEL_WRITE ) { + TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", + IsListEmpty(&Connection->SendRequest) ? + "empty" : "nonempty")); - TI_DbgPrint(DEBUG_TCP, - ("Writing %d bytes to %x\n", SendLen, SendBuffer)); + while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, + &Connection->Lock )) != NULL ) { + OSK_UINT SendLen = 0, Sent = 0; + PVOID SendBuffer = 0; - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Irp = Bucket->Request.RequestContext; + Mdl = Irp->MdlAddress; + + TI_DbgPrint(DEBUG_TCP, + ("Getting the user buffer from %x\n", Mdl)); + + NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); + + TI_DbgPrint(DEBUG_TCP, + ("Writing %d bytes to %x\n", SendLen, SendBuffer)); + + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint (DEBUG_TCP, ("Connection->SocketContext: %x\n", Connection->SocketContext)); - Status = TCPTranslateError - ( OskitTCPSend( Connection->SocketContext, - SendBuffer, - SendLen, - &Sent, - 0 ) ); + Status = TCPTranslateError + ( OskitTCPSend( Connection->SocketContext, + SendBuffer, + SendLen, + &Sent, + 0 ) ); - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); - if( Status == STATUS_PENDING ) { - InsertHeadList( &Connection->SendRequest, &Bucket->Entry ); - break; - } else { - TI_DbgPrint(DEBUG_TCP, - ("Completing Send request: %x %x\n", - Bucket->Request, Status)); + if( Status == STATUS_SUCCESS ) { + TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n", + Sent, Status)); - Bucket->Status = Status; - Bucket->Information = (Status == STATUS_SUCCESS) ? Sent : 0; + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Sent ); + exFreePool( Bucket ); + } else if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList + ( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Send request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + } - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - } - } + Connection->SignalState = 0; + Connection->Signalled = FALSE; } -static -VOID DrainSignals(VOID) { +VOID DrainSignals() { PCONNECTION_ENDPOINT Connection; - PLIST_ENTRY CurrentEntry; - KIRQL OldIrql; + PLIST_ENTRY ListEntry; - KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - CurrentEntry = ConnectionEndpointListHead.Flink; - while (CurrentEntry != &ConnectionEndpointListHead) - { - Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, - ListEntry ); - CurrentEntry = CurrentEntry->Flink; - KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - if (Connection->SocketContext) - { - HandleSignalledConnection(Connection); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - - ProcessCompletions(Connection); - } - else - { - KeReleaseSpinLock(&Connection->Lock, OldIrql); - } - - KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + while( (ListEntry = ExInterlockedRemoveHeadList(&SignalledConnectionsList, + &SignalledConnectionsLock)) != NULL) { + Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT, + SignalList ); + HandleSignalledConnection( Connection ); } - KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); } PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { PCONNECTION_ENDPOINT Connection = - ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT), - CONN_ENDPT_TAG); + exAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT)); if (!Connection) return Connection; @@ -325,42 +308,28 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT)); /* Initialize spin lock that protects the connection endpoint file object */ - KeInitializeSpinLock(&Connection->Lock); + TcpipInitializeSpinLock(&Connection->Lock); InitializeListHead(&Connection->ConnectRequest); InitializeListHead(&Connection->ListenRequest); InitializeListHead(&Connection->ReceiveRequest); InitializeListHead(&Connection->SendRequest); - InitializeListHead(&Connection->CompletionQueue); /* Save client context pointer */ Connection->ClientContext = ClientContext; - /* Add connection endpoint to global list */ - ExInterlockedInsertTailList(&ConnectionEndpointListHead, - &Connection->ListEntry, - &ConnectionEndpointListLock); - return Connection; } VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) { - KIRQL OldIrql; - TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n")); - - TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - RemoveEntryList(&Connection->ListEntry); - TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - - ExFreePoolWithTag( Connection, CONN_ENDPT_TAG ); + exFreePool( Connection ); } NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ) { NTSTATUS Status; - KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + ASSERT_LOCKED(&TCPLock); TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, " "Proto %d\n", @@ -377,8 +346,6 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", Connection->SocketContext)); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - return Status; } @@ -391,21 +358,19 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) * This is the low level interface for receiving TCP data */ { - KIRQL OldIrql; - TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to oskit\n", IPPacket->TotalSize, IPPacket->HeaderSize)); - KeAcquireSpinLock(&ClientInfo.Lock, &OldIrql); - ClientInfo.Unlocked = TRUE; + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); OskitTCPReceiveDatagram( IPPacket->Header, IPPacket->TotalSize, IPPacket->HeaderSize ); - ClientInfo.Unlocked = FALSE; - KeReleaseSpinLock(&ClientInfo.Lock, OldIrql); + DrainSignals(); + + TcpipRecursiveMutexLeave( &TCPLock ); } /* event.c */ @@ -430,6 +395,11 @@ void TCPFree( void *ClientData, void *data, OSK_PCHAR file, OSK_UINT line ); void TCPMemShutdown( void ); +int TCPSleep( void *ClientData, void *token, int priority, char *msg, + int tmio ); + +void TCPWakeup( void *ClientData, void *token ); + OSKITTCP_EVENT_HANDLERS EventHandlers = { NULL, /* Client Data */ TCPSocketState, /* SocketState */ @@ -437,8 +407,8 @@ OSKITTCP_EVENT_HANDLERS EventHandlers = { TCPFindInterface, /* FindInterface */ TCPMalloc, /* Malloc */ TCPFree, /* Free */ - NULL, /* Sleep */ - NULL, /* Wakeup */ + TCPSleep, /* Sleep */ + TCPWakeup /* Wakeup */ }; static KEVENT TimerLoopEvent; @@ -464,7 +434,7 @@ TimerThread(PVOID Context) while ( 1 ) { if (Next == NextFast) { NextFast += 2; - } + } if (Next == NextSlow) { NextSlow += 5; } @@ -476,8 +446,12 @@ TimerThread(PVOID Context) PsTerminateSystemThread(Status); } + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); TimerOskitTCP( Next == NextFast, Next == NextSlow ); - DrainSignals(); + if (Next == NextSlow) { + DrainSignals(); + } + TcpipRecursiveMutexLeave( &TCPLock ); Current = Next; if (10 <= Current) { @@ -497,6 +471,7 @@ StartTimer(VOID) TimerThread, NULL); } + NTSTATUS TCPStartup(VOID) /* * FUNCTION: Initializes the TCP subsystem @@ -506,6 +481,11 @@ NTSTATUS TCPStartup(VOID) { NTSTATUS Status; + TcpipRecursiveMutexInit( &TCPLock ); + ExInitializeFastMutex( &SleepingThreadsLock ); + KeInitializeSpinLock( &SignalledConnectionsLock ); + InitializeListHead( &SleepingThreadsList ); + InitializeListHead( &SignalledConnectionsList ); Status = TCPMemStartup(); if ( ! NT_SUCCESS(Status) ) { return Status; @@ -517,11 +497,10 @@ NTSTATUS TCPStartup(VOID) return Status; } - KeInitializeSpinLock(&ClientInfo.Lock); - ClientInfo.Unlocked = FALSE; - + TcpipRecursiveMutexEnter(&TCPLock, TRUE); RegisterOskitTCPEventHandlers( &EventHandlers ); InitOskitTCP(); + TcpipRecursiveMutexLeave(&TCPLock); /* Register this protocol with IP layer */ IPRegisterProtocol(IPPROTO_TCP, TCPReceive); @@ -582,9 +561,8 @@ NTSTATUS TCPTranslateError( int OskitError ) { case 0: Status = STATUS_SUCCESS; break; case OSK_EADDRNOTAVAIL: Status = STATUS_INVALID_ADDRESS; break; case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break; - case OSK_ECONNREFUSED: Status = STATUS_REMOTE_NOT_LISTENING; break; - case OSK_ECONNRESET: - case OSK_ECONNABORTED: Status = STATUS_REMOTE_DISCONNECT; break; + case OSK_ECONNREFUSED: + case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break; case OSK_EWOULDBLOCK: case OSK_EINPROGRESS: Status = STATUS_PENDING; break; case OSK_EINVAL: Status = STATUS_INVALID_PARAMETER; break; @@ -617,10 +595,11 @@ NTSTATUS TCPConnect USHORT RemotePort; PTDI_BUCKET Bucket; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n")); + ASSERT_LOCKED(&TCPLock); + Status = AddrBuildAddress ((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress, &RemoteAddress, @@ -636,6 +615,11 @@ NTSTATUS TCPConnect return STATUS_NETWORK_UNREACHABLE; } + if (Connection->State & SEL_FIN) + { + return STATUS_REMOTE_DISCONNECT; + } + /* Freed in TCPSocketState */ TI_DbgPrint(DEBUG_TCP, ("Connecting to address %x:%x\n", @@ -646,8 +630,6 @@ NTSTATUS TCPConnect AddressToBind = AddressToConnect; AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - Status = TCPTranslateError ( OskitTCPBind( Connection->SocketContext, &AddressToBind, @@ -661,27 +643,22 @@ NTSTATUS TCPConnect Status = TCPTranslateError ( OskitTCPConnect( Connection->SocketContext, + Connection, &AddressToConnect, sizeof(AddressToConnect) ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - if (Status == STATUS_PENDING) { - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); - if( !Bucket ) - { - return STATUS_NO_MEMORY; - } + Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); + if( !Bucket ) return STATUS_NO_MEMORY; Bucket->Request.RequestNotifyObject = (PVOID)Complete; Bucket->Request.RequestContext = Context; + + IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, - &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock ); } - } else { - KeReleaseSpinLock(&Connection->Lock, OldIrql); } return Status; @@ -694,20 +671,29 @@ NTSTATUS TCPDisconnect PTDI_CONNECTION_INFORMATION ReturnInfo, PTCP_COMPLETION_ROUTINE Complete, PVOID Context ) { - NTSTATUS Status = STATUS_INVALID_PARAMETER; - KIRQL OldIrql; + NTSTATUS Status; + + ASSERT_LOCKED(&TCPLock); TI_DbgPrint(DEBUG_TCP,("started\n")); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + switch( Flags & (TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE) ) { + case 0: + case TDI_DISCONNECT_ABORT: + Flags = 0; + break; - if (Flags & TDI_DISCONNECT_RELEASE) - Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext)); + case TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE: + Flags = 2; + break; - if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) - Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD)); + case TDI_DISCONNECT_RELEASE: + Flags = 1; + break; + } - KeReleaseSpinLock(&Connection->Lock, OldIrql); + Status = TCPTranslateError + ( OskitTCPShutdown( Connection->SocketContext, Flags ) ); TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status)); @@ -717,20 +703,18 @@ NTSTATUS TCPDisconnect NTSTATUS TCPClose ( PCONNECTION_ENDPOINT Connection ) { NTSTATUS Status; - KIRQL OldIrql; - PVOID Socket; TI_DbgPrint(DEBUG_TCP,("TCPClose started\n")); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - Socket = Connection->SocketContext; - Connection->SocketContext = NULL; - Status = TCPTranslateError( OskitTCPClose( Socket ) ); - if (!NT_SUCCESS(Status)) - { - Connection->SocketContext = Socket; - } - KeReleaseSpinLock(&Connection->Lock, OldIrql); + ASSERT_LOCKED(&TCPLock); + + /* Make our code remove all pending IRPs */ + Connection->State |= SEL_FIN; + DrainSignals(); + + Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) ); + if (Status == STATUS_SUCCESS) + Connection->SocketContext = NULL; TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status)); @@ -749,19 +733,25 @@ NTSTATUS TCPReceiveData UINT DataLen, Received = 0; NTSTATUS Status; PTDI_BUCKET Bucket; - KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", ReceiveLength, Connection->SocketContext)); + ASSERT_LOCKED(&TCPLock); + + ASSERT_KM_POINTER(Connection->SocketContext); + + /* Closing */ + if (Connection->State & SEL_FIN) + { + *BytesReceived = 0; + return STATUS_REMOTE_DISCONNECT; + } + NdisQueryBuffer( Buffer, &DataBuffer, &DataLen ); TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - - ASSERT_KM_POINTER(Connection->SocketContext); - Status = TCPTranslateError ( OskitTCPRecv ( Connection->SocketContext, @@ -770,14 +760,12 @@ NTSTATUS TCPReceiveData &Received, ReceiveFlags ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received)); /* Keep this request around ... there was no data yet */ if( Status == STATUS_PENDING ) { /* Freed in TCPSocketState */ - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); + Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); if( !Bucket ) { TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); return STATUS_NO_MEMORY; @@ -787,8 +775,9 @@ NTSTATUS TCPReceiveData Bucket->Request.RequestContext = Context; *BytesReceived = 0; - ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, - &Connection->Lock ); + IoMarkIrpPending((PIRP)Context); + + ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); TI_DbgPrint(DEBUG_TCP,("Queued read irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received)); @@ -811,9 +800,8 @@ NTSTATUS TCPSendData UINT Sent = 0; NTSTATUS Status; PTDI_BUCKET Bucket; - KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + ASSERT_LOCKED(&TCPLock); TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", SendLength, Connection->SocketContext)); @@ -824,19 +812,24 @@ NTSTATUS TCPSendData TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n", Connection->SocketContext)); + /* Closing */ + if (Connection->State & SEL_FIN) + { + *BytesSent = 0; + return STATUS_REMOTE_DISCONNECT; + } + Status = TCPTranslateError ( OskitTCPSend( Connection->SocketContext, (OSK_PCHAR)BufferData, SendLength, &Sent, 0 ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent)); /* Keep this request around ... there was no data yet */ if( Status == STATUS_PENDING ) { /* Freed in TCPSocketState */ - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); + Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); if( !Bucket ) { TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); return STATUS_NO_MEMORY; @@ -845,9 +838,10 @@ NTSTATUS TCPSendData Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; *BytesSent = 0; + + IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, - &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); TI_DbgPrint(DEBUG_TCP,("Queued write irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent)); @@ -859,6 +853,10 @@ NTSTATUS TCPSendData return Status; } +VOID TCPTimeout(VOID) { + /* Now handled by TimerThread */ +} + UINT TCPAllocatePort( UINT HintPort ) { if( HintPort ) { if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort; @@ -882,16 +880,12 @@ NTSTATUS TCPGetSockAddress OSK_UI16 LocalPort, RemotePort; PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address; NTSTATUS Status; - KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + ASSERT_LOCKED(&TCPLock); Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext, &LocalAddress, &LocalPort, &RemoteAddress, &RemotePort)); - - KeReleaseSpinLock(&Connection->Lock, OldIrql); - if (!NT_SUCCESS(Status)) return Status; @@ -904,13 +898,12 @@ NTSTATUS TCPGetSockAddress return Status; } -BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { +VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { PLIST_ENTRY Entry; PLIST_ENTRY ListHead[4]; KIRQL OldIrql; PTDI_BUCKET Bucket; UINT i = 0; - BOOLEAN Found = FALSE; ListHead[0] = &Endpoint->SendRequest; ListHead[1] = &Endpoint->ReceiveRequest; @@ -929,16 +922,13 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { if( Bucket->Request.RequestContext == Irp ) { RemoveEntryList( &Bucket->Entry ); - ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG ); - Found = TRUE; + exFreePool( Bucket ); break; } } } TcpipReleaseSpinLock( &Endpoint->Lock, OldIrql ); - - return Found; } /* EOF */ diff --git a/reactos/lib/drivers/ip/transport/udp/udp.c b/reactos/lib/drivers/ip/transport/udp/udp.c index 125e5101fc0..46366e6833d 100644 --- a/reactos/lib/drivers/ip/transport/udp/udp.c +++ b/reactos/lib/drivers/ip/transport/udp/udp.c @@ -172,9 +172,6 @@ NTSTATUS UDPSendDatagram( USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; - - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -189,12 +186,10 @@ NTSTATUS UDPSendDatagram( break; default: - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_UNSUCCESSFUL; } if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_NETWORK_UNREACHABLE; } @@ -218,20 +213,14 @@ NTSTATUS UDPSendDatagram( DataSize ); if( !NT_SUCCESS(Status) ) - { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; - } if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - return STATUS_SUCCESS; } diff --git a/reactos/lib/drivers/oskittcp/include/memtrack.h b/reactos/lib/drivers/oskittcp/include/memtrack.h new file mode 100644 index 00000000000..802ed74aed1 --- /dev/null +++ b/reactos/lib/drivers/oskittcp/include/memtrack.h @@ -0,0 +1,80 @@ +#ifndef MEMTRACK_H +#define MEMTRACK_H + +#ifndef FOURCC +#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) +#endif + +#define FBSD_MALLOC FOURCC('d','s','b','f') +#define EXALLOC_TAG FOURCC('E','x','A','l') + +#if DBG +#define MTMARK() TrackDumpFL(__FILE__, __LINE__) +#define NdisAllocateBuffer(x,y,z,a,b) { \ + NdisAllocateBuffer(x,y,z,a,b); \ + if( *x == NDIS_STATUS_SUCCESS ) { \ + Track(NDIS_BUFFER_TAG, *y); \ + } \ +} +#define NdisAllocatePacket(x,y,z) { \ + NdisAllocatePacket(x,y,z); \ + if( *x == NDIS_STATUS_SUCCESS ) { \ + Track(NDIS_PACKET_TAG, *y); \ + } \ +} +#define FreeNdisPacket(x) { TI_DbgPrint(MID_TRACE,("Deleting Packet %x\n", x)); FreeNdisPacketX(x); } +#define NdisFreePacket(x) { Untrack(x); NdisFreePacket(x); } +#define NdisFreeBuffer(x) { Untrack(x); NdisFreeBuffer(x); } +#define exAllocatePool(x,y) ExAllocatePoolX(x,y,__FILE__,__LINE__) +#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolX(x,y,__FILE__,__LINE__) +#define exFreePool(x) ExFreePoolX(x,__FILE__,__LINE__) + +extern LIST_ENTRY AllocatedObjectsHead; +extern KSPIN_LOCK AllocatedObjectsLock; + +typedef struct _ALLOCATION_TRACKER { + LIST_ENTRY Entry; + DWORD Tag; + PVOID Thing; + PCHAR FileName; + DWORD LineNo; +} ALLOCATION_TRACKER, *PALLOCATION_TRACKER; + +VOID TrackingInit(); +VOID TrackWithTag( DWORD Tag, PVOID Thing, PCHAR File, DWORD Line ); +#define Track(Tag,Thing) TrackWithTag(Tag,Thing,__FILE__,__LINE__) +VOID UntrackFL( PCHAR File, DWORD Line, PVOID Thing ); +#define Untrack(Thing) UntrackFL(__FILE__,__LINE__,Thing) +VOID TrackDumpFL( PCHAR File, DWORD Line ); +#define TrackDump() TrackDumpFL(__FILE__,__LINE__) +VOID TrackTag( DWORD Tag ); + +static __inline PVOID ExAllocatePoolX( POOL_TYPE type, SIZE_T size, PCHAR File, ULONG Line ) { + PVOID Out = ExAllocatePool( type, size ); + if( Out ) TrackWithTag( EXALLOC_TAG, Out, File, Line ); + return Out; +} +static __inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) { + UntrackFL(File, Line, Data); + ExFreePool(Data); +} + +#define MEMTRACK_MAX_TAGS_TO_TRACK 64 +#else +#define MTMARK() +#define Track(x,y) +#define TrackingInit() +#define TrackDump() +#define Untrack(x) +#define TrackTag(x) +#define FreeNdisPacket FreeNdisPacketX +#define exFreePool(x) ExFreePool(x) +#define exAllocatePool(x,y) ExAllocatePool(x,y) +#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolWithTag(x,y,z) +#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideList(x) +#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideList(x,y) +#define TrackWithTag(w,x,y,z) +#define UntrackFL(w,x,y,z) +#endif + +#endif/*MEMMTRAC_H*/ diff --git a/reactos/lib/drivers/oskittcp/include/oskittcp.h b/reactos/lib/drivers/oskittcp/include/oskittcp.h index 64e587b7dad..b5242fe03a9 100644 --- a/reactos/lib/drivers/oskittcp/include/oskittcp.h +++ b/reactos/lib/drivers/oskittcp/include/oskittcp.h @@ -123,7 +123,7 @@ extern int OskitTCPSend( void *socket, OSK_UINT *OutLen, OSK_UINT Flags ); -extern int OskitTCPConnect( void *socket, +extern int OskitTCPConnect( void *socket, void *connection, void *nam, OSK_UINT namelen ); extern int OskitTCPClose( void *socket ); @@ -131,7 +131,7 @@ extern int OskitTCPBind( void *socket, void *nam, OSK_UINT namelen ); extern int OskitTCPAccept( void *socket, void **new_socket, - void *context, void *addr_out, + void *addr_out, OSK_UINT addr_len, OSK_UINT *out_addr_len, OSK_UINT finish_accept ); @@ -164,8 +164,6 @@ int OskitTCPSetSockOpt(void *socket, int OskitTCPDisconnect(void *socket); -int OskitTCPGetSocketError(void *socket); - #undef errno void *fbsd_malloc( unsigned int bytes, char *file, unsigned line, ... ); @@ -189,27 +187,4 @@ void fbsd_free( void *data, char *file, unsigned line, ... ); #define FREAD 0x0001 #define FWRITE 0x0002 -/* Don't define this unless your are insane or aicom */ -//#define LOCK_SPAM - -#ifdef LOCK_SPAM -#define OSKLock() if (!KeTryToAcquireSpinLockAtDpcLevel(&OSKLock)) \ - { \ - DbgPrint("OSKLock WAIT (%s)\n", __FUNCTION__); \ - KeAcquireSpinLockAtDpcLevel(&OSKLock); \ - } \ - DbgPrint("OSKLock >>>> (%s)\n", __FUNCTION__) - -#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock); \ - DbgPrint("OSKLock <<<< (%s)\n", __FUNCTION__) -#else -#define OSKLock() KeAcquireSpinLockAtDpcLevel(&OSKLock) -#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock) -#endif - -#define OSKLockAndRaise(x) KeRaiseIrql(DISPATCH_LEVEL, x); \ - OSKLock() -#define OSKUnlockAndLower(x) OSKUnlock(); \ - KeLowerIrql(x) - #endif/*OSKITTCP_H*/ diff --git a/reactos/lib/drivers/oskittcp/oskittcp/interface.c b/reactos/lib/drivers/oskittcp/oskittcp/interface.c index a925d330434..a1d3e89e3de 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/interface.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/interface.c @@ -23,8 +23,6 @@ OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 }; //OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA; OSK_UINT OskitDebugTraceLevel = 0; -KSPIN_LOCK OSKLock; - /* SPL */ unsigned cpl; unsigned net_imask; @@ -47,7 +45,6 @@ void fbsd_free( void *data, char *file, unsigned line, ... ) { void InitOskitTCP() { OS_DbgPrint(OSK_MID_TRACE,("Init Called\n")); - KeInitializeSpinLock(&OSKLock); OS_DbgPrint(OSK_MID_TRACE,("MB Init\n")); mbinit(); OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n")); @@ -69,19 +66,12 @@ void DeinitOskitTCP() { } void TimerOskitTCP( int FastTimer, int SlowTimer ) { - KIRQL OldIrql; - - /* This function is a special case in which we cannot use OSKLock/OSKUnlock - * because we don't enter with the connection lock held */ - - OSKLockAndRaise(&OldIrql); if ( SlowTimer ) { tcp_slowtimo(); } if ( FastTimer ) { tcp_fasttimo(); } - OSKUnlockAndLower(OldIrql); } void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) { @@ -125,16 +115,12 @@ int OskitTCPSocket( void *context, int proto ) { struct socket *so; - - OSKLock(); int error = socreate(domain, &so, type, proto); if( !error ) { so->so_connection = context; so->so_state |= SS_NBIO; *aso = so; } - OSKUnlock(); - return error; } @@ -167,11 +153,8 @@ int OskitTCPRecv( void *connection, OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len)); - OSKLock(); error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */, &tcp_flags ); - OSKUnlock(); - *OutLen = Len - uio.uio_resid; return error; @@ -199,15 +182,14 @@ int OskitTCPBind( void *socket, addr.sa_family = addr.sa_len; addr.sa_len = sizeof(struct sockaddr); - OSKLock(); error = sobind(so, &sabuf); - OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return (error); } -int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) { +int OskitTCPConnect( void *socket, void *connection, + void *nam, OSK_UINT namelen ) { struct socket *so = socket; int error = EFAULT; struct mbuf sabuf; @@ -215,7 +197,8 @@ int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) { OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket)); - OSKLock(); + so->so_connection = connection; + if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { error = EALREADY; goto done; @@ -234,9 +217,7 @@ int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) { error = soconnect(so, &sabuf); - if (error == EINPROGRESS) - goto done; - else if (error) + if (error) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { @@ -251,54 +232,34 @@ bad: error = EINTR; done: - OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return (error); } int OskitTCPDisconnect(void *socket) { - int error; - if (!socket) return OSK_ESHUTDOWN; - OSKLock(); - error = sodisconnect(socket); - OSKUnlock(); - - return error; + return sodisconnect(socket); } int OskitTCPShutdown( void *socket, int disconn_type ) { - int error; - if (!socket) return OSK_ESHUTDOWN; - OSKLock(); - error = soshutdown( socket, disconn_type ); - OSKUnlock(); - - return error; + return soshutdown( socket, disconn_type ); } int OskitTCPClose( void *socket ) { - int error; struct socket *so = socket; if (!socket) return OSK_ESHUTDOWN; - OSKLock(); - /* We have to remove the socket context here otherwise we end up - * back in HandleSignalledConnection with a freed connection context - */ - so->so_connection = NULL; - error = soclose( socket ); - OSKUnlock(); - - return error; + so->so_connection = 0; + soclose( so ); + return 0; } int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, @@ -320,10 +281,7 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, uio.uio_rw = UIO_WRITE; uio.uio_procp = NULL; - OSKLock(); error = sosend( socket, NULL, &uio, NULL, NULL, 0 ); - OSKUnlock(); - *OutLen = Len - uio.uio_resid; return error; @@ -331,7 +289,6 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, int OskitTCPAccept( void *socket, void **new_socket, - void *context, void *AddrOut, OSK_UINT AddrLen, OSK_UINT *OutAddrLen, @@ -360,12 +317,11 @@ int OskitTCPAccept( void *socket, /* that's a copyin actually */ namelen = *OutAddrLen; - OSKLock(); - s = splnet(); #if 0 if ((head->so_options & SO_ACCEPTCONN) == 0) { + splx(s); OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n", head->so_options, SO_ACCEPTCONN)); error = EINVAL; @@ -377,10 +333,39 @@ int OskitTCPAccept( void *socket, head->so_q, head->so_state)); if ((head->so_state & SS_NBIO) && head->so_q == NULL) { + splx(s); error = EWOULDBLOCK; goto out; } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + while (head->so_q == NULL && head->so_error == 0) { + if (head->so_state & SS_CANTRCVMORE) { + head->so_error = ECONNABORTED; + break; + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + error = tsleep((caddr_t)&head->so_timeo, PSOCK | PCATCH, + "accept", 0); + if (error) { + splx(s); + goto out; + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + +#if 0 + if (head->so_error) { + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + error = head->so_error; + head->so_error = 0; + splx(s); + goto out; + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); +#endif + /* * At this point we know that there is at least one connection * ready to be accepted. Remove it from the queue. @@ -399,20 +384,19 @@ int OskitTCPAccept( void *socket, head->so_q = so->so_q; head->so_qlen--; + *newso = so; + + /*so->so_state &= ~SS_COMP;*/ + mnam.m_data = (char *)&sa; mnam.m_len = sizeof(sa); - error = soaccept(so, &mnam); - if (error) - goto out; + (void) soaccept(so, &mnam); - so->so_state |= SS_NBIO | SS_ISCONNECTED; + so->so_state = SS_NBIO | SS_ISCONNECTED; so->so_q = so->so_q0 = NULL; so->so_qlen = 0; so->so_head = 0; - so->so_connection = context; - - *newso = so; OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); if (name) { @@ -422,10 +406,9 @@ int OskitTCPAccept( void *socket, *OutAddrLen = namelen; /* copyout actually */ } OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + splx(s); } out: - splx(s); - OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error)); return (error); } @@ -438,16 +421,10 @@ out: void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, OSK_UINT IpHeaderLen ) { - struct mbuf *Ip; + struct mbuf *Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); struct ip *iph; - OSKLock(); - Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); - if( !Ip ) - { - OSKUnlock(); - return; /* drop the segment */ - } + if( !Ip ) return; /* drop the segment */ //memcpy( Ip->m_data, Data, Len ); Ip->m_pkthdr.len = IpHeaderLen; @@ -462,7 +439,6 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, IpHeaderLen)); tcp_input(Ip, IpHeaderLen); - OSKUnlock(); /* The buffer Ip is freed by tcp_input */ } @@ -474,7 +450,6 @@ int OskitTCPSetSockOpt(void *socket, int size) { struct mbuf *m; - int error; if (!socket) return OSK_ESHUTDOWN; @@ -482,23 +457,16 @@ int OskitTCPSetSockOpt(void *socket, if (size >= MLEN) return OSK_EINVAL; - OSKLock(); m = m_get(M_WAIT, MT_SOOPTS); if (!m) - { - OSKUnlock(); return OSK_ENOMEM; - } m->m_len = size; memcpy(m->m_data, buffer, size); /* m is freed by sosetopt */ - error = sosetopt(socket, level, optname, m); - OSKUnlock(); - - return error; + return sosetopt(socket, level, optname, m); } int OskitTCPGetSockOpt(void *socket, @@ -513,7 +481,6 @@ int OskitTCPGetSockOpt(void *socket, if (!socket) return OSK_ESHUTDOWN; - OSKLock(); error = sogetopt(socket, level, optname, &m); if (!error) { @@ -522,7 +489,6 @@ int OskitTCPGetSockOpt(void *socket, if (!buffer || oldsize < m->m_len) { m_freem(m); - OSKUnlock(); return OSK_EINVAL; } @@ -530,7 +496,6 @@ int OskitTCPGetSockOpt(void *socket, m_freem(m); } - OSKUnlock(); return error; } @@ -542,11 +507,7 @@ int OskitTCPListen( void *socket, int backlog ) { return OSK_ESHUTDOWN; OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket)); - - OSKLock(); error = solisten( socket, backlog ); - OSKUnlock(); - OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return error; @@ -563,13 +524,11 @@ int OskitTCPSetAddress( void *socket, if (!socket) return OSK_ESHUTDOWN; - OSKLock(); inp = (struct inpcb *)so->so_pcb; inp->inp_laddr.s_addr = LocalAddress; inp->inp_lport = LocalPort; inp->inp_faddr.s_addr = RemoteAddress; inp->inp_fport = RemotePort; - OSKUnlock(); return 0; } @@ -585,31 +544,15 @@ int OskitTCPGetAddress( void *socket, if (!socket) return OSK_ESHUTDOWN; - OSKLock(); inp = (struct inpcb *)so->so_pcb; *LocalAddress = inp->inp_laddr.s_addr; *LocalPort = inp->inp_lport; *RemoteAddress = inp->inp_faddr.s_addr; *RemotePort = inp->inp_fport; - OSKUnlock(); return 0; } -int OskitTCPGetSocketError(void *socket) { - struct socket *so = socket; - int error; - - if (!socket) - return OSK_ESHUTDOWN; - - OSKLock(); - error = so->so_error; - OSKUnlock(); - - return error; -} - struct ifaddr *ifa_iffind(struct sockaddr *addr, int type) { if( OtcpEvent.FindInterface ) @@ -623,7 +566,7 @@ struct ifaddr *ifa_iffind(struct sockaddr *addr, int type) void oskittcp_die( const char *file, int line ) { DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file, line); - ASSERT(FALSE); + *((int *)0) = 0; } /* Stuff supporting the BSD network-interface interface */ From 911304e174d5d1f93c546993d718df1481973f12 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Sat, 28 Nov 2009 14:51:52 +0000 Subject: [PATCH 095/140] Removed documentation about a build system feature that's no longer supported I give thanks for the opportunity to improve ReactOS by removing, instead of adding code svn path=/trunk/; revision=44302 --- reactos/Makefile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/reactos/Makefile b/reactos/Makefile index a2a184725ae..85cc3473669 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -19,11 +19,6 @@ # This target installs all of ReactOS to a location specified by the # ROS_INSTALL environment variable. # -# module_install -# These targets installs a single module to a location specified by the -# ROS_INSTALL environment variable. Replace module with the name of the -# module you want to install. -# # clean # This target cleans (deletes) all files that are generated when building # ReactOS. From 3ba0c60504defe88e78e2f2b252005b5b671a548 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sat, 28 Nov 2009 14:54:34 +0000 Subject: [PATCH 096/140] [ntoskrnl/config] - CmpFindSubKeyInName: CmpFindSubKeyInRoot is useless in finding the correct leaf with the key name that is being searched for when keys are not sorted. Loop and search each leaf of the root index for the key name. See bug #4895 for more info. svn path=/trunk/; revision=44303 --- reactos/ntoskrnl/config/cmindex.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/reactos/ntoskrnl/config/cmindex.c b/reactos/ntoskrnl/config/cmindex.c index 162263d7590..0948bd31dd4 100644 --- a/reactos/ntoskrnl/config/cmindex.c +++ b/reactos/ntoskrnl/config/cmindex.c @@ -733,6 +733,33 @@ CmpFindSubKeyByName(IN PHHIVE Hive, /* Check if this is another index root */ if (IndexRoot->Signature == CM_KEY_INDEX_ROOT) { + +#ifndef SOMEONE_WAS_NICE_ENOUGH_TO_MAKE_OUR_CELLS_LEXICALLY_SORTED + /* CmpFindSubKeyInRoot is useless for actually finding the correct leaf when keys are not sorted */ + LONG ii; + PCM_KEY_INDEX Leaf; + /* Loop through each leaf in the index root */ + for (ii=0; iiCount; ii++) + { + Leaf = HvGetCell(Hive, IndexRoot->List[ii]); + if (Leaf) + { + Found = CmpFindSubKeyInLeaf(Hive, Leaf, SearchName, &SubKey); + HvReleaseCell(Hive, IndexRoot->List[ii]); + if (Found & 0x80000000) + { + HvReleaseCell(Hive, CellToRelease); + return HCELL_NIL; + } + + if ((Found) && (SubKey != HCELL_NIL)) + { + HvReleaseCell(Hive, CellToRelease); + return SubKey; + } + } + } +#endif /* Lookup the name in the root */ Found = CmpFindSubKeyInRoot(Hive, IndexRoot, From 91523d7181fd70dad5e9721e886e6d1da7c00ca1 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 28 Nov 2009 15:01:40 +0000 Subject: [PATCH 097/140] [msvcrt] Update scanf family with a patch that also went to Wine (http://source.winehq.org/git/wine.git/?a=commit;h=2043035e1749e40e23853d751ac1410d39fc8d27): Calculate floating point decimals in internally used long double precision. Fixes bug #4092 (calculator imprecision) svn path=/trunk/; revision=44304 --- reactos/lib/sdk/crt/string/scanf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/lib/sdk/crt/string/scanf.h b/reactos/lib/sdk/crt/string/scanf.h index bfe7a05119f..25c6336e1a1 100644 --- a/reactos/lib/sdk/crt/string/scanf.h +++ b/reactos/lib/sdk/crt/string/scanf.h @@ -266,7 +266,7 @@ _FUNCTION_ { } /* handle decimals */ if (width!=0 && nch == '.') { - float dec = 1; + long double dec = 1; nch = _GETC_(file); if (width>0) width--; while (width!=0 && (nch!=_EOF_) && _ISDIGIT_(nch)) { From b06cec2ffd04579631dfcfaeacabc3945699ccf0 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 28 Nov 2009 15:13:18 +0000 Subject: [PATCH 098/140] [msvcrt] - Use the process heap for malloc and friends - Fixes a crash during GIMP startup (bug #3503, part 1) svn path=/trunk/; revision=44306 --- reactos/lib/sdk/crt/stdlib/malloc.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/reactos/lib/sdk/crt/stdlib/malloc.c b/reactos/lib/sdk/crt/stdlib/malloc.c index 71f2d492f94..65163ae496d 100644 --- a/reactos/lib/sdk/crt/stdlib/malloc.c +++ b/reactos/lib/sdk/crt/stdlib/malloc.c @@ -34,8 +34,6 @@ /* round to 16 bytes + alloc at minimum 16 bytes */ #define ROUND_SIZE(size) (max(16, ROUND_UP(size, 16))) -extern HANDLE hHeap; - /* * @implemented */ @@ -46,7 +44,7 @@ void* malloc(size_t _size) if (nSize<_size) return NULL; - return HeapAlloc(hHeap, 0, nSize); + return HeapAlloc(GetProcessHeap(), 0, nSize); } /* @@ -54,7 +52,7 @@ void* malloc(size_t _size) */ void free(void* _ptr) { - HeapFree(hHeap,0,_ptr); + HeapFree(GetProcessHeap(),0,_ptr); } /* @@ -68,7 +66,7 @@ void* calloc(size_t _nmemb, size_t _size) if ( (_nmemb > ((size_t)-1 / _size)) || (cSize Date: Sat, 28 Nov 2009 15:16:36 +0000 Subject: [PATCH 099/140] [msvcrt] - Fix buffer calculation in argvtoW, missed unicode character size - Fixes another crash during GIMP startup, now GIMP starts (bug #3503, part 2) - Fix same problem in valisttoA/W svn path=/trunk/; revision=44307 --- reactos/lib/sdk/crt/process/process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reactos/lib/sdk/crt/process/process.c b/reactos/lib/sdk/crt/process/process.c index 2932bc6b836..53f752310fc 100644 --- a/reactos/lib/sdk/crt/process/process.c +++ b/reactos/lib/sdk/crt/process/process.c @@ -128,7 +128,7 @@ argvtosT(const _TCHAR* const* argv, _TCHAR delim) len += _tcslen(argv[i]) + 1; } - str = ptr = (_TCHAR*) malloc(len + 1); + str = ptr = (_TCHAR*) malloc((len + 1) * sizeof(_TCHAR)); if (str == NULL) return NULL; @@ -163,7 +163,7 @@ valisttosT(const _TCHAR* arg0, va_list alist, _TCHAR delim) } while(ptr != NULL); - str = (_TCHAR*) malloc(len + 1); + str = (_TCHAR*) malloc((len + 1) * sizeof(_TCHAR)); if (str == NULL) return NULL; From 71710290299317d6db44b598b5d9cbbc4a5a59d7 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 28 Nov 2009 15:26:02 +0000 Subject: [PATCH 100/140] [gdiplus] - Update to current Wine sources - Now routes BMP drawing to gdi instead of doing ole32 magic (bug #3412) svn path=/trunk/; revision=44308 --- reactos/dll/win32/gdiplus/brush.c | 239 ++++++++-- reactos/dll/win32/gdiplus/gdiplus.c | 29 +- reactos/dll/win32/gdiplus/gdiplus.spec | 8 +- reactos/dll/win32/gdiplus/gdiplus_private.h | 6 +- reactos/dll/win32/gdiplus/graphics.c | 90 ++-- reactos/dll/win32/gdiplus/image.c | 466 ++++++++++++++------ 6 files changed, 614 insertions(+), 224 deletions(-) diff --git a/reactos/dll/win32/gdiplus/brush.c b/reactos/dll/win32/gdiplus/brush.c index 6220443b04d..bfce7d85bb5 100644 --- a/reactos/dll/win32/gdiplus/brush.c +++ b/reactos/dll/win32/gdiplus/brush.c @@ -143,7 +143,7 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) } case BrushTypeLinearGradient:{ GpLineGradient *dest, *src; - INT count; + INT count, pcount; dest = GdipAlloc(sizeof(GpLineGradient)); if(!dest) return OutOfMemory; @@ -157,11 +157,20 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) count = dest->blendcount; dest->blendfac = GdipAlloc(count * sizeof(REAL)); dest->blendpos = GdipAlloc(count * sizeof(REAL)); + pcount = dest->pblendcount; + if (pcount) + { + dest->pblendcolor = GdipAlloc(pcount * sizeof(ARGB)); + dest->pblendpos = GdipAlloc(pcount * sizeof(REAL)); + } - if (!dest->blendfac || !dest->blendpos) + if (!dest->blendfac || !dest->blendpos || + (pcount && (!dest->pblendcolor || !dest->pblendpos))) { GdipFree(dest->blendfac); GdipFree(dest->blendpos); + GdipFree(dest->pblendcolor); + GdipFree(dest->pblendpos); DeleteObject(dest->brush.gdibrush); GdipFree(dest); return OutOfMemory; @@ -170,6 +179,12 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL)); memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL)); + if (pcount) + { + memcpy(dest->pblendcolor, src->pblendcolor, pcount * sizeof(ARGB)); + memcpy(dest->pblendpos, src->pblendpos, pcount * sizeof(REAL)); + } + *clone = &dest->brush; break; } @@ -189,19 +204,38 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone) return Ok; } -static LONG HatchStyleToHatch(HatchStyle hatchstyle) -{ - switch (hatchstyle) - { - case HatchStyleHorizontal: return HS_HORIZONTAL; - case HatchStyleVertical: return HS_VERTICAL; - case HatchStyleForwardDiagonal: return HS_FDIAGONAL; - case HatchStyleBackwardDiagonal: return HS_BDIAGONAL; - case HatchStyleCross: return HS_CROSS; - case HatchStyleDiagonalCross: return HS_DIAGCROSS; - default: return 0; - } -} +static const char HatchBrushes[][8] = { + { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }, /* HatchStyleHorizontal */ + { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleVertical */ + { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }, /* HatchStyleForwardDiagonal */ + { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }, /* HatchStyleBackwardDiagonal */ + { 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08 }, /* HatchStyleCross */ + { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 }, /* HatchStyleDiagonalCross */ + { 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80 }, /* HatchStyle05Percent */ + { 0x00, 0x02, 0x00, 0x88, 0x00, 0x20, 0x00, 0x88 }, /* HatchStyle10Percent */ + { 0x00, 0x22, 0x00, 0xcc, 0x00, 0x22, 0x00, 0xcc }, /* HatchStyle20Percent */ + { 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xcc }, /* HatchStyle25Percent */ + { 0x00, 0xcc, 0x04, 0xcc, 0x00, 0xcc, 0x40, 0xcc }, /* HatchStyle30Percent */ + { 0x44, 0xcc, 0x22, 0xcc, 0x44, 0xcc, 0x22, 0xcc }, /* HatchStyle40Percent */ + { 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc, 0x55, 0xcc }, /* HatchStyle50Percent */ + { 0x55, 0xcd, 0x55, 0xee, 0x55, 0xdc, 0x55, 0xee }, /* HatchStyle60Percent */ + { 0x55, 0xdd, 0x55, 0xff, 0x55, 0xdd, 0x55, 0xff }, /* HatchStyle70Percent */ + { 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff }, /* HatchStyle75Percent */ + { 0x55, 0xff, 0x59, 0xff, 0x55, 0xff, 0x99, 0xff }, /* HatchStyle80Percent */ + { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xfd, 0xff }, /* HatchStyle90Percent */ + { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 }, /* HatchStyleLightDownwardDiagonal */ + { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 }, /* HatchStyleLightUpwardDiagonal */ + { 0x99, 0x33, 0x66, 0xcc, 0x99, 0x33, 0x66, 0xcc }, /* HatchStyleDarkDownwardDiagonal */ + { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 }, /* HatchStyleDarkUpwardDiagonal */ + { 0xc1, 0x83, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0 }, /* HatchStyleWideDownwardDiagonal */ + { 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x07, 0x83, 0xc1 }, /* HatchStyleWideUpwardDiagonal */ + { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }, /* HatchStyleLightVertical */ + { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }, /* HatchStyleLightHorizontal */ + { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, /* HatchStyleNarrowVertical */ + { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, /* HatchStyleNarrowHorizontal */ + { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc }, /* HatchStyleDarkVertical */ + { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff }, /* HatchStyleDarkHorizontal */ +}; /****************************************************************************** * GdipCreateHatchBrush [GDIPLUS.@] @@ -209,6 +243,7 @@ static LONG HatchStyleToHatch(HatchStyle hatchstyle) GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, ARGB backcol, GpHatch **brush) { COLORREF fgcol = ARGB2COLORREF(forecol); + GpStatus stat = Ok; TRACE("(%d, %d, %d, %p)\n", hatchstyle, forecol, backcol, brush); @@ -217,37 +252,79 @@ GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, AR *brush = GdipAlloc(sizeof(GpHatch)); if (!*brush) return OutOfMemory; - switch (hatchstyle) + if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0])) { - case HatchStyleHorizontal: - case HatchStyleVertical: - case HatchStyleForwardDiagonal: - case HatchStyleBackwardDiagonal: - case HatchStyleCross: - case HatchStyleDiagonalCross: - /* Brushes that map to BS_HATCHED */ - (*brush)->brush.lb.lbStyle = BS_HATCHED; - (*brush)->brush.lb.lbColor = fgcol; - (*brush)->brush.lb.lbHatch = HatchStyleToHatch(hatchstyle); - break; + HBITMAP hbmp; + HDC hdc; + BITMAPINFOHEADER bmih; + DWORD* bits; + int x, y; - default: - FIXME("Unimplemented hatch style %d\n", hatchstyle); + hdc = CreateCompatibleDC(0); - (*brush)->brush.lb.lbStyle = BS_SOLID; - (*brush)->brush.lb.lbColor = fgcol; - (*brush)->brush.lb.lbHatch = 0; - break; + if (hdc) + { + bmih.biSize = sizeof(bmih); + bmih.biWidth = 8; + bmih.biHeight = 8; + bmih.biPlanes = 1; + bmih.biBitCount = 32; + bmih.biCompression = BI_RGB; + bmih.biSizeImage = 0; + + hbmp = CreateDIBSection(hdc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&bits, NULL, 0); + + if (hbmp) + { + for (y=0; y<8; y++) + for (x=0; x<8; x++) + if ((HatchBrushes[hatchstyle][y] & (0x80 >> x)) != 0) + bits[y*8+x] = forecol; + else + bits[y*8+x] = backcol; + } + else + stat = GenericError; + + DeleteDC(hdc); + } + else + stat = GenericError; + + if (stat == Ok) + { + (*brush)->brush.lb.lbStyle = BS_PATTERN; + (*brush)->brush.lb.lbColor = 0; + (*brush)->brush.lb.lbHatch = (ULONG_PTR)hbmp; + (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb); + + DeleteObject(hbmp); + } + } + else + { + FIXME("Unimplemented hatch style %d\n", hatchstyle); + + (*brush)->brush.lb.lbStyle = BS_SOLID; + (*brush)->brush.lb.lbColor = fgcol; + (*brush)->brush.lb.lbHatch = 0; + (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb); } + if (stat == Ok) + { + (*brush)->brush.bt = BrushTypeHatchFill; + (*brush)->forecol = forecol; + (*brush)->backcol = backcol; + (*brush)->hatchstyle = hatchstyle; + } + else + { + GdipFree(*brush); + *brush = NULL; + } - (*brush)->brush.gdibrush = CreateBrushIndirect(&(*brush)->brush.lb); - (*brush)->brush.bt = BrushTypeHatchFill; - (*brush)->forecol = forecol; - (*brush)->backcol = backcol; - (*brush)->hatchstyle = hatchstyle; - - return Ok; + return stat; } /****************************************************************************** @@ -316,6 +393,10 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint, (*line)->blendfac[0] = 1.0f; (*line)->blendpos[0] = 1.0f; + (*line)->pblendcolor = NULL; + (*line)->pblendpos = NULL; + (*line)->pblendcount = 0; + return Ok; } @@ -762,7 +843,7 @@ GpStatus WINGDIPAPI GdipCreateTextureIA(GpImage *image, /* image is flipped */ if(pbmi->bmiHeader.biHeight > 0){ - dibits += pbmi->bmiHeader.biSizeImage; + dibits += image_stride * (pbmi->bmiHeader.biHeight - 1); image_stride *= -1; textbits += stride * (n_height - 1); stride *= -1; @@ -893,6 +974,8 @@ GpStatus WINGDIPAPI GdipDeleteBrush(GpBrush *brush) case BrushTypeLinearGradient: GdipFree(((GpLineGradient*)brush)->blendfac); GdipFree(((GpLineGradient*)brush)->blendpos); + GdipFree(((GpLineGradient*)brush)->pblendcolor); + GdipFree(((GpLineGradient*)brush)->pblendpos); break; case BrushTypeTextureFill: GdipDeleteMatrix(((GpTexture*)brush)->transform); @@ -1600,6 +1683,69 @@ GpStatus WINGDIPAPI GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus, GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient *brush, GDIPCONST ARGB *blend, GDIPCONST REAL* positions, INT count) +{ + ARGB *new_color; + REAL *new_pos; + TRACE("(%p,%p,%p,%i)\n", brush, blend, positions, count); + + if (!brush || !blend || !positions || count < 2 || + positions[0] != 0.0f || positions[count-1] != 1.0f) + { + return InvalidParameter; + } + + new_color = GdipAlloc(count * sizeof(ARGB)); + new_pos = GdipAlloc(count * sizeof(REAL)); + if (!new_color || !new_pos) + { + GdipFree(new_color); + GdipFree(new_pos); + return OutOfMemory; + } + + memcpy(new_color, blend, sizeof(ARGB) * count); + memcpy(new_pos, positions, sizeof(REAL) * count); + + GdipFree(brush->pblendcolor); + GdipFree(brush->pblendpos); + + brush->pblendcolor = new_color; + brush->pblendpos = new_pos; + brush->pblendcount = count; + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient *brush, + ARGB *blend, REAL* positions, INT count) +{ + if (!brush || !blend || !positions || count < 2) + return InvalidParameter; + + if (brush->pblendcount == 0) + return GenericError; + + if (count < brush->pblendcount) + return InsufficientBuffer; + + memcpy(blend, brush->pblendcolor, sizeof(ARGB) * brush->pblendcount); + memcpy(positions, brush->pblendpos, sizeof(REAL) * brush->pblendcount); + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush, + INT *count) +{ + if (!brush || !count) + return InvalidParameter; + + *count = brush->pblendcount; + + return Ok; +} + +GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush) { static int calls; @@ -1620,6 +1766,17 @@ GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush, return NotImplemented; } +GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient *brush, REAL sx, REAL sy, + GpMatrixOrder order) +{ + static int calls; + + if(!(calls++)) + FIXME("not implemented\n"); + + return NotImplemented; +} + GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient* brush, REAL dx, REAL dy, GpMatrixOrder order) { diff --git a/reactos/dll/win32/gdiplus/gdiplus.c b/reactos/dll/win32/gdiplus/gdiplus.c index ec956f34f57..9fe933280ab 100644 --- a/reactos/dll/win32/gdiplus/gdiplus.c +++ b/reactos/dll/win32/gdiplus/gdiplus.c @@ -86,7 +86,7 @@ Status WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput input->DebugEventCallback, input->SuppressBackgroundThread, input->SuppressExternalCodecs); - if(input->GdiplusVersion != 1) + if(input->GdiplusVersion < 1 || input->GdiplusVersion > 2) return UnsupportedGdiplusVersion; if(input->SuppressBackgroundThread){ @@ -211,38 +211,37 @@ static void unstretch_angle(REAL * angle, REAL rad_x, REAL rad_y) INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2, REAL startAngle, REAL sweepAngle) { - INT i, count; + INT i; REAL end_angle, start_angle, endAngle; endAngle = startAngle + sweepAngle; unstretch_angle(&startAngle, x2 / 2.0, y2 / 2.0); unstretch_angle(&endAngle, x2 / 2.0, y2 / 2.0); - count = ceilf(fabs(endAngle - startAngle) / M_PI_2) * 3 + 1; - /* don't make more than a full circle */ - count = min(MAX_ARC_PTS, count); - - if(count == 1) - return 0; - if(!points) - return count; - /* start_angle and end_angle are the iterative variables */ start_angle = startAngle; - for(i = 0; i < count - 1; i += 3){ + for(i = 0; i < MAX_ARC_PTS - 1; i += 3){ /* check if we've overshot the end angle */ if( sweepAngle > 0.0 ) + { + if (start_angle >= endAngle) break; end_angle = min(start_angle + M_PI_2, endAngle); + } else + { + if (start_angle <= endAngle) break; end_angle = max(start_angle - M_PI_2, endAngle); + } - add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i == 0); + if (points) + add_arc_part(&points[i], x1, y1, x2, y2, start_angle, end_angle, i == 0); start_angle += M_PI_2 * (sweepAngle < 0.0 ? -1.0 : 1.0); } - return count; + if (i == 0) return 0; + else return i+1; } COLORREF ARGB2COLORREF(ARGB color) @@ -419,7 +418,7 @@ void convert_32bppARGB_to_32bppPARGB(UINT width, UINT height, } /* recursive deletion of GpRegion nodes */ -inline void delete_element(region_element* element) +void delete_element(region_element* element) { switch(element->type) { diff --git a/reactos/dll/win32/gdiplus/gdiplus.spec b/reactos/dll/win32/gdiplus/gdiplus.spec index bda241ed93b..aa64a3cb311 100644 --- a/reactos/dll/win32/gdiplus/gdiplus.spec +++ b/reactos/dll/win32/gdiplus/gdiplus.spec @@ -304,8 +304,8 @@ @ stdcall GdipGetLineBlendCount(ptr ptr) @ stdcall GdipGetLineColors(ptr ptr) @ stdcall GdipGetLineGammaCorrection(ptr ptr) -@ stub GdipGetLinePresetBlend -@ stub GdipGetLinePresetBlendCount +@ stdcall GdipGetLinePresetBlend(ptr ptr ptr long) +@ stdcall GdipGetLinePresetBlendCount(ptr ptr) @ stdcall GdipGetLineRect(ptr ptr) @ stdcall GdipGetLineRectI(ptr ptr) @ stdcall GdipGetLineSpacing(ptr long ptr) @@ -476,7 +476,7 @@ @ stdcall GdipRemovePropertyItem(ptr long) @ stdcall GdipResetClip(ptr) @ stub GdipResetImageAttributes -@ stub GdipResetLineTransform +@ stdcall GdipResetLineTransform(ptr) @ stub GdipResetPageTransform @ stdcall GdipResetPath(ptr) @ stub GdipResetPathGradientTransform @@ -496,7 +496,7 @@ @ stdcall GdipSaveGraphics(ptr ptr) @ stdcall GdipSaveImageToFile(ptr ptr ptr ptr) @ stdcall GdipSaveImageToStream(ptr ptr ptr ptr) -@ stub GdipScaleLineTransform +@ stdcall GdipScaleLineTransform(ptr long long long) @ stdcall GdipScaleMatrix(ptr long long long) @ stub GdipScalePathGradientTransform @ stdcall GdipScalePenTransform(ptr long long long) diff --git a/reactos/dll/win32/gdiplus/gdiplus_private.h b/reactos/dll/win32/gdiplus/gdiplus_private.h index e87176e3064..dfff66c0a3a 100644 --- a/reactos/dll/win32/gdiplus/gdiplus_private.h +++ b/reactos/dll/win32/gdiplus/gdiplus_private.h @@ -61,7 +61,7 @@ extern BOOL lengthen_path(GpPath *path, INT len); extern GpStatus trace_path(GpGraphics *graphics, GpPath *path); typedef struct region_element region_element; -extern inline void delete_element(region_element *element); +extern void delete_element(region_element *element); static inline INT roundr(REAL x) { @@ -166,6 +166,9 @@ struct GpLineGradient{ REAL* blendfac; /* blend factors */ REAL* blendpos; /* blend positions */ INT blendcount; + ARGB* pblendcolor; /* preset blend colors */ + REAL* pblendpos; /* preset blend positions */ + INT pblendcount; }; struct GpTexture{ @@ -208,6 +211,7 @@ struct GpAdustableArrowCap{ struct GpImage{ IPicture* picture; ImageType type; + GUID format; UINT flags; }; diff --git a/reactos/dll/win32/gdiplus/graphics.c b/reactos/dll/win32/gdiplus/graphics.c index 1df3eee4ba0..df107e42040 100644 --- a/reactos/dll/win32/gdiplus/graphics.c +++ b/reactos/dll/win32/gdiplus/graphics.c @@ -220,7 +220,27 @@ static ARGB blend_line_gradient(GpLineGradient* brush, REAL position) blendfac = (left_blendfac * (right_blendpos - position) + right_blendfac * (position - left_blendpos)) / range; } - return blend_colors(brush->startcolor, brush->endcolor, blendfac); + + if (brush->pblendcount == 0) + return blend_colors(brush->startcolor, brush->endcolor, blendfac); + else + { + int i=1; + ARGB left_blendcolor, right_blendcolor; + REAL left_blendpos, right_blendpos; + + /* locate the blend colors surrounding this position */ + while (blendfac > brush->pblendpos[i]) + i++; + + /* interpolate between the blend colors */ + left_blendpos = brush->pblendpos[i-1]; + left_blendcolor = brush->pblendcolor[i-1]; + right_blendpos = brush->pblendpos[i]; + right_blendcolor = brush->pblendcolor[i]; + blendfac = (blendfac - left_blendpos) / (right_blendpos - left_blendpos); + return blend_colors(left_blendcolor, right_blendcolor, blendfac); + } } static void brush_fill_path(GpGraphics *graphics, GpBrush* brush) @@ -1235,6 +1255,7 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete, (*metafile)->image.type = ImageTypeMetafile; + memcpy(&(*metafile)->image.format, &ImageFormatWMF, sizeof(GUID)); (*metafile)->bounds.X = ((REAL) placeable->BoundingBox.Left) / ((REAL) placeable->Inch); (*metafile)->bounds.Y = ((REAL) placeable->BoundingBox.Right) / ((REAL) placeable->Inch); (*metafile)->bounds.Width = ((REAL) (placeable->BoundingBox.Right @@ -1795,16 +1816,25 @@ GpStatus WINGDIPAPI GdipDrawImagePointRect(GpGraphics *graphics, GpImage *image, REAL x, REAL y, REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight, GpUnit srcUnit) { - FIXME("(%p, %p, %f, %f, %f, %f, %f, %f, %d): stub\n", graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit); - return NotImplemented; + GpPointF points[3]; + TRACE("(%p, %p, %f, %f, %f, %f, %f, %f, %d)\n", graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit); + + points[0].X = points[2].X = x; + points[0].Y = points[1].Y = y; + + /* FIXME: convert image coordinates to Graphics coordinates? */ + points[1].X = x + srcwidth; + points[2].Y = y + srcheight; + + return GdipDrawImagePointsRect(graphics, image, points, 3, srcx, srcy, + srcwidth, srcheight, srcUnit, NULL, NULL, NULL); } GpStatus WINGDIPAPI GdipDrawImagePointRectI(GpGraphics *graphics, GpImage *image, INT x, INT y, INT srcx, INT srcy, INT srcwidth, INT srcheight, GpUnit srcUnit) { - FIXME("(%p, %p, %d, %d, %d, %d, %d, %d, %d): stub\n", graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit); - return NotImplemented; + return GdipDrawImagePointRect(graphics, image, x, y, srcx, srcy, srcwidth, srcheight, srcUnit); } GpStatus WINGDIPAPI GdipDrawImagePoints(GpGraphics *graphics, GpImage *image, @@ -1854,15 +1884,6 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image else return NotImplemented; - /* IPicture renders bitmaps with the y-axis reversed - * FIXME: flipping for unknown image type might not be correct. */ - if(image->type != ImageTypeMetafile){ - INT temp; - temp = pti[0].y; - pti[0].y = pti[2].y; - pti[2].y = temp; - } - if(IPicture_Render(image->picture, graphics->hdc, pti[0].x, pti[0].y, pti[1].x - pti[0].x, pti[2].y - pti[0].y, srcx * dx, srcy * dy, @@ -2362,7 +2383,7 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string HFONT gdifont; LOGFONTW lfw; TEXTMETRICW textmet; - GpPointF pt[2], rectcpy[4]; + GpPointF pt[3], rectcpy[4]; POINT corners[4]; WCHAR* stringdup; REAL angle, ang_cos, ang_sin, rel_width, rel_height; @@ -2409,6 +2430,21 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string SetBkMode(graphics->hdc, TRANSPARENT); SetTextColor(graphics->hdc, brush->lb.lbColor); + pt[0].X = 0.0; + pt[0].Y = 0.0; + pt[1].X = 1.0; + pt[1].Y = 0.0; + pt[2].X = 0.0; + pt[2].Y = 1.0; + GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 3); + angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X)); + ang_cos = cos(angle); + ang_sin = sin(angle); + rel_width = sqrt((pt[1].Y-pt[0].Y)*(pt[1].Y-pt[0].Y)+ + (pt[1].X-pt[0].X)*(pt[1].X-pt[0].X)); + rel_height = sqrt((pt[2].Y-pt[0].Y)*(pt[2].Y-pt[0].Y)+ + (pt[2].X-pt[0].X)*(pt[2].X-pt[0].X)); + rectcpy[3].X = rectcpy[0].X = rect->X; rectcpy[1].Y = rectcpy[0].Y = rect->Y + offsety; rectcpy[2].X = rectcpy[1].X = rect->X + rect->Width; @@ -2416,30 +2452,14 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string transform_and_round_points(graphics, corners, rectcpy, 4); if (roundr(rect->Width) == 0) - { - rel_width = 1.0; nwidth = INT_MAX; - } else - { - rel_width = sqrt((corners[1].x - corners[0].x) * (corners[1].x - corners[0].x) + - (corners[1].y - corners[0].y) * (corners[1].y - corners[0].y)) - / rect->Width; nwidth = roundr(rel_width * rect->Width); - } if (roundr(rect->Height) == 0) - { - rel_height = 1.0; nheight = INT_MAX; - } else - { - rel_height = sqrt((corners[2].x - corners[1].x) * (corners[2].x - corners[1].x) + - (corners[2].y - corners[1].y) * (corners[2].y - corners[1].y)) - / rect->Height; nheight = roundr(rel_height * rect->Height); - } if (roundr(rect->Width) != 0 && roundr(rect->Height) != 0) { @@ -2457,14 +2477,6 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string lfw.lfHeight = roundr(((REAL)lfw.lfHeight) * rel_height); lfw.lfWidth = roundr(textmet.tmAveCharWidth * rel_width); - pt[0].X = 0.0; - pt[0].Y = 0.0; - pt[1].X = 1.0; - pt[1].Y = 0.0; - GdipTransformMatrixPoints(graphics->worldtrans, pt, 2); - angle = -gdiplus_atan2((pt[1].Y - pt[0].Y), (pt[1].X - pt[0].X)); - ang_cos = cos(angle); - ang_sin = sin(angle); lfw.lfEscapement = lfw.lfOrientation = roundr((angle / M_PI) * 1800.0); gdifont = CreateFontIndirectW(&lfw); diff --git a/reactos/dll/win32/gdiplus/image.c b/reactos/dll/win32/gdiplus/image.c index b1e831fdf99..5b70918aa07 100644 --- a/reactos/dll/win32/gdiplus/image.c +++ b/reactos/dll/win32/gdiplus/image.c @@ -94,36 +94,321 @@ GpStatus WINGDIPAPI GdipBitmapCreateApplyEffect(GpBitmap** inputBitmaps, return NotImplemented; } +static inline void getpixel_16bppGrayScale(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = *g = *b = row[x*2+1]; + *a = 255; +} + +static inline void getpixel_16bppRGB555(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + WORD pixel = *((WORD*)(row)+x); + *r = (pixel>>7&0xf8)|(pixel>>12&0x7); + *g = (pixel>>2&0xf8)|(pixel>>6&0x7); + *b = (pixel<<3&0xf8)|(pixel>>2&0x7); + *a = 255; +} + +static inline void getpixel_16bppRGB565(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + WORD pixel = *((WORD*)(row)+x); + *r = (pixel>>8&0xf8)|(pixel>>13&0x7); + *g = (pixel>>3&0xfc)|(pixel>>9&0x3); + *b = (pixel<<3&0xf8)|(pixel>>2&0x7); + *a = 255; +} + +static inline void getpixel_16bppARGB1555(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + WORD pixel = *((WORD*)(row)+x); + *r = (pixel>>7&0xf8)|(pixel>>12&0x7); + *g = (pixel>>2&0xf8)|(pixel>>6&0x7); + *b = (pixel<<3&0xf8)|(pixel>>2&0x7); + if ((pixel&0x8000) == 0x8000) + *a = 255; + else + *a = 0; +} + +static inline void getpixel_24bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*3+2]; + *g = row[x*3+1]; + *b = row[x*3]; + *a = 255; +} + +static inline void getpixel_32bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*4+2]; + *g = row[x*4+1]; + *b = row[x*4]; + *a = 255; +} + +static inline void getpixel_32bppARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*4+2]; + *g = row[x*4+1]; + *b = row[x*4]; + *a = row[x*4+3]; +} + +static inline void getpixel_32bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *a = row[x*4+3]; + if (*a == 0) + *r = *g = *b = 0; + else + { + *r = row[x*4+2] * 255 / *a; + *g = row[x*4+1] * 255 / *a; + *b = row[x*4] * 255 / *a; + } +} + +static inline void getpixel_48bppRGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*6+5]; + *g = row[x*6+3]; + *b = row[x*6+1]; + *a = 255; +} + +static inline void getpixel_64bppARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *r = row[x*8+5]; + *g = row[x*8+3]; + *b = row[x*8+1]; + *a = row[x*8+7]; +} + +static inline void getpixel_64bppPARGB(BYTE *r, BYTE *g, BYTE *b, BYTE *a, + const BYTE *row, UINT x) +{ + *a = row[x*8+7]; + if (*a == 0) + *r = *g = *b = 0; + else + { + *r = row[x*8+5] * 255 / *a; + *g = row[x*8+3] * 255 / *a; + *b = row[x*8+1] * 255 / *a; + } +} + GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, ARGB *color) { - static int calls; + BYTE r, g, b, a; + BYTE *row; TRACE("%p %d %d %p\n", bitmap, x, y, color); - if(!bitmap || !color) + if(!bitmap || !color || + x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height) return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + row = bitmap->bits+bitmap->stride*y; - *color = 0xdeadbeef; + switch (bitmap->format) + { + case PixelFormat16bppGrayScale: + getpixel_16bppGrayScale(&r,&g,&b,&a,row,x); + break; + case PixelFormat16bppRGB555: + getpixel_16bppRGB555(&r,&g,&b,&a,row,x); + break; + case PixelFormat16bppRGB565: + getpixel_16bppRGB565(&r,&g,&b,&a,row,x); + break; + case PixelFormat16bppARGB1555: + getpixel_16bppARGB1555(&r,&g,&b,&a,row,x); + break; + case PixelFormat24bppRGB: + getpixel_24bppRGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat32bppRGB: + getpixel_32bppRGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat32bppARGB: + getpixel_32bppARGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat32bppPARGB: + getpixel_32bppPARGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat48bppRGB: + getpixel_48bppRGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat64bppARGB: + getpixel_64bppARGB(&r,&g,&b,&a,row,x); + break; + case PixelFormat64bppPARGB: + getpixel_64bppPARGB(&r,&g,&b,&a,row,x); + break; + default: + FIXME("not implemented for format 0x%x\n", bitmap->format); + return NotImplemented; + } - return NotImplemented; + *color = a<<24|r<<16|g<<8|b; + + return Ok; +} + +static inline void setpixel_16bppGrayScale(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + *((WORD*)(row)+x) = (r+g+b)*85; +} + +static inline void setpixel_16bppRGB555(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + *((WORD*)(row)+x) = (r<<7&0x7c00)| + (g<<2&0x03e0)| + (b>>3&0x001f); +} + +static inline void setpixel_16bppRGB565(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + *((WORD*)(row)+x) = (r<<8&0xf800)| + (g<<3&0x07e0)| + (b>>3&0x001f); +} + +static inline void setpixel_16bppARGB1555(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + *((WORD*)(row)+x) = (a<<8&0x8000)| + (r<<7&0x7c00)| + (g<<2&0x03e0)| + (b>>3&0x001f); +} + +static inline void setpixel_24bppRGB(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + row[x*3+2] = r; + row[x*3+1] = g; + row[x*3] = b; +} + +static inline void setpixel_32bppRGB(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + *((DWORD*)(row)+x) = (r<<16)|(g<<8)|b; +} + +static inline void setpixel_32bppARGB(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + *((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b; +} + +static inline void setpixel_32bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + r = r * a / 255; + g = g * a / 255; + b = b * a / 255; + *((DWORD*)(row)+x) = (a<<24)|(r<<16)|(g<<8)|b; +} + +static inline void setpixel_48bppRGB(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + row[x*6+5] = row[x*6+4] = r; + row[x*6+3] = row[x*6+2] = g; + row[x*6+1] = row[x*6] = b; +} + +static inline void setpixel_64bppARGB(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + UINT64 a64=a, r64=r, g64=g, b64=b; + *((UINT64*)(row)+x) = (a64<<56)|(a64<<48)|(r64<<40)|(r64<<32)|(g64<<24)|(g64<<16)|(b64<<8)|b64; +} + +static inline void setpixel_64bppPARGB(BYTE r, BYTE g, BYTE b, BYTE a, + BYTE *row, UINT x) +{ + UINT64 a64, r64, g64, b64; + a64 = a * 257; + r64 = r * a / 255; + g64 = g * a / 255; + b64 = b * a / 255; + *((UINT64*)(row)+x) = (a64<<48)|(r64<<32)|(g64<<16)|b64; } GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, ARGB color) { - static int calls; + BYTE a, r, g, b; + BYTE *row; TRACE("bitmap:%p, x:%d, y:%d, color:%08x\n", bitmap, x, y, color); - if(!bitmap) + if(!bitmap || x < 0 || y < 0 || x >= bitmap->width || y >= bitmap->height) return InvalidParameter; - if(!(calls++)) - FIXME("not implemented\n"); + a = color>>24; + r = color>>16; + g = color>>8; + b = color; - return NotImplemented; + row = bitmap->bits + bitmap->stride * y; + + switch (bitmap->format) + { + case PixelFormat16bppGrayScale: + setpixel_16bppGrayScale(r,g,b,a,row,x); + break; + case PixelFormat16bppRGB555: + setpixel_16bppRGB555(r,g,b,a,row,x); + break; + case PixelFormat16bppRGB565: + setpixel_16bppRGB565(r,g,b,a,row,x); + break; + case PixelFormat16bppARGB1555: + setpixel_16bppARGB1555(r,g,b,a,row,x); + break; + case PixelFormat24bppRGB: + setpixel_24bppRGB(r,g,b,a,row,x); + break; + case PixelFormat32bppRGB: + setpixel_32bppRGB(r,g,b,a,row,x); + break; + case PixelFormat32bppARGB: + setpixel_32bppARGB(r,g,b,a,row,x); + break; + case PixelFormat32bppPARGB: + setpixel_32bppPARGB(r,g,b,a,row,x); + break; + case PixelFormat48bppRGB: + setpixel_48bppRGB(r,g,b,a,row,x); + break; + case PixelFormat64bppARGB: + setpixel_64bppARGB(r,g,b,a,row,x); + break; + case PixelFormat64bppPARGB: + setpixel_64bppPARGB(r,g,b,a,row,x); + break; + default: + FIXME("not implemented for format 0x%x\n", bitmap->format); + return NotImplemented; + } + + return Ok; } /* This function returns a pointer to an array of pixels that represents the @@ -413,6 +698,8 @@ GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage) GdipDisposeImage(*cloneImage); *cloneImage = NULL; } + else memcpy(&(*cloneImage)->format, &image->format, sizeof(GUID)); + return stat; } else @@ -645,11 +932,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap** bitmap) TRACE("%p, %p\n", hicon, bitmap); if(!bitmap || !GetIconInfo(hicon, &iinfo)) - { - DeleteObject(iinfo.hbmColor); - DeleteObject(iinfo.hbmMask); return InvalidParameter; - } /* get the size of the icon */ ret = GetObjectA(iinfo.hbmColor ? iinfo.hbmColor : iinfo.hbmMask, sizeof(bm), &bm); @@ -858,6 +1141,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, } (*bitmap)->image.type = ImageTypeBitmap; + memcpy(&(*bitmap)->image.format, &ImageFormatMemoryBMP, sizeof(GUID)); (*bitmap)->image.flags = ImageFlagsNone; (*bitmap)->width = width; (*bitmap)->height = height; @@ -1144,23 +1428,11 @@ GpStatus WINGDIPAPI GdipGetImagePixelFormat(GpImage *image, PixelFormat *format) GpStatus WINGDIPAPI GdipGetImageRawFormat(GpImage *image, GUID *format) { - static int calls; - if(!image || !format) return InvalidParameter; - if(!(calls++)) - FIXME("stub\n"); + memcpy(format, &image->format, sizeof(GUID)); - /* FIXME: should be detected from embedded picture or stored separately */ - switch (image->type) - { - case ImageTypeBitmap: *format = ImageFormatBMP; break; - case ImageTypeMetafile: *format = ImageFormatEMF; break; - default: - WARN("unknown type %u\n", image->type); - *format = ImageFormatUndefined; - } return Ok; } @@ -1507,107 +1779,39 @@ static GpStatus decode_image_icon(IStream* stream, REFCLSID clsid, GpImage **ima return decode_image_wic(stream, &CLSID_WICIcoDecoder, image); } +static GpStatus decode_image_bmp(IStream* stream, REFCLSID clsid, GpImage **image) +{ + GpStatus status; + GpBitmap* bitmap; + + status = decode_image_wic(stream, &CLSID_WICBmpDecoder, image); + + bitmap = (GpBitmap*)*image; + + if (status == Ok && bitmap->format == PixelFormat32bppARGB) + { + /* WIC supports bmp files with alpha, but gdiplus does not */ + bitmap->format = PixelFormat32bppRGB; + } + + return status; +} + static GpStatus decode_image_jpeg(IStream* stream, REFCLSID clsid, GpImage **image) { return decode_image_wic(stream, &CLSID_WICJpegDecoder, image); } +static GpStatus decode_image_png(IStream* stream, REFCLSID clsid, GpImage **image) +{ + return decode_image_wic(stream, &CLSID_WICPngDecoder, image); +} + static GpStatus decode_image_gif(IStream* stream, REFCLSID clsid, GpImage **image) { return decode_image_wic(stream, &CLSID_WICGifDecoder, image); } -static GpStatus decode_image_olepicture_bitmap(IStream* stream, REFCLSID clsid, GpImage **image) -{ - IPicture *pic; - BITMAPINFO *pbmi; - BITMAPCOREHEADER* bmch; - HBITMAP hbm; - HDC hdc; - - TRACE("%p %p\n", stream, image); - - if(!stream || !image) - return InvalidParameter; - - if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture, - (LPVOID*) &pic) != S_OK){ - TRACE("Could not load picture\n"); - return GenericError; - } - - pbmi = GdipAlloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)); - if (!pbmi) - return OutOfMemory; - *image = GdipAlloc(sizeof(GpBitmap)); - if(!*image){ - GdipFree(pbmi); - return OutOfMemory; - } - (*image)->type = ImageTypeBitmap; - - (*((GpBitmap**) image))->width = ipicture_pixel_width(pic); - (*((GpBitmap**) image))->height = ipicture_pixel_height(pic); - - /* get the pixel format */ - IPicture_get_Handle(pic, (OLE_HANDLE*)&hbm); - IPicture_get_CurDC(pic, &hdc); - - (*((GpBitmap**) image))->hbitmap = hbm; - (*((GpBitmap**) image))->hdc = hdc; - (*((GpBitmap**) image))->bits = NULL; - - bmch = (BITMAPCOREHEADER*) (&pbmi->bmiHeader); - bmch->bcSize = sizeof(BITMAPCOREHEADER); - - if(!hdc){ - HBITMAP old; - hdc = CreateCompatibleDC(0); - old = SelectObject(hdc, hbm); - GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS); - SelectObject(hdc, old); - DeleteDC(hdc); - } - else - GetDIBits(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS); - - switch(bmch->bcBitCount) - { - case 1: - (*((GpBitmap**) image))->format = PixelFormat1bppIndexed; - break; - case 4: - (*((GpBitmap**) image))->format = PixelFormat4bppIndexed; - break; - case 8: - (*((GpBitmap**) image))->format = PixelFormat8bppIndexed; - break; - case 16: - (*((GpBitmap**) image))->format = PixelFormat16bppRGB565; - break; - case 24: - (*((GpBitmap**) image))->format = PixelFormat24bppRGB; - break; - case 32: - (*((GpBitmap**) image))->format = PixelFormat32bppRGB; - break; - case 48: - (*((GpBitmap**) image))->format = PixelFormat48bppRGB; - break; - default: - FIXME("Bit depth %d is not fully supported yet\n", bmch->bcBitCount); - (*((GpBitmap**) image))->format = (bmch->bcBitCount << 8) | PixelFormatGDI; - break; - } - - GdipFree(pbmi); - - (*image)->picture = pic; - (*image)->flags = ImageFlagsNone; - - return Ok; -} - static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid, GpImage **image) { IPicture *pic; @@ -1715,7 +1919,15 @@ GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream* stream, GpImage **image) if (FAILED(hr)) return hresult_to_status(hr); /* call on the image decoder to do the real work */ - return codec->decode_func(stream, &codec->info.Clsid, image); + stat = codec->decode_func(stream, &codec->info.Clsid, image); + + /* take note of the original data format */ + if (stat == Ok) + { + memcpy(&(*image)->format, &codec->info.FormatID, sizeof(GUID)); + } + + return stat; } /* FIXME: no ICM */ @@ -1915,6 +2127,12 @@ static GpStatus encode_image_BMP(GpImage *image, IStream* stream, return encode_image_WIC(image, stream, &CLSID_WICBmpEncoder, params); } +static GpStatus encode_image_png(GpImage *image, IStream* stream, + GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params) +{ + return encode_image_WIC(image, stream, &CLSID_WICPngEncoder, params); +} + /***************************************************************************** * GdipSaveImageToStream [GDIPLUS.@] */ @@ -2051,7 +2269,7 @@ static const struct image_codec codecs[NUM_CODECS] = { /* SigMask */ bmp_sig_mask, }, encode_image_BMP, - decode_image_olepicture_bitmap + decode_image_bmp }, { { /* JPEG */ @@ -2138,15 +2356,15 @@ static const struct image_codec codecs[NUM_CODECS] = { /* FormatDescription */ png_format, /* FilenameExtension */ png_extension, /* MimeType */ png_mimetype, - /* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin, + /* Flags */ ImageCodecFlagsEncoder | ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin, /* Version */ 1, /* SigCount */ 1, /* SigSize */ 8, /* SigPattern */ png_sig_pattern, /* SigMask */ png_sig_mask, }, - NULL, - decode_image_olepicture_bitmap + encode_image_png, + decode_image_png }, { { /* ICO */ From f45f63e7c24131c24a9dce15ecc98be45171e615 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 28 Nov 2009 17:01:46 +0000 Subject: [PATCH 101/140] [PORTCLS] - Store KSOBJECT_HEADER as the first member in a struct, which ks can use to access object header. Fixes initialization of ReactOS portcls in WinXP - Partly implement power querying / setting. Fixes bsod when shutting down the system in WinXP with ReactOS portcls - Change the pin state at PASSIVE_LEVEL - Implement IOCTL_KS_RESET for CPinWaveCyclic svn path=/trunk/; revision=44309 --- .../wdm/audio/backpln/portcls/dispatcher.cpp | 118 +++++---- .../wdm/audio/backpln/portcls/dma_slave.cpp | 1 + .../wdm/audio/backpln/portcls/interrupt.cpp | 2 + .../drivers/wdm/audio/backpln/portcls/irp.cpp | 239 +++++++++++++++++- .../wdm/audio/backpln/portcls/irpstream.cpp | 25 +- .../audio/backpln/portcls/pin_wavecyclic.cpp | 218 +++++++++------- .../wdm/audio/backpln/portcls/port_dmus.cpp | 1 + .../wdm/audio/backpln/portcls/private.hpp | 15 +- .../audio/backpln/portcls/propertyhandler.cpp | 7 +- .../wdm/audio/backpln/portcls/undoc.cpp | 71 +++++- 10 files changed, 531 insertions(+), 166 deletions(-) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp b/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp index 81953425c4f..3d2bbb6e018 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/dispatcher.cpp @@ -16,16 +16,16 @@ Dispatch_fnDeviceIoControl( PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->DeviceIoControl(DeviceObject, Irp); + return DispatchContext->Target->DeviceIoControl(DeviceObject, Irp); } NTSTATUS @@ -35,17 +35,17 @@ Dispatch_fnRead( PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->Read(DeviceObject, Irp); + return DispatchContext->Target->Read(DeviceObject, Irp); } NTSTATUS @@ -55,17 +55,17 @@ Dispatch_fnWrite( PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->Write(DeviceObject, Irp); + return DispatchContext->Target->Write(DeviceObject, Irp); } NTSTATUS @@ -75,17 +75,17 @@ Dispatch_fnFlush( PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->Flush(DeviceObject, Irp); + return DispatchContext->Target->Flush(DeviceObject, Irp); } NTSTATUS @@ -95,17 +95,24 @@ Dispatch_fnClose( PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; + NTSTATUS Status; // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->Close(DeviceObject, Irp); + Status = DispatchContext->Target->Close(DeviceObject, Irp); + + if (NT_SUCCESS(Status)) + { + KsFreeObjectHeader(DispatchContext->ObjectHeader); + FreeItem(DispatchContext, TAG_PORTCLASS); + } + // done + return Status; } NTSTATUS @@ -115,17 +122,17 @@ Dispatch_fnQuerySecurity( PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->QuerySecurity(DeviceObject, Irp); + return DispatchContext->Target->QuerySecurity(DeviceObject, Irp); } NTSTATUS @@ -135,17 +142,16 @@ Dispatch_fnSetSecurity( PIRP Irp) { PIO_STACK_LOCATION IoStack; - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); - // access IrpTarget - IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext; - + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->SetSecurity(DeviceObject, Irp); + return DispatchContext->Target->SetSecurity(DeviceObject, Irp); } BOOLEAN @@ -161,13 +167,13 @@ Dispatch_fnFastDeviceIoControl( PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; - // access IrpTarget - IrpTarget = (IIrpTarget *)FileObject->FsContext; + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->FastDeviceIoControl(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject); + return DispatchContext->Target->FastDeviceIoControl(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject); } @@ -183,13 +189,13 @@ Dispatch_fnFastRead( PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; - // access IrpTarget - IrpTarget = (IIrpTarget *)FileObject->FsContext; + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->FastRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); + return DispatchContext->Target->FastRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); } BOOLEAN @@ -204,12 +210,12 @@ Dispatch_fnFastWrite( PIO_STATUS_BLOCK IoStatus, PDEVICE_OBJECT DeviceObject) { - IIrpTarget * IrpTarget; + PDISPATCH_CONTEXT DispatchContext; - // access IrpTarget - IrpTarget = (IIrpTarget *)FileObject->FsContext; + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)FileObject->FsContext; // let IrpTarget handle request - return IrpTarget->FastWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); + return DispatchContext->Target->FastWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject); } static KSDISPATCH_TABLE DispatchTable = @@ -226,7 +232,6 @@ static KSDISPATCH_TABLE DispatchTable = Dispatch_fnFastWrite, }; - NTSTATUS NTAPI NewDispatchObject( @@ -238,14 +243,35 @@ NewDispatchObject( NTSTATUS Status; KSOBJECT_HEADER ObjectHeader; PIO_STACK_LOCATION IoStack; + PDISPATCH_CONTEXT DispatchContext; // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); - IoStack->FileObject->FsContext = (PVOID)Target; + DispatchContext = (PDISPATCH_CONTEXT)AllocateItem(NonPagedPool, sizeof(DISPATCH_CONTEXT), TAG_PORTCLASS); + if (!DispatchContext) + return STATUS_INSUFFICIENT_RESOURCES; + // allocate object header Status = KsAllocateObjectHeader(&ObjectHeader, CreateItemCount, CreateItem, Irp, &DispatchTable); - DPRINT("KsAllocateObjectHeader result %x\n", Status); + + if (!NT_SUCCESS(Status)) + { + // free dispatch context + FreeItem(DispatchContext, TAG_PORTCLASS); + // done + return Status; + } + + // initialize dispatch context + DispatchContext->ObjectHeader = ObjectHeader; + DispatchContext->Target = Target; + DispatchContext->CreateItem = CreateItem; + + // store dispatch context + IoStack->FileObject->FsContext = DispatchContext; + + DPRINT("KsAllocateObjectHeader result %x Target %p Context %p\n", Status, Target, DispatchContext); return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp index 47805983fc8..a68e25ea8ef 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/dma_slave.cpp @@ -223,6 +223,7 @@ NTAPI CDmaChannelInit::BufferSize() { DPRINT("BufferSize %u\n", m_BufferSize); + PC_ASSERT(m_BufferSize); return m_BufferSize; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp b/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp index 38b5f87aba1..84dd17123b4 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/interrupt.cpp @@ -231,6 +231,8 @@ CInterruptSync::Connect() if (IsListEmpty(&m_ServiceRoutines)) return STATUS_UNSUCCESSFUL; + DPRINT("Vector %u Level %u Flags %x Affinity %x\n", Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Level, Descriptor->Flags, Descriptor->u.Interrupt.Affinity); + Status = IoConnectInterrupt(&m_Interrupt, IInterruptServiceRoutine, (PVOID)this, diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp b/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp index 29fd26c17c3..18a089dadf7 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/irp.cpp @@ -12,6 +12,13 @@ #include "private.hpp" +typedef struct +{ + PIRP Irp; + PDEVICE_OBJECT DeviceObject; +}QUERY_POWER_CONTEXT, *PQUERY_POWER_CONTEXT; + + NTSTATUS NTAPI PortClsCreate( @@ -33,7 +40,10 @@ PortClsPnp( NTSTATUS Status; PPCLASS_DEVICE_EXTENSION DeviceExt; PIO_STACK_LOCATION IoStack; + POWER_STATE PowerState; IResourceList* resource_list = NULL; + //ULONG Index; + //PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor, UnPartialDescriptor; DeviceExt = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -92,6 +102,14 @@ PortClsPnp( // Assign the resource list to our extension DeviceExt->resources = resource_list; + // store device power state + DeviceExt->DevicePowerState = PowerDeviceD0; + DeviceExt->SystemPowerState = PowerSystemWorking; + + // notify power manager of current state + PowerState = *((POWER_STATE*)&DeviceExt->DevicePowerState); + PoSetPowerState(DeviceObject, DevicePowerState, PowerState); + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; @@ -103,10 +121,9 @@ PortClsPnp( DeviceExt->resources->Release(); IoDeleteDevice(DeviceObject); - // Do not complete? - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; + // Forward request + Status = PcForwardIrpSynchronous(DeviceObject, Irp); + return PcCompleteIrp(DeviceObject, Irp, Status); case IRP_MN_QUERY_INTERFACE: DPRINT("IRP_MN_QUERY_INTERFACE\n"); @@ -133,21 +150,221 @@ PortClsPnp( return STATUS_UNSUCCESSFUL; } +VOID +CALLBACK +PwrCompletionFunction( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR MinorFunction, + IN POWER_STATE PowerState, + IN PVOID Context, + IN PIO_STATUS_BLOCK IoStatus) +{ + NTSTATUS Status; + PQUERY_POWER_CONTEXT PwrContext = (PQUERY_POWER_CONTEXT)Context; + + if (NT_SUCCESS(IoStatus->Status)) + { + // forward request to lower device object + Status = PcForwardIrpSynchronous(PwrContext->DeviceObject, PwrContext->Irp); + } + else + { + // failed + Status = IoStatus->Status; + } + + // start next power irp + PoStartNextPowerIrp(PwrContext->Irp); + + // complete request + PwrContext->Irp->IoStatus.Status = Status; + IoCompleteRequest(PwrContext->Irp, IO_NO_INCREMENT); + + // free context + FreeItem(PwrContext, TAG_PORTCLASS); +} + + NTSTATUS NTAPI PortClsPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PIO_STACK_LOCATION IoStack; + PPCLASS_DEVICE_EXTENSION DeviceExtension; + PQUERY_POWER_CONTEXT PwrContext; + POWER_STATE PowerState; + NTSTATUS Status = STATUS_SUCCESS; + DPRINT("PortClsPower called\n"); - // TODO + // get currrent stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if (IoStack->MinorFunction != IRP_MN_SET_POWER && IoStack->MinorFunction != IRP_MN_QUERY_POWER) + { + // just forward the request + Status = PcForwardIrpSynchronous(DeviceObject, Irp); - return STATUS_SUCCESS; + // start next power irp + PoStartNextPowerIrp(Irp); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + + + // get device extension + DeviceExtension = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; + + // get current request type + if (IoStack->Parameters.Power.Type == DevicePowerState) + { + // request for device power state + if (DeviceExtension->DevicePowerState == IoStack->Parameters.Power.State.DeviceState) + { + // nothing has changed + if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) + { + // only forward query requests + Status = PcForwardIrpSynchronous(DeviceObject, Irp); + } + + // start next power irp + PoStartNextPowerIrp(Irp); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + + if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) + { + // check if there is a registered adapter power management + if (DeviceExtension->AdapterPowerManagement) + { + // it is query if the change can be changed + PowerState = *((POWER_STATE*)&IoStack->Parameters.Power.State.DeviceState); + Status = DeviceExtension->AdapterPowerManagement->QueryPowerChangeState(PowerState); + + // sanity check + PC_ASSERT(Status == STATUS_SUCCESS); + } + + // only forward query requests + PcForwardIrpSynchronous(DeviceObject, Irp); + + // start next power irp + PoStartNextPowerIrp(Irp); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + else + { + // set power state + PowerState = *((POWER_STATE*)&IoStack->Parameters.Power.State.DeviceState); + PoSetPowerState(DeviceObject, DevicePowerState, PowerState); + + // check if there is a registered adapter power management + if (DeviceExtension->AdapterPowerManagement) + { + // notify of a power change state + DeviceExtension->AdapterPowerManagement->PowerChangeState(PowerState); + } + + // FIXME call all registered IPowerNotify interfaces via ISubdevice interface + + // store new power state + DeviceExtension->DevicePowerState = IoStack->Parameters.Power.State.DeviceState; + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + } + else + { + // sanity check + PC_ASSERT(IoStack->Parameters.Power.Type == SystemPowerState); + + if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) + { + // mark irp as pending + IoMarkIrpPending(Irp); + + // allocate power completion context + PwrContext = (PQUERY_POWER_CONTEXT)AllocateItem(NonPagedPool, sizeof(QUERY_POWER_CONTEXT), TAG_PORTCLASS); + + if (!PwrContext) + { + // no memory + PoStartNextPowerIrp(Irp); + + // complete and forget + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + + // setup power context + PwrContext->Irp = Irp; + PwrContext->DeviceObject = DeviceObject; + + // pass the irp down + PowerState = *((POWER_STATE*)IoStack->Parameters.Power.State.SystemState); + Status = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject, IoStack->MinorFunction, PowerState, PwrCompletionFunction, (PVOID)PwrContext, NULL); + + // check for success + if (!NT_SUCCESS(Status)) + { + // failed + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + + // done + return STATUS_PENDING; + } + else + { + // set power request + DeviceExtension->SystemPowerState = IoStack->Parameters.Power.State.SystemState; + + // only forward query requests + Status = PcForwardIrpSynchronous(DeviceObject, Irp); + + // start next power irp + PoStartNextPowerIrp(Irp); + + // complete request + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + // done + return Status; + } + } } NTSTATUS @@ -200,10 +417,10 @@ PcDispatchIrp( { PIO_STACK_LOCATION IoStack; - DPRINT("PcDispatchIrp called - handling IRP in PortCls\n"); - IoStack = IoGetCurrentIrpStackLocation(Irp); + DPRINT("PcDispatchIrp called - handling IRP in PortCls MajorFunction %x MinorFunction %x\n", IoStack->MajorFunction, IoStack->MinorFunction); + switch ( IoStack->MajorFunction ) { // PortCls diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp index f201db292b8..f80616487e1 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -145,7 +145,14 @@ CIrpQueue::AddMapping( } // get first stream header - Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + + if (Irp->RequestorMode == UserMode) + Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; + else + Header = (PKSSTREAM_HEADER)Irp->UserBuffer; + + // sanity check + PC_ASSERT(Header); // calculate num headers NumHeaders = IoStack->Parameters.DeviceIoControl.OutputBufferLength / Header->Size; @@ -156,7 +163,8 @@ CIrpQueue::AddMapping( // get first audio buffer Mdl = Irp->MdlAddress; - + // sanity check + PC_ASSERT(Mdl); // store the current stream header Irp->Tail.Overlay.DriverContext[OFFSET_STREAMHEADER] = (PVOID)Header; @@ -166,7 +174,6 @@ CIrpQueue::AddMapping( // store current header index Irp->Tail.Overlay.DriverContext[OFFSET_HEADERINDEX] = UlongToPtr(0); - NumData = 0; // prepare all headers for(Index = 0; Index < NumHeaders; Index++) @@ -175,7 +182,10 @@ CIrpQueue::AddMapping( PC_ASSERT(Header); PC_ASSERT(Mdl); - Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); + if (Irp->RequestorMode == UserMode) + { + Header->Data = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority); + } if (!Header->Data) { @@ -344,10 +354,13 @@ CIrpQueue::UpdateMapping( return; } - // irp has been processed completly + // irp has been processed completly NumData = 0; - StreamHeader = (PKSSTREAM_HEADER)m_Irp->AssociatedIrp.SystemBuffer; + if (m_Irp->RequestorMode == KernelMode) + StreamHeader = (PKSSTREAM_HEADER)m_Irp->UserBuffer; + else + StreamHeader = (PKSSTREAM_HEADER)m_Irp->AssociatedIrp.SystemBuffer; // loop all stream headers for(Index = 0; Index < STREAMHEADER_COUNT(m_Irp); Index++) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index f7a7c7f44a8..71e7b33bb66 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -35,16 +35,11 @@ public: CPortPinWaveCyclic(IUnknown *OuterUnknown){} virtual ~CPortPinWaveCyclic(){} - VOID SetState(KSSTATE State); - protected: VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount); VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount); VOID GeneratePositionEvents(IN ULONGLONG OldOffset, IN ULONGLONG NewOffset); - NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); - NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); - friend NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); friend NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); @@ -52,6 +47,7 @@ protected: friend NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); friend NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); friend NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); + friend VOID CALLBACK PinSetStateWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); IPortWaveCyclic * m_Port; IPortFilterWaveCyclic * m_Filter; @@ -82,6 +78,8 @@ protected: KSPIN_LOCK m_EventListLock; LIST_ENTRY m_EventList; + KSRESET m_ResetState; + ULONG m_Delay; LONG m_Ref; @@ -358,6 +356,57 @@ PinWaveCyclicAudioPosition( return STATUS_NOT_SUPPORTED; } +typedef struct +{ + CPortPinWaveCyclic *Pin; + KSSTATE NewState; + PIO_WORKITEM WorkItem; + PIRP Irp; + +}SETPIN_CONTEXT, *PSETPIN_CONTEXT; + +VOID +CALLBACK +PinSetStateWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + PSETPIN_CONTEXT PinWorkContext = (PSETPIN_CONTEXT)Context; + NTSTATUS Status; + + // try set stream + Status = PinWorkContext->Pin->m_Stream->SetState(PinWorkContext->NewState); + + DPRINT1("Setting state %u %x\n", PinWorkContext->NewState, Status); + if (NT_SUCCESS(Status)) + { + // store new state + PinWorkContext->Pin->m_State = PinWorkContext->NewState; + + if (PinWorkContext->Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && PinWorkContext->Pin->m_State == KSSTATE_STOP) + { + /* FIXME complete pending irps with successfull state */ + PinWorkContext->Pin->m_IrpQueue->CancelBuffers(); + } + //HACK + //PinWorkContext->Pin->m_IrpQueue->CancelBuffers(); + } + + // store result + PinWorkContext->Irp->IoStatus.Information = sizeof(KSSTATE); + PinWorkContext->Irp->IoStatus.Status = Status; + + // complete irp + IoCompleteRequest(PinWorkContext->Irp, IO_NO_INCREMENT); + + // free work item + IoFreeWorkItem(PinWorkContext->WorkItem); + + // free work context + FreeItem(PinWorkContext, TAG_PORTCLASS); + +} + NTSTATUS NTAPI @@ -366,10 +415,10 @@ PinWaveCyclicState( IN PKSIDENTIFIER Request, IN OUT PVOID Data) { - NTSTATUS Status = STATUS_UNSUCCESSFUL; CPortPinWaveCyclic *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; PKSSTATE State = (PKSSTATE)Data; + PSETPIN_CONTEXT PinWorkContext; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); @@ -387,25 +436,20 @@ PinWaveCyclicState( if (Request->Flags & KSPROPERTY_TYPE_SET) { - // try set stream - Status = Pin->m_Stream->SetState(*State); + PinWorkContext = (PSETPIN_CONTEXT)AllocateItem(NonPagedPool, sizeof(PSETPIN_CONTEXT), TAG_PORTCLASS); + PC_ASSERT(PinWorkContext); - DPRINT("Setting state %u %x\n", *State, Status); - if (NT_SUCCESS(Status)) - { - // store new state - Pin->m_State = *State; + PinWorkContext->WorkItem = IoAllocateWorkItem(IoGetCurrentIrpStackLocation(Irp)->DeviceObject); + PC_ASSERT(PinWorkContext->WorkItem); + // initialize work item context + PinWorkContext->NewState = *State; + PinWorkContext->Pin = Pin; + PinWorkContext->Irp = Irp; - if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP) - { - /* FIXME complete pending irps with successfull state */ - Pin->m_IrpQueue->CancelBuffers(); - } - } + IoMarkIrpPending(Irp); - // store result - Irp->IoStatus.Information = sizeof(KSSTATE); - return Status; + IoQueueWorkItem(PinWorkContext->WorkItem, PinSetStateWorkerRoutine, DelayedWorkQueue, (PVOID)PinWorkContext); + return STATUS_PENDING; } else if (Request->Flags & KSPROPERTY_TYPE_GET) { @@ -413,7 +457,7 @@ PinWaveCyclicState( *State = Pin->m_State; // store result Irp->IoStatus.Information = sizeof(KSSTATE); - + DPRINT1("Getting state %u %x\n", *State, STATUS_SUCCESS); return STATUS_SUCCESS; } @@ -464,7 +508,7 @@ PinWaveCyclicDataFormat( } // new change request - PC_ASSERT(Pin->m_State == KSSTATE_STOP); + PC_ASSERT(Pin->m_State != KSSTATE_RUN); // FIXME queue a work item when Irql != PASSIVE_LEVEL PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); @@ -760,65 +804,6 @@ CPortPinWaveCyclic::NewIrpTarget( return STATUS_UNSUCCESSFUL; } -NTSTATUS -NTAPI -CPortPinWaveCyclic::HandleKsProperty( - IN PIRP Irp) -{ - PKSPROPERTY Property; - NTSTATUS Status; - UNICODE_STRING GuidString; - PIO_STACK_LOCATION IoStack; - - IoStack = IoGetCurrentIrpStackLocation(Irp); - - DPRINT("IPortPinWave_HandleKsProperty entered\n"); - - IoStack = IoGetCurrentIrpStackLocation(Irp); - - Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); - - if (Status == STATUS_NOT_FOUND) - { - Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - RtlStringFromGUID(Property->Set, &GuidString); - DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); - RtlFreeUnicodeString(&GuidString); - } - - if (Status != STATUS_PENDING) - { - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } - - return Status; -} - -NTSTATUS -NTAPI -CPortPinWaveCyclic::HandleKsStream( - IN PIRP Irp) -{ - NTSTATUS Status; - ULONG Data = 0; - InterlockedIncrement((PLONG)&m_TotalPackets); - - DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); - - Status = m_IrpQueue->AddMapping(Irp, &Data); - - if (NT_SUCCESS(Status)) - { - m_Position.WriteOffset += Data; - - return STATUS_PENDING; - } - - return Status; -} - NTSTATUS NTAPI CPortPinWaveCyclic::DeviceIoControl( @@ -826,14 +811,28 @@ CPortPinWaveCyclic::DeviceIoControl( IN PIRP Irp) { PIO_STACK_LOCATION IoStack; + PKSPROPERTY Property; + UNICODE_STRING GuidString; NTSTATUS Status = STATUS_NOT_SUPPORTED; + ULONG Data = 0; + KSRESET ResetValue; + /* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); - if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { - return HandleKsProperty(Irp); + /* handle property with subdevice descriptor */ + Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); + + if (Status == STATUS_NOT_FOUND) + { + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + RtlStringFromGUID(Property->Set, &GuidString); + DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); + RtlFreeUnicodeString(&GuidString); + } } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) { @@ -846,11 +845,48 @@ CPortPinWaveCyclic::DeviceIoControl( else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) { /// FIXME - /// handle reset state + Status = KsAcquireResetValue(Irp, &ResetValue); + DPRINT("Status %x Value %u\n", Status, ResetValue); + /* check for success */ + if (NT_SUCCESS(Status)) + { + if (ResetValue == KSRESET_BEGIN) + { + m_IrpQueue->CancelBuffers(); + m_ResetState = KSRESET_BEGIN; + } + else if (ResetValue == KSRESET_END) + { + m_ResetState = KSRESET_END; + } + } } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM) { - return HandleKsStream(Irp); + /* increment total number of packets */ + InterlockedIncrement((PLONG)&m_TotalPackets); + + DPRINT("New Packet Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); + + /* is the device not currently reset */ + if (m_ResetState == KSRESET_END) + { + /* add the mapping */ + Status = m_IrpQueue->AddMapping(Irp, &Data); + + /* check for success */ + if (NT_SUCCESS(Status)) + { + m_Position.WriteOffset += Data; + Status = STATUS_PENDING; + } + } + else + { + /* reset request is currently in progress */ + Status = STATUS_DEVICE_NOT_READY; + DPRINT1("NotReady\n"); + } } else { @@ -1146,6 +1182,9 @@ CPortPinWaveCyclic::Init( m_Descriptor.EventList = &m_EventList; m_Descriptor.EventListLock = &m_EventListLock; + // initialize reset state + m_ResetState = KSRESET_END; + // release subdevice descriptor Subdevice->Release(); @@ -1183,6 +1222,7 @@ CPortPinWaveCyclic::Init( m_AllocatorFraming.FrameSize = m_FrameSize; m_Stream->Silence(SilenceBuffer, m_FrameSize); + m_Stream->Silence(m_CommonBuffer, m_CommonBufferSize); Status = m_IrpQueue->Init(ConnectDetails, DataFormat, DeviceObject, m_FrameSize, 0, SilenceBuffer); if (!NT_SUCCESS(Status)) @@ -1203,8 +1243,8 @@ CPortPinWaveCyclic::Init( m_Port = Port; m_Filter = Filter; - DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); - DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); + //DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); + //DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); return STATUS_SUCCESS; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp index 3b8c7cc1929..8c08b1f9c3d 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_dmus.cpp @@ -107,6 +107,7 @@ CPortDMus::QueryInterface( if (IsEqualGUIDAligned(refiid, IID_IPortDMus) || IsEqualGUIDAligned(refiid, IID_IPortMidi) || + IsEqualGUIDAligned(refiid, IID_IPort) || IsEqualGUIDAligned(refiid, IID_IUnknown)) { *Output = PVOID(PUNKNOWN((IPortDMus*)this)); diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.hpp b/reactos/drivers/wdm/audio/backpln/portcls/private.hpp index 45e6092e6e3..17adc4c8af5 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.hpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.hpp @@ -328,7 +328,10 @@ PcHandleDisableEventWithTable( IN PIRP Irp, IN PSUBDEVICE_DESCRIPTOR Descriptor); - +IIrpTarget * +NTAPI +KsoGetIrpTargetFromIrp( + PIRP Irp); #define DEFINE_KSPROPERTY_CONNECTIONSET(PinSet,\ PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\ @@ -389,6 +392,9 @@ typedef struct LIST_ENTRY TimerList; KSPIN_LOCK TimerListLock; + DEVICE_POWER_STATE DevicePowerState; + SYSTEM_POWER_STATE SystemPowerState; + } PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION; @@ -406,4 +412,11 @@ typedef struct PVOID Context; }TIMER_CONTEXT, *PTIMER_CONTEXT; +typedef struct +{ + KSOBJECT_HEADER ObjectHeader; + IIrpTarget * Target; + PKSOBJECT_CREATE_ITEM CreateItem; +}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; + #endif diff --git a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp index 9a4bbbd8ca0..730cd059a13 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp @@ -183,7 +183,7 @@ PinPropertyHandler( IIrpTarget * IrpTarget; IPort *Port; ISubdevice *SubDevice; - + PDISPATCH_CONTEXT DispatchContext; NTSTATUS Status = STATUS_UNSUCCESSFUL; @@ -193,8 +193,11 @@ PinPropertyHandler( // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); + // get dispatch context + DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; + // Get the IrpTarget - IrpTarget = (IIrpTarget*)IoStack->FileObject->FsContext; + IrpTarget = DispatchContext->Target; PC_ASSERT(IrpTarget); // Get the parent diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp index 21e2bf1ec2d..393e32cf9f4 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -50,13 +50,13 @@ NTAPI KsoGetIrpTargetFromIrp( PIRP Irp) { - PKSOBJECT_CREATE_ITEM CreateItem; + PIO_STACK_LOCATION IoStack; - // access the create item - CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); // IIrpTarget is stored in Context member - return (IIrpTarget*)CreateItem->Context; + return (IIrpTarget*)IoStack->FileObject->FsContext; } NTSTATUS @@ -110,6 +110,9 @@ PcHandlePropertyWithTable( /* try first KsPropertyHandler */ Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet); + if (Status != STATUS_NOT_FOUND) + return Status; + // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -119,7 +122,7 @@ PcHandlePropertyWithTable( // check if this a GUID_NULL request if (Status == STATUS_NOT_FOUND) { - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE) || !(Property->Property.Flags & KSPROPERTY_TYPE_TOPOLOGY)) return Status; // check if its a request for a topology node @@ -350,16 +353,21 @@ VOID DumpFilterDescriptor( IN PPCFILTER_DESCRIPTOR FilterDescription) { - ULONG Index; + ULONG Index, SubIndex; PPCPROPERTY_ITEM PropertyItem; + PPCEVENT_ITEM EventItem; + PPCNODE_DESCRIPTOR NodeDescriptor; UNICODE_STRING GuidString; - DPRINT("======================\n"); - DPRINT("Descriptor Automation Table%p\n",FilterDescription->AutomationTable); + + + DPRINT1("======================\n"); + DPRINT1("Descriptor Automation Table%p\n",FilterDescription->AutomationTable); if (FilterDescription->AutomationTable) { - DPRINT("FilterPropertiesCount %u FilterPropertySize %u Expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM)); + DPRINT1("FilterPropertiesCount %u FilterPropertySize %u Expected %u Events %u EventItemSize %u expected %u\n", FilterDescription->AutomationTable->PropertyCount, FilterDescription->AutomationTable->PropertyItemSize, sizeof(PCPROPERTY_ITEM), + FilterDescription->AutomationTable->EventCount, FilterDescription->AutomationTable->EventItemSize, sizeof(PCEVENT_ITEM)); if (FilterDescription->AutomationTable->PropertyCount) { PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties; @@ -367,15 +375,56 @@ DumpFilterDescriptor( for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++) { RtlStringFromGUID(*PropertyItem->Set, &GuidString); - DPRINT("Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags); + DPRINT("Property Index %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags); PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize); } + + EventItem = (PPCEVENT_ITEM)FilterDescription->AutomationTable->Events; + for(Index = 0; Index < FilterDescription->AutomationTable->EventCount; Index++) + { + RtlStringFromGUID(*EventItem->Set, &GuidString); + DPRINT1("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags); + + EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize); + } + } } + if (FilterDescription->Nodes) + { + DPRINT1("NodeCount %u NodeSize %u expected %u\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR)); + NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes; + for(Index = 0; Index < FilterDescription->NodeCount; Index++) + { + DPRINT("Index %u AutomationTable %p\n", Index, NodeDescriptor->AutomationTable); - DPRINT("======================\n"); + if (NodeDescriptor->AutomationTable) + { + DPRINT1("Index %u EventCount %u\n", Index, NodeDescriptor->AutomationTable->EventCount); + EventItem = (PPCEVENT_ITEM)NodeDescriptor->AutomationTable->Events; + for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->EventCount; SubIndex++) + { + RtlStringFromGUID(*EventItem->Set, &GuidString); + DPRINT1("EventIndex %u GUID %S Id %u Flags %x\n", Index, GuidString.Buffer, EventItem->Id, EventItem->Flags); + + EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + FilterDescription->AutomationTable->EventItemSize); + } + + } + + + NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize); + } + + + + } + + + + DPRINT1("======================\n"); } NTSTATUS From 1ea59d6a624873a0d41877d9763ebed5438216af Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 28 Nov 2009 17:05:06 +0000 Subject: [PATCH 102/140] - Silence debug print svn path=/trunk/; revision=44310 --- reactos/drivers/ksfilter/ks/connectivity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/drivers/ksfilter/ks/connectivity.c b/reactos/drivers/ksfilter/ks/connectivity.c index 56f7fe74179..5395ff2c822 100644 --- a/reactos/drivers/ksfilter/ks/connectivity.c +++ b/reactos/drivers/ksfilter/ks/connectivity.c @@ -217,7 +217,7 @@ KspReadMediaCategory( /* open the key */ Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes); - DPRINT1("ZwOpenKey() status 0x%08lx %S\n", Status, Path.Buffer); + DPRINT("ZwOpenKey() status 0x%08lx %S\n", Status, Path.Buffer); /* free path buffer */ ExFreePool(Path.Buffer); From 7d4a441c1540309a1e0d58257de6a7087704a217 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 28 Nov 2009 17:06:22 +0000 Subject: [PATCH 103/140] - Implement IOCTL_RESET_STREAM which is required for waveInReset waveOutReset svn path=/trunk/; revision=44311 --- .../drivers/wdm/audio/legacy/wdmaud/control.c | 34 +++++++++++++++++++ .../wdm/audio/legacy/wdmaud/interface.h | 16 ++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c index 6dda4dee4c2..b5f1c53a968 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/control.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/control.c @@ -316,6 +316,38 @@ WdmAudGetDeviceInterface( return SetIrpIoStatus(Irp, STATUS_INVALID_DEVICE_REQUEST, sizeof(WDMAUD_DEVICE_INFO)); } +NTSTATUS +NTAPI +WdmAudResetStream( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PWDMAUD_DEVICE_INFO DeviceInfo) +{ + KSRESET ResetStream; + NTSTATUS Status; + ULONG BytesReturned; + PFILE_OBJECT FileObject; + + DPRINT("WdmAudResetStream\n"); + + Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType); + return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); + } + + ResetStream = DeviceInfo->u.ResetStream; + ASSERT(ResetStream == KSRESET_BEGIN || ResetStream == KSRESET_END); + + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_RESET_STATE, (PVOID)&ResetStream, sizeof(KSRESET), NULL, 0, &BytesReturned); + + ObDereferenceObject(FileObject); + + DPRINT("WdmAudResetStream Status %x\n", Status); + return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); +} + NTSTATUS NTAPI WdmAudDeviceControl( @@ -382,6 +414,8 @@ WdmAudDeviceControl( return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo); case IOCTL_GET_MIXER_EVENT: return WdmAudGetMixerEvent(DeviceObject, Irp, DeviceInfo, ClientInfo); + case IOCTL_RESET_STREAM: + return WdmAudResetStream(DeviceObject, Irp, DeviceInfo); case IOCTL_GETPOS: case IOCTL_GETDEVID: case IOCTL_GETVOLUME: diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h index 13e748fea0c..d764459f7ea 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/interface.h @@ -57,6 +57,7 @@ typedef struct ULONG Value; }MixerEvent; KSSTATE State; + KSRESET ResetStream; ULONG Volume; ULONG FrameSize; HANDLE hNotifyEvent; @@ -346,7 +347,7 @@ typedef struct /// IOCTL_GET_MIXER_EVENT /// -/// Description: This IOCTL queries for +/// Description: This IOCTL queries for wdmaud driver if there any new kernel streaming events available /// /// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, /// InputBufferSize is size of WDMAUD_DEVICE_INFO structure @@ -360,5 +361,18 @@ typedef struct METHOD_BUFFERED, \ FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) +/// IOCTL_RESET_STREAM +/// +/// Description: This IOCTL instructs wdmaud to reset a stream +/// +/// Arguments: InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure, +/// InputBufferSize is size of WDMAUD_DEVICE_INFO structure +/// Note: The hDevice member must be set and DeviceType +/// ReturnCode: STATUS_SUCCESS indicates success +#define IOCTL_RESET_STREAM \ + CTL_CODE(FILE_DEVICE_SOUND, \ + 17, \ + METHOD_BUFFERED, \ + FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS) #endif From 41cbf8aa2b6419de8509565ab4a74b42032b9071 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 28 Nov 2009 19:34:45 +0000 Subject: [PATCH 104/140] - [Win32k] Add comments to text functions. svn path=/trunk/; revision=44312 --- .../subsystems/win32/win32k/objects/text.c | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/reactos/subsystems/win32/win32k/objects/text.c b/reactos/subsystems/win32/win32k/objects/text.c index 1fdd636b2da..14376a131ae 100644 --- a/reactos/subsystems/win32/win32k/objects/text.c +++ b/reactos/subsystems/win32/win32k/objects/text.c @@ -15,6 +15,11 @@ /** Functions *****************************************************************/ +/* + flOpts : + GetTextExtentPoint32W = 0 + GetTextExtentPointW = 1 + */ BOOL FASTCALL GreGetTextExtentW( @@ -65,6 +70,12 @@ GreGetTextExtentW( return Result; } + +/* + fl : + GetTextExtentExPointW = 0 and everything else that uses this. + GetTextExtentExPointI = 1 + */ BOOL FASTCALL GreGetTextExtentExW( @@ -235,6 +246,12 @@ NtGdiGetTextCharsetInfo( return Ret; } + +/* + fl : + GetTextExtentExPointW = 0 and everything else that uses this. + GetTextExtentExPointI = 1 + */ W32KAPI BOOL APIENTRY @@ -389,6 +406,12 @@ NtGdiGetTextExtentExW( return TRUE; } + +/* + flOpts : + GetTextExtentPoint32W = 0 + GetTextExtentPointW = 1 + */ BOOL APIENTRY NtGdiGetTextExtent(HDC hdc, From 9560d470537e0e897b1c77ec8179b45769502006 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sat, 28 Nov 2009 19:35:47 +0000 Subject: [PATCH 105/140] [msvcrt] - Validate the process heap - Remove validation as soon as this function is tested svn path=/trunk/; revision=44313 --- reactos/lib/sdk/crt/misc/getargs.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/reactos/lib/sdk/crt/misc/getargs.c b/reactos/lib/sdk/crt/misc/getargs.c index 68f06498517..1bdb409ab46 100644 --- a/reactos/lib/sdk/crt/misc/getargs.c +++ b/reactos/lib/sdk/crt/misc/getargs.c @@ -22,8 +22,6 @@ int __argc = 0; extern wchar_t **__winitenv; -extern HANDLE hHeap; - char* strndup(char* name, size_t len) { char *s = malloc(len + 1); @@ -179,7 +177,7 @@ int aexpand(char* name, int expand_wildcards) } /* - * @unimplemented + * @implemented */ void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, int* new_mode) { @@ -243,7 +241,7 @@ void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, i aexpand(strndup(_acmdln+afterlastspace, i - afterlastspace), doexpand); } - HeapValidate(hHeap, 0, NULL); + HeapValidate(GetProcessHeap(), 0, NULL); *argc = __argc; if (__argv == NULL) @@ -259,7 +257,7 @@ void __getmainargs(int* argc, char*** argv, char*** env, int expand_wildcards, i } /* - * @unimplemented + * @implemented */ void __wgetmainargs(int* argc, wchar_t*** wargv, wchar_t*** wenv, int expand_wildcards, int* new_mode) @@ -323,7 +321,7 @@ void __wgetmainargs(int* argc, wchar_t*** wargv, wchar_t*** wenv, wexpand(wcsndup(_wcmdln+afterlastspace, i - afterlastspace), doexpand); } - HeapValidate(hHeap, 0, NULL); + HeapValidate(GetProcessHeap(), 0, NULL); *argc = __argc; if (__wargv == NULL) From 43cd83d78149c64900069486b631bc87ba54ae37 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Sat, 28 Nov 2009 20:09:07 +0000 Subject: [PATCH 106/140] Nevermind. svn path=/trunk/; revision=44314 --- reactos/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/reactos/Makefile b/reactos/Makefile index 85cc3473669..a2a184725ae 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -19,6 +19,11 @@ # This target installs all of ReactOS to a location specified by the # ROS_INSTALL environment variable. # +# module_install +# These targets installs a single module to a location specified by the +# ROS_INSTALL environment variable. Replace module with the name of the +# module you want to install. +# # clean # This target cleans (deletes) all files that are generated when building # ReactOS. From 637f171861e2dfe6eb86adaf14dd7ca1317cef6e Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 28 Nov 2009 22:15:20 +0000 Subject: [PATCH 107/140] - Try fix increase of winmm:mixer tests failure - Found by Gregor Schneider (DosX) svn path=/trunk/; revision=44315 --- reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp index 393e32cf9f4..4e567d18aa8 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -122,7 +122,7 @@ PcHandlePropertyWithTable( // check if this a GUID_NULL request if (Status == STATUS_NOT_FOUND) { - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE) || !(Property->Property.Flags & KSPROPERTY_TYPE_TOPOLOGY)) + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) return Status; // check if its a request for a topology node From 15fff6abae82494bbe54d0cc32f4ba14e285e86b Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Sun, 29 Nov 2009 10:53:39 +0000 Subject: [PATCH 108/140] [ntdll] - Implement LdrLockLoaderLock and LdrUnlockLoaderLock. svn path=/trunk/; revision=44318 --- reactos/dll/ntdll/ldr/utils.c | 62 ++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/reactos/dll/ntdll/ldr/utils.c b/reactos/dll/ntdll/ldr/utils.c index 873cce8f1fa..6a141eb624c 100644 --- a/reactos/dll/ntdll/ldr/utils.c +++ b/reactos/dll/ntdll/ldr/utils.c @@ -3382,8 +3382,55 @@ LdrLockLoaderLock(IN ULONG Flags, OUT PULONG Disposition OPTIONAL, OUT PULONG Cookie OPTIONAL) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + BOOLEAN Ret; + BOOLEAN CookieSet = FALSE; + + if ((Flags != 0x01) && (Flags != 0x02)) + return STATUS_INVALID_PARAMETER_1; + + if (!Cookie) return STATUS_INVALID_PARAMETER_3; + + /* Set some defaults for failure while verifying params */ + _SEH2_TRY + { + *Cookie = 0; + CookieSet = TRUE; + if (Disposition) *Disposition = 0; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + if (CookieSet) + Status = STATUS_INVALID_PARAMETER_3; + else + Status = STATUS_INVALID_PARAMETER_2; + } + _SEH2_END; + + if (Flags == 0x01) + { + DPRINT1("Warning: Reporting errors with exception not supported yet!\n"); + RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); + Status = STATUS_SUCCESS; + + } + else + { + if (!Disposition) return STATUS_INVALID_PARAMETER_2; + + Ret = RtlTryEnterCriticalSection(NtCurrentPeb()->LoaderLock); + + if (Ret) + *Disposition = 0x01; + else + *Disposition = 0x02; + + Status = STATUS_SUCCESS; + } + + /* FIXME: Cookie is based on part of the thread id */ + *Cookie = (ULONG)NtCurrentTeb()->RealClientId.UniqueThread; + return Status; } NTSTATUS @@ -3391,8 +3438,15 @@ NTAPI LdrUnlockLoaderLock(IN ULONG Flags, IN ULONG Cookie OPTIONAL) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + if (Flags != 0x01) + return STATUS_INVALID_PARAMETER_1; + + if (Cookie != (ULONG)NtCurrentTeb()->RealClientId.UniqueThread) + return STATUS_INVALID_PARAMETER_2; + + RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); + + return STATUS_SUCCESS; } BOOLEAN From eeba3408b2982100ddf1cc039d58b7f4a2d903e7 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Sun, 29 Nov 2009 18:07:14 +0000 Subject: [PATCH 109/140] [setupapi] Sync SetupGetIntField to Wine, fixes six setupapi:parser tests svn path=/trunk/; revision=44322 --- reactos/dll/win32/setupapi/parser.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/reactos/dll/win32/setupapi/parser.c b/reactos/dll/win32/setupapi/parser.c index 43a43fba36f..e1b693ddaec 100644 --- a/reactos/dll/win32/setupapi/parser.c +++ b/reactos/dll/win32/setupapi/parser.c @@ -1894,21 +1894,26 @@ BOOL WINAPI SetupGetIntField( PINFCONTEXT context, DWORD index, PINT result ) char *end, *buffer = localbuff; DWORD required; INT res; - BOOL ret = FALSE; + BOOL ret; - if (!SetupGetStringFieldA( context, index, localbuff, sizeof(localbuff), &required )) + if (!(ret = SetupGetStringFieldA( context, index, localbuff, sizeof(localbuff), &required ))) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE; if (!(buffer = HeapAlloc( GetProcessHeap(), 0, required ))) return FALSE; - if (!SetupGetStringFieldA( context, index, buffer, required, NULL )) goto done; + if (!(ret = SetupGetStringFieldA( context, index, buffer, required, NULL ))) goto done; } - res = strtol( buffer, &end, 0 ); - if (end != buffer && !*end) + /* The call to SetupGetStringFieldA succeeded. If buffer is empty we have an optional field */ + if (!*buffer) *result = 0; + else { - *result = res; - ret = TRUE; + res = strtol( buffer, &end, 0 ); + if (end != buffer && !*end) *result = res; + else + { + SetLastError( ERROR_INVALID_DATA ); + ret = FALSE; + } } - else SetLastError( ERROR_INVALID_DATA ); done: if (buffer != localbuff) HeapFree( GetProcessHeap(), 0, buffer ); From f21af7347fa03230c1653ad95f48ac9f39eae6a0 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 29 Nov 2009 18:56:56 +0000 Subject: [PATCH 110/140] [WDMAUD_KERNEL] - Always set Mute control on first channel [PORTCLS] - Rewrite node property handling. Fixes lots of bugs and fixes all winmm_winetest mixer failures svn path=/trunk/; revision=44323 --- .../audio/backpln/portcls/pin_wavecyclic.cpp | 4 +- .../wdm/audio/backpln/portcls/undoc.cpp | 465 ++++++++++-------- .../drivers/wdm/audio/legacy/wdmaud/mixer.c | 2 +- 3 files changed, 273 insertions(+), 198 deletions(-) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index 71e7b33bb66..c1850b00dfe 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -1243,8 +1243,8 @@ CPortPinWaveCyclic::Init( m_Port = Port; m_Filter = Filter; - //DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); - //DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); + DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); + DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); return STATUS_SUCCESS; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp index 4e567d18aa8..45e11cf90c1 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -86,6 +86,269 @@ PcHandleDisableEventWithTable( return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock); } +NTSTATUS +PcHandleGuidNullRequest( + IN OUT PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) +{ + PPCNODE_DESCRIPTOR Node; + PPCPROPERTY_ITEM PropertyItem; + PIO_STACK_LOCATION IoStack; + PKSP_NODE Property; + LPGUID Buffer; + ULONG Count = 0, SubIndex, Index; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + + // access property + Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) + { + // request is out of bounds + Irp->IoStatus.Information = 0; + return STATUS_INVALID_PARAMETER; + } + + Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); + + if (!Node->AutomationTable) + { + // request is out of bounds + Irp->IoStatus.Information = 0; + return STATUS_INVALID_PARAMETER; + } + + PC_ASSERT(Node->AutomationTable); + PC_ASSERT(Node->AutomationTable->PropertyCount); + PC_ASSERT(Node->AutomationTable->PropertyItemSize); + + Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; + for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) + { + BOOL Found = FALSE; + for (SubIndex = 0; SubIndex < Count; Index++) + { + if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set)) + { + Found = TRUE; + break; + } + } + if (!Found) + { + RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID)); + Count++; + } + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); + } + + // store result length + Irp->IoStatus.Information = sizeof (GUID) * Count; + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count) + { + // buffer too small + FreeItem(Buffer, TAG_PORTCLASS); + return STATUS_MORE_ENTRIES; + } + + RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count); + FreeItem(Buffer, TAG_PORTCLASS); + return STATUS_SUCCESS; +} + +NTSTATUS +PcFindNodePropertyHandler( + PIRP Irp, + PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, + OUT PPCPROPERTY_ITEM * OutPropertyItem) +{ + PPCNODE_DESCRIPTOR Node; + PPCPROPERTY_ITEM PropertyItem; + PIO_STACK_LOCATION IoStack; + PKSP_NODE Property; + ULONG Index; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // access property + Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) + { + // request is out of bounds + DPRINT("InvalidIndex %u %u\n", Property->NodeId, SubDeviceDescriptor->DeviceDescriptor->NodeCount); + return STATUS_INVALID_PARAMETER; + } + + Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); + + if (!Node->AutomationTable) + { + // request is out of bounds + Irp->IoStatus.Information = 0; + return STATUS_NOT_FOUND; + } + + // sanity checks + PC_ASSERT(Node->AutomationTable); + PC_ASSERT(Node->AutomationTable->PropertyCount); + PC_ASSERT(Node->AutomationTable->PropertyItemSize); + + PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; + + DPRINT("NodeId %u PropertyCount %u\n", Property->NodeId, Node->AutomationTable->PropertyCount); + for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) + { + if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id) + { + //found property handler + *OutPropertyItem = PropertyItem; + return STATUS_SUCCESS; + } + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); + } + + // no handler yet found + DPRINT("NotFound\n"); + return STATUS_NOT_FOUND; +} + +NTSTATUS +PcNodeBasicSupportHandler( + PIRP Irp, + PPCPROPERTY_ITEM PropertyItem) +{ + PULONG Flags; + PIO_STACK_LOCATION IoStack; + PKSPROPERTY_DESCRIPTION Description; + PKSP_NODE Property; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // access property + Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG)); + Flags= (PULONG)Irp->UserBuffer; + + // reset flags + *Flags = 0; + + if (PropertyItem->Flags & KSPROPERTY_TYPE_SET) + *Flags |= KSPROPERTY_TYPE_SET; + + if (PropertyItem->Flags & KSPROPERTY_TYPE_GET) + *Flags |= KSPROPERTY_TYPE_GET; + + // store result length + Irp->IoStatus.Information = sizeof(ULONG); + + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) + { + // get output buffer + Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer; + + // store result + Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); + Description->PropTypeSet.Set = KSPROPTYPESETID_General; + Description->PropTypeSet.Id = 0; + Description->PropTypeSet.Flags = 0; + Description->MembersListCount = 0; + Description->Reserved = 0; + + Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION); + } + return STATUS_SUCCESS; +} + + +NTSTATUS +PcHandleNodePropertyRequest( + PIRP Irp, + IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) +{ + PIO_STACK_LOCATION IoStack; + PPCPROPERTY_ITEM PropertyItem; + PPCPROPERTY_REQUEST PropertyRequest; + PKSP_NODE Property; + NTSTATUS Status; + + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) + { + // certainly not a node property request + return STATUS_NOT_FOUND; + } + + // access property + Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY)) + { + return PcHandleGuidNullRequest(Irp, SubDeviceDescriptor); + } + + // find property handler + Status = PcFindNodePropertyHandler(Irp, SubDeviceDescriptor, &PropertyItem); + + // check for success + if (!NT_SUCCESS(Status)) + { + // might not be a node property request + DPRINT("NotFound\n"); + return STATUS_NOT_FOUND; + } + + if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) + { + // caller issued a basic property request + if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) + { + // driver does not have a basic support handler + return PcNodeBasicSupportHandler(Irp, PropertyItem); + } + } + + // allocate a property request + PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); + if (!PropertyRequest) + return STATUS_INSUFFICIENT_RESOURCES; + + PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport; + PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream; + PropertyRequest->Irp = Irp; + PropertyRequest->Node = Property->NodeId; + PropertyRequest->PropertyItem = PropertyItem; + PropertyRequest->Verb = Property->Property.Flags; + PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY); + PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY)); + PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; + PropertyRequest->Value = Irp->UserBuffer; + + Status = PropertyItem->Handler(PropertyRequest); + + if (Status != STATUS_PENDING) + { + //request completed + Irp->IoStatus.Information = PropertyRequest->ValueSize; + ExFreePool(PropertyRequest); + } + + // done + DPRINT("Status %x\n", Status); + return Status; +} NTSTATUS NTAPI @@ -96,207 +359,19 @@ PcHandlePropertyWithTable( IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) { NTSTATUS Status; - PIO_STACK_LOCATION IoStack; - PKSP_NODE Property; - PPCNODE_DESCRIPTOR Node; - PPCPROPERTY_ITEM PropertyItem; - ULONG Index; - LPGUID Buffer; - //PULONG Flags; - PPCPROPERTY_REQUEST PropertyRequest; - KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; + // try handle it as node property request + Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor); - /* try first KsPropertyHandler */ - Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet); - - if (Status != STATUS_NOT_FOUND) - return Status; - - // get current irp stack location - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - // check if this a GUID_NULL request if (Status == STATUS_NOT_FOUND) { - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) - return Status; + // store device descriptor + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; - // check if its a request for a topology node - if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY)) - { - if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } - - Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); - - if (!Node->AutomationTable) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } - - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); - - Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS); - if (!Buffer) - return STATUS_INSUFFICIENT_RESOURCES; - - - ULONG Count = 0, SubIndex; - PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; - for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) - { - BOOL Found = FALSE; - for (SubIndex = 0; SubIndex < Count; Index++) - { - if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set)) - { - Found = TRUE; - break; - } - } - if (!Found) - { - RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID)); - Count++; - } - PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); - } - - Irp->IoStatus.Information = sizeof (GUID) * Count; - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count) - { - // buffer too small - FreeItem(Buffer, TAG_PORTCLASS); - return STATUS_MORE_ENTRIES; - } - - RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count); - FreeItem(Buffer, TAG_PORTCLASS); - return STATUS_SUCCESS; - } - else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY) || - Property->Property.Flags == (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY) || - Property->Property.Flags == (KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY)) */ - { - //UNICODE_STRING GuidString; - - if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } - - Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); - - if (!Node->AutomationTable) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_NOT_FOUND; - } - - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); - - PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; - - for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) - { - if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id) - { - if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) - { - if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) - { - PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG)); - PULONG Flags = (PULONG)Irp->UserBuffer; - - /* reset flags */ - *Flags = 0; - - if (PropertyItem->Flags & KSPROPERTY_TYPE_SET) - *Flags |= KSPROPERTY_TYPE_SET; - - if (PropertyItem->Flags & KSPROPERTY_TYPE_GET) - *Flags |= KSPROPERTY_TYPE_GET; - - Irp->IoStatus.Information = sizeof(ULONG); - - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) - { - /* get output buffer */ - PKSPROPERTY_DESCRIPTION Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer; - - /* store result */ - Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); - Description->PropTypeSet.Set = KSPROPTYPESETID_General; - Description->PropTypeSet.Id = 0; - Description->PropTypeSet.Flags = 0; - Description->MembersListCount = 0; - Description->Reserved = 0; - - Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION); - } - return STATUS_SUCCESS; - } - } - - - PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); - if (!PropertyRequest) - return STATUS_INSUFFICIENT_RESOURCES; - - PC_ASSERT(SubDeviceDescriptor->UnknownMiniport); - PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport; - PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream; - PropertyRequest->Irp = Irp; - PropertyRequest->Node = Property->NodeId; - PropertyRequest->PropertyItem = PropertyItem; - PropertyRequest->Verb = Property->Property.Flags; - PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY); - PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY)); - PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; - PropertyRequest->Value = Irp->UserBuffer; - - Status = PropertyItem->Handler(PropertyRequest); - - if (Status != STATUS_PENDING) - { - //DPRINT("Status %x ValueSize %u - - Irp->IoStatus.Information = PropertyRequest->ValueSize; - ExFreePool(PropertyRequest); - } -#if 0 - RtlStringFromGUID(Property->Property.Set, &GuidString); - DPRINT("Id %u Flags %x Set %S FlagsItem %x Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, PropertyItem->Flags, Status); - RtlFreeUnicodeString(&GuidString); -#endif - return Status; - } - PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); - } -#if 0 - RtlStringFromGUID(Property->Property.Set, &GuidString); - DPRINT("Id %u Flags %x Set %S Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, Status); - RtlFreeUnicodeString(&GuidString); -#endif - } + /* then try KsPropertyHandler */ + Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet); } + return Status; } diff --git a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c index 946d45bb9c8..5de3872e55d 100644 --- a/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c +++ b/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c @@ -2162,7 +2162,7 @@ SetGetMuteControlDetails( Value = Input->fValue; /* set control details */ - Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, MAXULONG, &Value); + Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value); if (!NT_SUCCESS(Status)) return Status; From e4abf36dc6d3090e1252b8ef168304221674a645 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 29 Nov 2009 19:29:52 +0000 Subject: [PATCH 111/140] - Partly revert 44309 as it sometimes causes problems svn path=/trunk/; revision=44324 --- .../audio/backpln/portcls/pin_wavecyclic.cpp | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index c1850b00dfe..22682f9923f 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -415,10 +415,10 @@ PinWaveCyclicState( IN PKSIDENTIFIER Request, IN OUT PVOID Data) { + NTSTATUS Status = STATUS_UNSUCCESSFUL; CPortPinWaveCyclic *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; PKSSTATE State = (PKSSTATE)Data; - PSETPIN_CONTEXT PinWorkContext; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); @@ -436,20 +436,24 @@ PinWaveCyclicState( if (Request->Flags & KSPROPERTY_TYPE_SET) { - PinWorkContext = (PSETPIN_CONTEXT)AllocateItem(NonPagedPool, sizeof(PSETPIN_CONTEXT), TAG_PORTCLASS); - PC_ASSERT(PinWorkContext); + // try set stream + Status = Pin->m_Stream->SetState(*State); - PinWorkContext->WorkItem = IoAllocateWorkItem(IoGetCurrentIrpStackLocation(Irp)->DeviceObject); - PC_ASSERT(PinWorkContext->WorkItem); - // initialize work item context - PinWorkContext->NewState = *State; - PinWorkContext->Pin = Pin; - PinWorkContext->Irp = Irp; + DPRINT("Setting state %u %x\n", *State, Status); + if (NT_SUCCESS(Status)) + { + // store new state + Pin->m_State = *State; - IoMarkIrpPending(Irp); - - IoQueueWorkItem(PinWorkContext->WorkItem, PinSetStateWorkerRoutine, DelayedWorkQueue, (PVOID)PinWorkContext); - return STATUS_PENDING; + if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP) + { + // FIXME + // complete with successful state + Pin->m_IrpQueue->CancelBuffers(); + } + // store result + Irp->IoStatus.Information = sizeof(KSSTATE); + } } else if (Request->Flags & KSPROPERTY_TYPE_GET) { @@ -457,7 +461,7 @@ PinWaveCyclicState( *State = Pin->m_State; // store result Irp->IoStatus.Information = sizeof(KSSTATE); - DPRINT1("Getting state %u %x\n", *State, STATUS_SUCCESS); + return STATUS_SUCCESS; } @@ -1243,8 +1247,8 @@ CPortPinWaveCyclic::Init( m_Port = Port; m_Filter = Filter; - DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); - DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); + //DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); + //DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); return STATUS_SUCCESS; } From 647f63f8810be0068323342d37351c6b5e6a8908 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 29 Nov 2009 21:17:15 +0000 Subject: [PATCH 112/140] [MMEBUDDY] - Return correct error code - Fixes last 4 four winmm_winetest mixer test failures svn path=/trunk/; revision=44325 --- reactos/lib/drivers/sound/mmebuddy/utility.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/lib/drivers/sound/mmebuddy/utility.c b/reactos/lib/drivers/sound/mmebuddy/utility.c index db547992eab..0a53fdf43a8 100644 --- a/reactos/lib/drivers/sound/mmebuddy/utility.c +++ b/reactos/lib/drivers/sound/mmebuddy/utility.c @@ -113,6 +113,10 @@ Win32ErrorToMmResult( case ERROR_INSUFFICIENT_BUFFER : return MMSYSERR_INVALPARAM; + case ERROR_INVALID_PARAMETER : + return MMSYSERR_INVALPARAM; + + default : return MMSYSERR_ERROR; } From 7759e8983b091515c71b6b2a582d7f476b1b598f Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sun, 29 Nov 2009 22:58:33 +0000 Subject: [PATCH 113/140] [WDMAUD.DRV] - Implement support for resetting a stream (not yet used) - Don't translate the error again in QueryMixerInfo as SyncOverlappedDeviceIoControl has already translated the error - Don't touch the cbSize member when opening a wave device, as the caller might have passed a WAVEFORMAT struct instead a WAVEFORMATEX struct. Fixes winmm_winetest wave / mixer crashs - Query all available events when an mixer event is fired svn path=/trunk/; revision=44326 --- reactos/dll/win32/wdmaud.drv/wdmaud.c | 71 ++++++++++++++++++++------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/reactos/dll/win32/wdmaud.drv/wdmaud.c b/reactos/dll/win32/wdmaud.drv/wdmaud.c index 325df20f881..9d3922f01e3 100644 --- a/reactos/dll/win32/wdmaud.drv/wdmaud.c +++ b/reactos/dll/win32/wdmaud.drv/wdmaud.c @@ -321,24 +321,27 @@ MixerEventThreadRoutine( break; } - Result = SyncOverlappedDeviceIoControl(KernelHandle, - IOCTL_GET_MIXER_EVENT, - (LPVOID) &DeviceInfo, - sizeof(WDMAUD_DEVICE_INFO), - (LPVOID) &DeviceInfo, - sizeof(WDMAUD_DEVICE_INFO), - NULL); - - if (Result == MMSYSERR_NOERROR) + do { - DriverCallback(Instance->WinMM.ClientCallback, - HIWORD(Instance->WinMM.Flags), - Instance->WinMM.Handle, - DeviceInfo.u.MixerEvent.NotificationType, - Instance->WinMM.ClientCallbackInstanceData, - (DWORD_PTR)DeviceInfo.u.MixerEvent.Value, - 0); - } + Result = SyncOverlappedDeviceIoControl(KernelHandle, + IOCTL_GET_MIXER_EVENT, + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + NULL); + + if (Result == MMSYSERR_NOERROR) + { + DriverCallback(Instance->WinMM.ClientCallback, + HIWORD(Instance->WinMM.Flags), + Instance->WinMM.Handle, + DeviceInfo.u.MixerEvent.NotificationType, + Instance->WinMM.ClientCallbackInstanceData, + (DWORD_PTR)DeviceInfo.u.MixerEvent.Value, + 0); + } + }while(Result == MMSYSERR_NOERROR); }while(TRUE); /* done */ @@ -443,7 +446,7 @@ SetWdmWaveDeviceFormat( ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); DeviceInfo.DeviceType = DeviceType; DeviceInfo.DeviceIndex = DeviceId; - DeviceInfo.u.WaveFormatEx.cbSize = WaveFormat->cbSize; + DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize; DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag; #ifdef USERMODE_MIXER DeviceInfo.u.WaveFormatEx.nChannels = 2; @@ -746,6 +749,35 @@ GetWdmPosition( return MMSYSERR_NOERROR; } +MMRESULT +ResetStream( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN MMDEVICE_TYPE DeviceType, + IN BOOLEAN bStartReset) +{ + MMRESULT Result; + HANDLE Handle; + WDMAUD_DEVICE_INFO DeviceInfo; + + Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); + SND_ASSERT( Result == MMSYSERR_NOERROR ); + + ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); + DeviceInfo.hDevice = Handle; + DeviceInfo.DeviceType = DeviceType; + DeviceInfo.u.ResetStream = (bStartReset ? KSRESET_BEGIN : KSRESET_END); + + Result = SyncOverlappedDeviceIoControl(KernelHandle, + IOCTL_RESET_STREAM, + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + (LPVOID) &DeviceInfo, + sizeof(WDMAUD_DEVICE_INFO), + NULL); + return Result; +} + + MMRESULT QueryMixerInfo( IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, @@ -808,7 +840,7 @@ QueryMixerInfo( if ( ! MMSUCCESS(Result) ) { - return TranslateInternalMmResult(Result); + return Result; } switch(uMsg) @@ -876,6 +908,7 @@ PopulateWdmDeviceList( if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) { FuncTable.SetState = SetWdmWaveState; + FuncTable.ResetStream = ResetStream; } FuncTable.Open = OpenWdmSoundDevice; From ced89bf1a11f7ed013c641efdef16d6a56dc461a Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Mon, 30 Nov 2009 01:50:47 +0000 Subject: [PATCH 114/140] Updated the rapps Software list. AbiWord from 2.6.4 to 2.6.8 MinGW from 5.1.4 to 5.1.6 MirandaIM from 0.8.9 to 0.8.10 Opera from 9.6.4 to 10.10 (YES, this works!) SDL Mixer from 1.2.9 to 1.2.11 SeaMonkey from 1.1.18 to 2.0 (YES, that too!) UltraVNC from 1.0.6.5 to 1.0.8.0 uTorrent from 1.8.4 to 1.8.5 vlc from 1.0.2 to 1.0.3 svn path=/trunk/; revision=44328 --- .../base/applications/rapps/rapps/abiword.txt | 6 +++--- .../base/applications/rapps/rapps/mingw.txt | 6 +++--- .../applications/rapps/rapps/mirandaim.txt | 6 +++--- .../base/applications/rapps/rapps/opera.txt | 6 +++--- .../applications/rapps/rapps/sdl_mixer.txt | 6 +++--- .../applications/rapps/rapps/seamonkey.txt | 20 +++++++++---------- .../applications/rapps/rapps/ultravnc.txt | 4 ++-- .../applications/rapps/rapps/utorrent.txt | 4 ++-- reactos/base/applications/rapps/rapps/vlc.txt | 6 +++--- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/reactos/base/applications/rapps/rapps/abiword.txt b/reactos/base/applications/rapps/rapps/abiword.txt index 336af4b9adc..c6da039bead 100644 --- a/reactos/base/applications/rapps/rapps/abiword.txt +++ b/reactos/base/applications/rapps/rapps/abiword.txt @@ -2,13 +2,13 @@ [Section] Name = AbiWord -Version = 2.6.4 +Version = 2.6.8 Licence = GPL Description = Word processor. -Size = 5.9MB +Size = 5.6MB Category = 6 URLSite = http://www.abisource.com/ -URLDownload = http://www.abisource.com/downloads/abiword/2.6.4/Windows/abiword-setup-2.6.4.exe +URLDownload = http://www.abisource.com/downloads/abiword/2.6.8/Windows/abiword-setup-2.6.8.exe CDPath = none [Section.0407] diff --git a/reactos/base/applications/rapps/rapps/mingw.txt b/reactos/base/applications/rapps/rapps/mingw.txt index 2e2fabe312f..109c99bc61d 100644 --- a/reactos/base/applications/rapps/rapps/mingw.txt +++ b/reactos/base/applications/rapps/rapps/mingw.txt @@ -2,13 +2,13 @@ [Section] Name = MinGW -Version = 5.1.4 +Version = 5.1.6 Licence = Public domain/GPL Description = A Port of the GNU toolchain with GCC, GDB, GNU make, etc. -Size = 136kb +Size = 155kb Category = 7 URLSite = http://mingw.org/ -URLDownload = http://ovh.dl.sourceforge.net/sourceforge/mingw/MinGW-5.1.4.exe +URLDownload = http://ovh.dl.sourceforge.net/sourceforge/mingw/MinGW-5.1.6.exe CDPath = none diff --git a/reactos/base/applications/rapps/rapps/mirandaim.txt b/reactos/base/applications/rapps/rapps/mirandaim.txt index 315a6a398d0..cfa1f1b164c 100644 --- a/reactos/base/applications/rapps/rapps/mirandaim.txt +++ b/reactos/base/applications/rapps/rapps/mirandaim.txt @@ -1,14 +1,14 @@ -; UTF-8 +; UTF-8 [Section] Name = Miranda IM -Version = 0.8.9 +Version = 0.8.10 Licence = GPL Description = Open source multiprotocol instant messaging application - May not work completely. Size = 1.6MB Category = 5 URLSite = http://www.miranda-im.org/ -URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.9-unicode.exe +URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.8.10-unicode.exe CDPath = none diff --git a/reactos/base/applications/rapps/rapps/opera.txt b/reactos/base/applications/rapps/rapps/opera.txt index a1d9b51acf4..3590f668f52 100644 --- a/reactos/base/applications/rapps/rapps/opera.txt +++ b/reactos/base/applications/rapps/rapps/opera.txt @@ -2,13 +2,13 @@ [Section] Name = Opera -Version = 9.64 +Version = 10.10 Licence = Freeware Description = The popular Opera Browser with many advanced features and including a Mail and BitTorrent client. -Size = 7.1M +Size = 11.0M Category = 5 URLSite = http://www.opera.com/ -URLDownload = http://ftp.opera.com/pub/opera/win/964/int/Opera_964_int_Setup.exe +URLDownload = http://ftp.opera.com/pub/opera/win/1010/int/Opera_1010_in_Setup.exe CDPath = none [Section.0419] diff --git a/reactos/base/applications/rapps/rapps/sdl_mixer.txt b/reactos/base/applications/rapps/rapps/sdl_mixer.txt index 950c48cc5d8..eaa3c51ec24 100644 --- a/reactos/base/applications/rapps/rapps/sdl_mixer.txt +++ b/reactos/base/applications/rapps/rapps/sdl_mixer.txt @@ -1,14 +1,14 @@ -; UTF-8 +; UTF-8 [Section] Name = Simple Direct Media Layer (SDL) Mixer -Version = 1.2.9 +Version = 1.2.11 Licence = LGPL Description = Needed for some Open Source Games to run. You need 7-Zip or a similar Utility to extract it. Size = 307kB Category = 14 URLSite = http://www.libsdl.org/projects/SDL_mixer/ -URLDownload = http://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-1.2.9-win32.zip +URLDownload = http://www.libsdl.org/projects/SDL_mixer/release/SDL_mixer-1.2.11-win32.zip CDPath = none diff --git a/reactos/base/applications/rapps/rapps/seamonkey.txt b/reactos/base/applications/rapps/rapps/seamonkey.txt index c10db18ef91..c79f31f3b7c 100644 --- a/reactos/base/applications/rapps/rapps/seamonkey.txt +++ b/reactos/base/applications/rapps/rapps/seamonkey.txt @@ -2,26 +2,26 @@ [Section] Name = Mozilla SeaMonkey -Version = 1.1.18 +Version = 2.0 Licence = MPL/GPL/LGPL Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Chat, and Composer bundle you will ever need. -Size = 12.4MB +Size = 10.0MB Category = 5 URLSite = http://www.seamonkey-project.org/ -URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/1.1.18/seamonkey-1.1.18.en-US.win32.installer.exe +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0/win32/en-US/SeaMonkey%20Setup%202.0.exe CDPath = none [Section.0419] Description = Продолжение Mozilla Suite. Включает браŃзер, почтовый клиент, IRC-клиент и HTML-редактор. -Size = 9.0MB -URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/1.1.18/contrib-localized/seamonkey-1.1.18.ru-RU.win32.installer.exe +Size = 10.4MB +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0/win32/ru/SeaMonkey%20Setup%202.0.exe [Section.0407] -Description = Mozilla Suite ist lebendig. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen. -Size = 9.0MB -URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/1.1.18/contrib-localized/seamonkey-1.1.18.de-AT.win32.installer.exe +Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen. +Size = 10.0MB +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0/win32/de/SeaMonkey%20Setup%202.0.exe [Section.0415] Description = Pakiet Mozilla ĹĽyje. W zestawie: przeglÄ…darka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz. -Size = 12.4MB -URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/1.1.18/contrib-localized/seamonkey-1.1.18.pl-PL.win32.installer.exe +Size = 10.8MB +URLDownload = http://ftp.df.lth.se/mozilla/seamonkey/releases/2.0/win32/pl/SeaMonkey%20Setup%202.0.exe diff --git a/reactos/base/applications/rapps/rapps/ultravnc.txt b/reactos/base/applications/rapps/rapps/ultravnc.txt index ca7568496e5..90587d3b9cd 100644 --- a/reactos/base/applications/rapps/rapps/ultravnc.txt +++ b/reactos/base/applications/rapps/rapps/ultravnc.txt @@ -2,11 +2,11 @@ [Section] Name = UltraVNC -Version = 1.0.6.5 +Version = 1.0.8.0 Licence = GPL Description = Open-source VNC client/server Size = 1.9MB Category = 5 URLSite = http://www.uvnc.com -URLDownload = http://support1.uvnc.com/download/1065/UltraVNC_1.0.6.5_Setup.exe +URLDownload = http://support1.uvnc.com/download/1080/UltraVNC_1.0.8.0_Setup.exe CDPath = none diff --git a/reactos/base/applications/rapps/rapps/utorrent.txt b/reactos/base/applications/rapps/rapps/utorrent.txt index 409ee45ad51..e36aecf4095 100644 --- a/reactos/base/applications/rapps/rapps/utorrent.txt +++ b/reactos/base/applications/rapps/rapps/utorrent.txt @@ -2,13 +2,13 @@ [Section] Name = µTorrent -Version = 1.8.4 +Version = 1.8.5 Licence = Freeware for non-commercial uses Description = Small and fast BitTorrent Client. Size = 282K Category = 5 URLSite = http://www.utorrent.com/ -URLDownload = http://download.utorrent.com/1.8.3/utorrent.exe +URLDownload = http://download.utorrent.com/1.8.5/utorrent.exe CDPath = none [Section.0419] diff --git a/reactos/base/applications/rapps/rapps/vlc.txt b/reactos/base/applications/rapps/rapps/vlc.txt index 9e708c75b36..57e89bd17d1 100644 --- a/reactos/base/applications/rapps/rapps/vlc.txt +++ b/reactos/base/applications/rapps/rapps/vlc.txt @@ -2,11 +2,11 @@ [Section] Name = VLC media player -Version = 1.0.2 +Version = 1.0.3 Licence = GPL Description = A media player. -Size = 18MB +Size = 17.2MB Category = 1 URLSite = http://www.videolan.org/vlc/ -URLDownload = http://mirror.services.wisc.edu/mirrors/videolan/vlc/1.0.2/win32/vlc-1.0.2-win32.exe +URLDownload = http://mirror.services.wisc.edu/mirrors/videolan/vlc/1.0.3/win32/vlc-1.0.3-win32.exe CDPath = none From bb403d5976f5364b3aea2c8e46f7e0f67b285804 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 30 Nov 2009 14:55:20 +0000 Subject: [PATCH 115/140] Fix build breakage svn path=/trunk/; revision=44329 --- reactos/include/reactos/libs/sound/mmebuddy.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/reactos/include/reactos/libs/sound/mmebuddy.h b/reactos/include/reactos/libs/sound/mmebuddy.h index 9f2ce0fe657..4e1583230c1 100644 --- a/reactos/include/reactos/libs/sound/mmebuddy.h +++ b/reactos/include/reactos/libs/sound/mmebuddy.h @@ -249,6 +249,10 @@ typedef MMRESULT(*MMQUERYDEVICEINTERFACESTRING_FUNC)( IN DWORD InterfaceLength, OUT DWORD * InterfaceSize); +typedef MMRESULT(*MMRESETSTREAM_FUNC)( + IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, + IN MMDEVICE_TYPE DeviceType, + IN BOOLEAN bStartReset); typedef struct _MMFUNCTION_TABLE { @@ -274,6 +278,7 @@ typedef struct _MMFUNCTION_TABLE MMGETPOS_FUNC GetPos; MMSETSTATE_FUNC SetState; MMQUERYDEVICEINTERFACESTRING_FUNC GetDeviceInterfaceString; + MMRESETSTREAM_FUNC ResetStream; // Redundant //MMWAVEHEADER_FUNC PrepareWaveHeader; From 8a06fa021a5994050108dd358b0cb075f8fbaf0d Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Mon, 30 Nov 2009 17:00:12 +0000 Subject: [PATCH 116/140] Apply font changes from r44305 to mainline. svn path=/trunk/; revision=44330 --- reactos/base/setup/usetup/muifonts.h | 12 ++++----- reactos/base/setup/usetup/muilanguages.h | 14 +++++------ reactos/boot/bootdata/packages/reactos.dff | 3 ++- reactos/media/inf/font.inf | 29 ++++++++++++++++------ 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/reactos/base/setup/usetup/muifonts.h b/reactos/base/setup/usetup/muifonts.h index 1cbdd22eef9..399a7eb460d 100644 --- a/reactos/base/setup/usetup/muifonts.h +++ b/reactos/base/setup/usetup/muifonts.h @@ -59,18 +59,18 @@ MUI_SUBFONT HebrewFonts[] = { NULL, NULL } }; -MUI_SUBFONT JapaneseFonts[] = +MUI_SUBFONT CJKFonts[] = { { L"Arial", L"Liberation Sans" }, { L"Courier", L"FreeMono" }, { L"Courier New", L"FreeMono" }, { L"Times New Roman", L"Liberation Serif" }, - { L"Tahoma", L"Systema" }, + { L"Tahoma", L"Droid Sans Fallback" }, { L"MS Sans Serif", L"Tahoma" }, - { L"MS Shell Dlg", L"Systema" }, - { L"MS Shell Dlg 2", L"Systema" }, - { L"MS UI Gothic", L"Systema" }, - { L"MS UI Gothic 2", L"Systema" }, + { L"MS Shell Dlg", L"Droid Sans Fallback" }, + { L"MS Shell Dlg 2", L"Droid Sans Fallback" }, + { L"MS UI Gothic", L"Droid Sans Fallback" }, + { L"MS UI Gothic 2", L"Droid Sans Fallback" }, { L"Helv", L"Tahoma" }, { NULL, NULL } }; diff --git a/reactos/base/setup/usetup/muilanguages.h b/reactos/base/setup/usetup/muilanguages.h index 59b9fed42fd..59b11591397 100644 --- a/reactos/base/setup/usetup/muilanguages.h +++ b/reactos/base/setup/usetup/muilanguages.h @@ -165,11 +165,11 @@ const MUI_LANGUAGE LanguageList[] = {L"00000402", L"1251", L"866", L"10007", L"Bulgarian", L"359", bgBGPages, bgBGErrorEntries, bgBGStrings, CyrillicFonts, bgBGLayouts }, {L"00000455", L"0", L"1", L"2", L"Burmese", L"1", enUSPages, enUSErrorEntries, enUSStrings, UnicodeFonts, myMMLayouts }, {L"00000403", L"1252", L"850", L"10000", L"Catalan", L"1", enUSPages, enUSErrorEntries, enUSStrings, LatinFonts, caESLayouts }, - {L"00000404", L"950", L"950", L"10008", L"Chinese (Taiwan)", L"886", enUSPages, enUSErrorEntries, enUSStrings, UnicodeFonts, zhTWLayouts }, - {L"00000804", L"936", L"936", L"10008", L"Chinese (PRC)", L"86", enUSPages, enUSErrorEntries, enUSStrings, UnicodeFonts, zhCNLayouts }, - {L"00000C04", L"950", L"950", L"10008", L"Chinese (Hong Kong S.A.R.)", L"1", enUSPages, enUSErrorEntries, enUSStrings, UnicodeFonts, zhHKLayouts }, - {L"00001004", L"936", L"936", L"10008", L"Chinese (Singapore)", L"1", enUSPages, enUSErrorEntries, enUSStrings, UnicodeFonts, zhSGLayouts }, - {L"00001404", L"950", L"950", L"10002", L"Chinese (Macau S.A.R.)", L"1", enUSPages, enUSErrorEntries, enUSStrings, UnicodeFonts, zhMOLayouts }, + {L"00000404", L"950", L"950", L"10008", L"Chinese (Taiwan)", L"886", enUSPages, enUSErrorEntries, enUSStrings, CJKFonts, zhTWLayouts }, + {L"00000804", L"936", L"936", L"10008", L"Chinese (PRC)", L"86", enUSPages, enUSErrorEntries, enUSStrings, CJKFonts, zhCNLayouts }, + {L"00000C04", L"950", L"950", L"10008", L"Chinese (Hong Kong S.A.R.)", L"1", enUSPages, enUSErrorEntries, enUSStrings, CJKFonts, zhHKLayouts }, + {L"00001004", L"936", L"936", L"10008", L"Chinese (Singapore)", L"1", enUSPages, enUSErrorEntries, enUSStrings, CJKFonts, zhSGLayouts }, + {L"00001404", L"950", L"950", L"10002", L"Chinese (Macau S.A.R.)", L"1", enUSPages, enUSErrorEntries, enUSStrings, CJKFonts, zhMOLayouts }, {L"0000041A", L"1250", L"852", L"10029", L"Croatian", L"385", enUSPages, enUSErrorEntries, enUSStrings, LatinFonts, hrHRLayouts }, {L"00000405", L"1250", L"852", L"10029", L"Czech", L"420", csCZPages, csCZErrorEntries, csCZStrings, LatinFonts, csCZLayouts }, {L"00000406", L"1252", L"850", L"10000", L"Danish", L"45", enUSPages, enUSErrorEntries, enUSStrings, LatinFonts, daDKLayouts }, @@ -216,11 +216,11 @@ const MUI_LANGUAGE LanguageList[] = {L"00000421", L"1252", L"850", L"10079", L"Indonesian", L"62", enUSPages, enUSErrorEntries, enUSStrings, LatinFonts, idIDLayouts }, {L"00000410", L"1252", L"850", L"10000", L"Italian (Italy)", L"39", itITPages, itITErrorEntries, itITStrings, LatinFonts, itITLayouts }, {L"00000810", L"1252", L"850", L"10000", L"Italian (Switzerland)", L"41", itITPages, itITErrorEntries, itITStrings, LatinFonts, itCHLayouts }, - {L"00000411", L"932", L"932", L"10001", L"Japanese", L"81", jaJPPages, jaJPErrorEntries, jaJPStrings, JapaneseFonts, jaJPLayouts }, + {L"00000411", L"932", L"932", L"10001", L"Japanese", L"81", jaJPPages, jaJPErrorEntries, jaJPStrings, CJKFonts, jaJPLayouts }, {L"0000044B", L"1252", L"437", L"10079", L"Kannada (India)", L"91", enUSPages, enUSErrorEntries, enUSStrings, LatinFonts, knINLayouts }, {L"0000043F", L"1251", L"866", L"10007", L"Kazakh", L"705", enUSPages, enUSErrorEntries, enUSStrings, CyrillicFonts, kkKZLayouts }, {L"00000457", L"0", L"437", L"2", L"Konkani", L"1", enUSPages, enUSErrorEntries, enUSStrings, UnicodeFonts, kokINLayouts}, - {L"00000412", L"949", L"949", L"10003", L"Korean", L"1", enUSPages, enUSErrorEntries, enUSStrings, UnicodeFonts, koKRLayouts }, + {L"00000412", L"949", L"949", L"10003", L"Korean", L"1", enUSPages, enUSErrorEntries, enUSStrings, CJKFonts, koKRLayouts }, {L"00000440", L"1251", L"866", L"10007", L"Kyrgyz (Kyrgyzstan)", L"1", enUSPages, enUSErrorEntries, enUSStrings, CyrillicFonts, kyKGLayouts }, {L"00000426", L"1257", L"775", L"10029", L"Latvian", L"371", enUSPages, enUSErrorEntries, enUSStrings, LatinFonts, lvLVLayouts }, {L"00000427", L"1257", L"775", L"10029", L"Lithuanian", L"370", ltLTPages, ltLTErrorEntries, ltLTStrings, LatinFonts, ltLTLayouts }, diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index bf616387568..d9d690f9924 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -667,6 +667,8 @@ subsystems\ntvdm\ntvdm.exe 1 subsystems\win32\win32k\win32k.sys 1 ; Optional/proprietary files +modules\optional\DroidSansFallback.ttf 3 optional +modules\optional\NOTICE_for_Droid_Font.txt 4 optional modules\optional\netkvm2k.inf 6 optional modules\optional\netkvm2k.cat 6 optional modules\optional\netkvm.sys 2 optional @@ -681,7 +683,6 @@ modules\optional\msvbvm60.dll 1 optional modules\optional\msvcirt.dll 1 optional modules\optional\msvcp71.dll 1 optional modules\optional\msvcr71.dll 1 optional -modules\optional\Systema.ttf 3 optional modules\optional\vmx_fb.dll 1 optional modules\optional\vmx_mode.dll 1 optional modules\optional\vmx_svga.inf 6 optional diff --git a/reactos/media/inf/font.inf b/reactos/media/inf/font.inf index d22911404e7..99c8af93adf 100644 --- a/reactos/media/inf/font.inf +++ b/reactos/media/inf/font.inf @@ -67,6 +67,19 @@ HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","MS Shell HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","MS Shell Dlg 2",0x00000000,"DejaVu Sans" HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Helv",0x00000000,"DejaVu Sans" +[Font.CJK.Reg] +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Arial",0x00000000,"Liberation Sans" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Courier",0x00000000,"FreeMono" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Courier New",0x00000000,"FreeMono" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Times New Roman",0x00000000,"Liberation Serif" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Tahoma",0x00000000,"Droid Sans Fallback" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","MS Sans Serif",0x00000000,"Tahoma" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","MS Shell Dlg",0x00000000,"Droid Sans Fallback" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","MS Shell Dlg 2",0x00000000,"Droid Sans Fallback" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","MS UI Gothic",0x00000000,"Droid Sans Fallback" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","MS UI Gothic 2",0x00000000,"Droid Sans Fallback" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Helv",0x00000000,"Tahoma" + [Font.Unicode.Reg] HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Arial",0x00000000,"DejaVu Sans" HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SysFontSubstitutes","Courier",0x00000000,"DejaVu Sans Mono" @@ -234,38 +247,38 @@ AddReg = Font.Unicode.Reg ; cp932/cp932 Japanese [Font.CP932.96] AddReg = Font.Reg.96 -AddReg = Font.Unicode.Reg +AddReg = Font.CJK.Reg [Font.CP932.120] AddReg = Font.Reg.120 -AddReg = Font.Unicode.Reg +AddReg = Font.CJK.Reg ; cp936/cp936 Simplified Chinese [Font.CP936.96] AddReg = Font.Reg.96 -AddReg = Font.Unicode.Reg +AddReg = Font.CJK.Reg [Font.CP936.120] AddReg = Font.Reg.120 -AddReg = Font.Unicode.Reg +AddReg = Font.CJK.Reg ; cp949/cp949 Korean [Font.CP949.96] AddReg = Font.Reg.96 -AddReg = Font.Unicode.Reg +AddReg = Font.CJK.Reg [Font.CP949.120] AddReg = Font.Reg.120 -AddReg = Font.Unicode.Reg +AddReg = Font.CJK.Reg ; cp950/cp950 Traditional Chinese [Font.CP950.96] AddReg = Font.Reg.96 -AddReg = Font.Unicode.Reg +AddReg = Font.CJK.Reg [Font.CP950.120] AddReg = Font.Reg.120 -AddReg = Font.Unicode.Reg +AddReg = Font.CJK.Reg [Font Sizes] Small Fonts = 96 From e3e3b99e8e40d896081fe816128222780f9d0d6c Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 30 Nov 2009 18:54:41 +0000 Subject: [PATCH 117/140] - First version of ReactOS Sound Record Application by Marco Pagliaricci (IRC: rendar) svn path=/trunk/; revision=44331 --- .../base/applications/sndrec32/audio_def.hpp | 34 + .../applications/sndrec32/audio_format.cpp | 24 + .../applications/sndrec32/audio_format.hpp | 147 +++ .../applications/sndrec32/audio_membuffer.cpp | 501 ++++++++ .../applications/sndrec32/audio_membuffer.hpp | 338 ++++++ .../applications/sndrec32/audio_producer.cpp | 12 + .../applications/sndrec32/audio_producer.hpp | 112 ++ .../applications/sndrec32/audio_receiver.cpp | 17 + .../applications/sndrec32/audio_receiver.hpp | 103 ++ .../sndrec32/audio_resampler_acm.cpp | 387 ++++++ .../sndrec32/audio_resampler_acm.hpp | 99 ++ .../applications/sndrec32/audio_wavein.cpp | 880 ++++++++++++++ .../applications/sndrec32/audio_wavein.hpp | 271 +++++ .../applications/sndrec32/audio_waveout.cpp | 889 ++++++++++++++ .../applications/sndrec32/audio_waveout.hpp | 186 +++ .../base/applications/sndrec32/bitmap1.bmp | 0 .../base/applications/sndrec32/but_end.bmp | Bin 0 -> 1046 bytes .../base/applications/sndrec32/but_play.bmp | Bin 0 -> 1046 bytes .../base/applications/sndrec32/but_rec.bmp | Bin 0 -> 1046 bytes .../base/applications/sndrec32/but_start.bmp | Bin 0 -> 1046 bytes .../base/applications/sndrec32/but_stop.bmp | Bin 0 -> 1046 bytes .../base/applications/sndrec32/kkaudio.hpp | 18 + .../sndrec32/reactOS_sndrec32.ico | Bin 0 -> 23558 bytes reactos/base/applications/sndrec32/resource.h | 44 + reactos/base/applications/sndrec32/small.ico | Bin 0 -> 23558 bytes .../base/applications/sndrec32/sndrec32.cpp | 1042 +++++++++++++++++ reactos/base/applications/sndrec32/sndrec32.h | 96 ++ .../applications/sndrec32/sndrec32.rbuild | 20 + .../base/applications/sndrec32/sndrec32.rc | 179 +++ reactos/base/applications/sndrec32/stdafx.h | 23 + .../base/applications/sndrec32/targetver.h | 24 + 31 files changed, 5446 insertions(+) create mode 100644 reactos/base/applications/sndrec32/audio_def.hpp create mode 100644 reactos/base/applications/sndrec32/audio_format.cpp create mode 100644 reactos/base/applications/sndrec32/audio_format.hpp create mode 100644 reactos/base/applications/sndrec32/audio_membuffer.cpp create mode 100644 reactos/base/applications/sndrec32/audio_membuffer.hpp create mode 100644 reactos/base/applications/sndrec32/audio_producer.cpp create mode 100644 reactos/base/applications/sndrec32/audio_producer.hpp create mode 100644 reactos/base/applications/sndrec32/audio_receiver.cpp create mode 100644 reactos/base/applications/sndrec32/audio_receiver.hpp create mode 100644 reactos/base/applications/sndrec32/audio_resampler_acm.cpp create mode 100644 reactos/base/applications/sndrec32/audio_resampler_acm.hpp create mode 100644 reactos/base/applications/sndrec32/audio_wavein.cpp create mode 100644 reactos/base/applications/sndrec32/audio_wavein.hpp create mode 100644 reactos/base/applications/sndrec32/audio_waveout.cpp create mode 100644 reactos/base/applications/sndrec32/audio_waveout.hpp create mode 100644 reactos/base/applications/sndrec32/bitmap1.bmp create mode 100644 reactos/base/applications/sndrec32/but_end.bmp create mode 100644 reactos/base/applications/sndrec32/but_play.bmp create mode 100644 reactos/base/applications/sndrec32/but_rec.bmp create mode 100644 reactos/base/applications/sndrec32/but_start.bmp create mode 100644 reactos/base/applications/sndrec32/but_stop.bmp create mode 100644 reactos/base/applications/sndrec32/kkaudio.hpp create mode 100644 reactos/base/applications/sndrec32/reactOS_sndrec32.ico create mode 100644 reactos/base/applications/sndrec32/resource.h create mode 100644 reactos/base/applications/sndrec32/small.ico create mode 100644 reactos/base/applications/sndrec32/sndrec32.cpp create mode 100644 reactos/base/applications/sndrec32/sndrec32.h create mode 100644 reactos/base/applications/sndrec32/sndrec32.rbuild create mode 100644 reactos/base/applications/sndrec32/sndrec32.rc create mode 100644 reactos/base/applications/sndrec32/stdafx.h create mode 100644 reactos/base/applications/sndrec32/targetver.h diff --git a/reactos/base/applications/sndrec32/audio_def.hpp b/reactos/base/applications/sndrec32/audio_def.hpp new file mode 100644 index 00000000000..da57f3f4b64 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_def.hpp @@ -0,0 +1,34 @@ +#ifndef _AUDIO_DEF__H_ +#define _AUDIO_DEF__H_ + + +#include + +// +// Defaults +// + +#define _AUDIO_DEFAULT_FORMAT A44100_16BIT_STEREO +#define _AUDIO_DEFAULT_WAVEINBUFFERS 8 +#define _AUDIO_DEFAULT_WAVEINBUFSECS 0.1f +#define _AUDIO_DEFAULT_WAVEOUTBUFFERS 8 +#define _AUDIO_DEFAULT_WAVEOUTBUFSECS 0.1f +#define _AUDIO_DEFAULT_BUFSECS 1.0f + + +// +// Namespace stuff +// + +#define _AUDIO_NAMESPACE_START_ namespace snd { +#define _AUDIO_NAMESPACE_END_ }; +// +// Platform depend stuff +// + +#include +#include //Windows MultiMedia (WINMM) audio apis +#include //codecs stuff +#include //codecs stuff + +#endif //ifdef _AUDIO_DEF__H_ diff --git a/reactos/base/applications/sndrec32/audio_format.cpp b/reactos/base/applications/sndrec32/audio_format.cpp new file mode 100644 index 00000000000..316f54bd8ad --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_format.cpp @@ -0,0 +1,24 @@ +/* + * PROJECT: ReactOS Sound Record Application + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sndrec32/audio_format.cpp + * PURPOSE: Audio Format + * PROGRAMMERS: Marco Pagliaricci + */ + + +#include "stdafx.h" +#include "audio_format.hpp" + +_AUDIO_NAMESPACE_START_ + +// +// Standard audio formats (declared as +// externs in `audio_format.hpp') +// + +audio_format UNNKOWN_FORMAT( 0, 0, 0); +audio_format A44100_16BIT_STEREO( 44100, 16, 2 ); + +_AUDIO_NAMESPACE_END_ + diff --git a/reactos/base/applications/sndrec32/audio_format.hpp b/reactos/base/applications/sndrec32/audio_format.hpp new file mode 100644 index 00000000000..1f620b2e3f2 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_format.hpp @@ -0,0 +1,147 @@ +#ifndef _AUDIOFORMAT__H_ +#define _AUDIOFORMAT__H_ + + + +#include "audio_def.hpp" + + + + +_AUDIO_NAMESPACE_START_ + + + + + + + +class audio_format +{ + protected: + + + unsigned int samples_psec; + unsigned short int bits_psample; + unsigned short int chan; + + + public: + + + // + // Ctors + // + + audio_format( unsigned int samples_per_second, + unsigned short int bits_per_sample, unsigned short int channels ) + + : samples_psec( samples_per_second ), bits_psample( bits_per_sample ), + chan( channels ) + + { } + + + + + + + + // + // Dtor + // + + virtual ~audio_format( void ) + { } + + + + + + + + // + // Operators + // + + bool operator==( audio_format & eq ) const + { + // + // The same audio format is when samples per second, + // bit per sample, and channels mono/stereo are equal. + // + + return (( samples_psec == eq.samples_psec ) + && ( bits_psample == eq.bits_psample ) && ( chan == eq.chan )); + } + + + + + + + + + // + // Public Functions + // + + unsigned int sample_rate( void ) const + { return samples_psec; } + + + unsigned short int bits( void ) const + { return bits_psample; } + + + unsigned short int channels( void ) const + { return chan; } + + + unsigned int byte_rate( void ) const + { return ( samples_psec * chan * ( bits_psample / 8 )); } + + + unsigned int block_align( void ) const + { return ( chan * ( bits_psample / 8 )); } + + + + unsigned int samples_in_seconds( float seconds ) const + { + + return ( unsigned int ) + ((( float )samples_psec * ( float ) chan ) * seconds ); + + } + + unsigned int samples_in_bytes ( unsigned int bytes ) const + { + + return ( bytes / (( bits_psample / 8 ) * chan )); + + } + +}; + + + + +extern audio_format UNKNOWN_FORMAT; +extern audio_format A44100_16BIT_STEREO; + + + + + + + +_AUDIO_NAMESPACE_END_ + + + + + + + +#endif //ifdef _AUDIOFORMAT__H_ diff --git a/reactos/base/applications/sndrec32/audio_membuffer.cpp b/reactos/base/applications/sndrec32/audio_membuffer.cpp new file mode 100644 index 00000000000..0f6580e27d3 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_membuffer.cpp @@ -0,0 +1,501 @@ +/* + * PROJECT: ReactOS Sound Record Application + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sndrec32/audio_membuffer.cpp + * PURPOSE: Audio MemBuffer + * PROGRAMMERS: Marco Pagliaricci + */ + +#include "stdafx.h" +#include "audio_membuffer.hpp" + +_AUDIO_NAMESPACE_START_ + + +void + audio_membuffer::alloc_mem_( unsigned int bytes ) +{ + + // + // Some checking + // + + if ( bytes == 0 ) + return; + + + + + + // + // Checks previsiously alloc'd memory + // and frees it. + // + + if ( audio_data ) + delete[] audio_data; + + + + // + // Allocs new memory and zeros it. + // + + audio_data = new BYTE[ bytes ]; + + + memset( audio_data, 0, bytes * sizeof( BYTE )); + + + + // + // Sets the correct buffer size + // + + buf_size = bytes; + + + init_size = bytes; + + + +} + + +void + audio_membuffer::free_mem_( void ) +{ + + if ( audio_data ) + delete[] audio_data; + + buf_size = 0; + audio_data = 0; + +} + + +void + audio_membuffer::resize_mem_( unsigned int new_size ) +{ + + + if ( new_size == 0 ) + return; + + + // + // The new_size, cannot be <= of the + // `bytes_received' member value of the + // parent class `audio_receiver'. + // We cannot touch received audio data, + // so we have to alloc at least + // bytes_received+1 bytes. + // + // But we can truncate unused memory, so + // `new_size' can be < of `buf_size'. + // + + if ( new_size <= bytes_received ) + return; + + + + + BYTE * new_mem; + + + + // + // Allocs new memory and zeros it. + // + + + new_mem = new BYTE[ new_size ]; + + memset( new_mem, 0, new_size * sizeof( BYTE )); + + + + if ( audio_data ) + { + + + // + // Copies received audio data, and discard + // unused memory. + // + + memcpy( new_mem, audio_data, bytes_received ); + + + + // + // Frees old memory. + // + + delete[] audio_data; + + + + + + // + // Commit new memory. + // + + audio_data = new_mem; + buf_size = new_size; + + + + + } else { + + audio_data = new_mem; + buf_size = new_size; + } + + + if ( buffer_resized ) + buffer_resized( new_size ); + +} + + + + +void + audio_membuffer::truncate_( void ) +{ + + // + // If `buf_size' is already = to the + // `bytes_received' of audio data, then + // this operation is useless; simply return. + // + + if ( bytes_received == buf_size ) + return; + + + + if ( audio_data ) + { + + + // + // Allocs a new buffer. + // + + BYTE * newbuf = new BYTE[ bytes_received ]; + + + + + // + // Copies audio data. + // + + memcpy( newbuf, audio_data, bytes_received ); + + + + // + // Frees old memory. + // + + delete[] audio_data; + + + + // + // Commit the new buffer. + // + + audio_data = newbuf; + buf_size = bytes_received; + + + + // + // Buffer truncation successfull. + // Now the buffer size is exactly big + // as much audio data was received. + // + + + } + + +} + + + + + + +////////////////////////////////////// +/////// Public Functions /////////// +////////////////////////////////////// + + + + +void + audio_membuffer::clear( void ) +{ + + free_mem_(); + + bytes_received = 0; +} + + + +void + audio_membuffer::reset( void ) +{ + + + // + // Frees memory and reset + // to initial state. + // + + clear(); + + + + // + // Alloc memory of size specified + // at the constructor. + // + + alloc_mem_( init_size ); + + +} + +void + audio_membuffer::alloc_bytes( unsigned int bytes ) +{ + + alloc_mem_( bytes ); + +} + + + + +void + audio_membuffer::alloc_seconds( unsigned int secs ) +{ + + alloc_mem_( aud_info.byte_rate() * secs ); + +} + + +void + audio_membuffer::alloc_seconds( float secs ) +{ + + alloc_mem_(( unsigned int )(( float ) aud_info.byte_rate() * secs )); + +} + + + + +void + audio_membuffer::resize_bytes( unsigned int bytes ) +{ + + resize_mem_( bytes ); + +} + + + +void + audio_membuffer::resize_seconds( unsigned int secs ) +{ + + resize_mem_( aud_info.byte_rate() * secs ); + +} + + +void + audio_membuffer::resize_seconds( float secs ) +{ + + resize_mem_(( unsigned int ) + (( float )aud_info.byte_rate() * secs ) + ); + +} + + + + + + +/////////////////////////////////////// +/////// Inherited Functions ///////// +/////////////////////////////////////// + + + + + + + +void + audio_membuffer::audio_receive + ( unsigned char * data, unsigned int size ) +{ + + + // + // If there isn't a buffer, allocs memory for + // it of size*2, and copies audio data arrival. + // + + if (( audio_data == 0 ) || ( buf_size == 0 )) + { + alloc_mem_( size * 2 ); + + memcpy( audio_data, data, size ); + + return; + + } + + + + + + // + // If buffer's free memory is < of `size', + // we have to realloc buffer memory of + // buf_size*2, while free memory is enough + // to contain `size' bytes. + // + // In this case free memory is represented + // by `buf_size - bytes_recorded'. + // + + unsigned int tot_mem = buf_size, + free_mem = buf_size - bytes_received; + + + if ( free_mem < size ) + { + + // + // Calcs new buffer size. + // TODO: flags for other behaviour? + + while ( free_mem < size ) + { + tot_mem *= 2; + + free_mem = tot_mem - bytes_received; + } + + + + // + // Resize buffer memory. + // + + resize_mem_( tot_mem ); + + } + + + // + // Now we have enough free space in the + // buffer, so let's copy audio data arrivals. + // + + memcpy( audio_data + bytes_received, data, size ); + + + + + if ( audio_arrival ) + audio_arrival( aud_info.samples_in_bytes( size )); + + + +} + + +unsigned int + audio_membuffer::read( BYTE * out_buf, unsigned int bytes ) +{ + + // + // Some checking + // + + if ( !audio_data ) + return 0; + + + if ( bytes_played_ >= bytes_received ) + return 0; + + + + unsigned int to_play = + bytes_received - bytes_played_; + + + unsigned int to_copy = + bytes > to_play ? to_play : bytes; + + + // + // Copies the audio data out. + // + + if (( out_buf ) && ( to_copy ) && ( audio_data )) + memcpy( out_buf, audio_data + bytes_played_, to_copy ); + + + // + // Increments the number of total bytes + // played (audio data gone out from the + // `audio_producer' object). + // + + bytes_played_ += bytes; + + + if ( audio_arrival ) + audio_arrival( aud_info.samples_in_bytes( bytes )); + + + // + // Returns the exact size of audio data + // produced. + // + + return to_copy; +} + + +bool + audio_membuffer::finished( void ) +{ + if ( bytes_played_ < bytes_received ) + return false; + else + return true; +} + +_AUDIO_NAMESPACE_END_ diff --git a/reactos/base/applications/sndrec32/audio_membuffer.hpp b/reactos/base/applications/sndrec32/audio_membuffer.hpp new file mode 100644 index 00000000000..4dd27212c57 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_membuffer.hpp @@ -0,0 +1,338 @@ +#ifndef _AUDIOMEMBUFFER__H_ +#define _AUDIOMEMBUFFER__H_ + + + +#include "audio_def.hpp" +#include "audio_receiver.hpp" +#include "audio_format.hpp" +#include "audio_producer.hpp" + + + + +_AUDIO_NAMESPACE_START_ + + + +class audio_membuffer : public audio_receiver, public audio_producer +{ + + + + + + protected: + + BYTE * audio_data; + audio_format aud_info; + unsigned int buf_size; + unsigned int init_size; + + + + // + // Protected Functions + // + + + //allocs N bytes for the audio buffer. + void alloc_mem_( unsigned int ); + + + //frees memory + void free_mem_( void ); + + + //resizes memory, and copies old + //audio data to new-size memory + void resize_mem_( unsigned int ); + + + //truncates and discards unused memory. + //`buf_size' will be the same as `bytes_received'. + void truncate_( void ); + + + + + public: + + + void ( * audio_arrival )( unsigned int ); + void ( * buffer_resized ) ( unsigned int ); + + + // + // Ctors + // + + audio_membuffer( void ) + : audio_data( 0 ), aud_info( _AUDIO_DEFAULT_FORMAT ), + buf_size( 0 ), init_size( 0 ) + { + + // + // Allocs memory for at least 1 or some seconds + // of recording. + // + init_size = ( unsigned int ) + (( float )aud_info.byte_rate() * _AUDIO_DEFAULT_BUFSECS ); + + + alloc_mem_( init_size ); + + + } + + + + audio_membuffer( audio_format aud_fmt ) + : audio_data( 0 ), aud_info( aud_fmt ), buf_size( 0 ), + init_size( 0 ) + { + + // + // Allocs memory for at least 1 or some seconds + // of recording. + // + init_size = ( unsigned int ) + (( float )aud_info.byte_rate() * _AUDIO_DEFAULT_BUFSECS ); + + + alloc_mem_( init_size ); + + } + + + + + audio_membuffer( audio_format aud_fmt, unsigned int seconds ) + : audio_data( 0 ), aud_info( aud_fmt ), buf_size( 0 ), + init_size( 0 ) + { + + // + // Allocs memory for audio recording + // the specified number of seconds. + // + init_size = aud_info.byte_rate() * seconds; + alloc_mem_( init_size ); + + } + + + + audio_membuffer( audio_format aud_fmt, float seconds ) + : audio_data( 0 ), aud_info( aud_fmt ), buf_size( 0 ), + init_size( 0 ) + { + + // + // Allocs memory for audio recording + // the specified number of seconds. + // + init_size = ( unsigned int )(( float ) aud_info.byte_rate() * + seconds <= 0 ? 1 : seconds ); + + + alloc_mem_( init_size ); + + } + + + + + audio_membuffer( unsigned int bytes ) + : audio_data( 0 ), aud_info( _AUDIO_DEFAULT_FORMAT ), + buf_size( 0 ), init_size( 0 ) + { + + // + // Allocs memory for the specified bytes + // + init_size = bytes; + alloc_mem_( init_size ); + + } + + + + + // + // Dtor + // + + virtual ~audio_membuffer( void ) + { + + // + // Frees memory and reset values. + // + + clear(); + + } + + + + + + + + + + // + // Public functions + // + + + + //returns the audio buffer size in bytes. + unsigned int mem_size( void ) const + { return buf_size; } + + + //returns how many audio data has been + //received, in bytes. + unsigned int bytes_recorded( void ) const + { return bytes_received; } + + + //returns the integer number of seconds + //that the buffer can record + unsigned int seconds_total( void ) const + { return buf_size / aud_info.byte_rate(); } + + + //returns the integer number of seconds + //that the buffer can record + unsigned int seconds_recorded( void ) const + { return bytes_received / aud_info.byte_rate(); } + + + //returns the float number of seconds + //that the buffer can record + float fseconds_total( void ) const + { return ( float )(( float ) buf_size / + ( float ) aud_info.byte_rate()); } + + + //returns the float number of seconds + //that has been recorded + float fseconds_recorded( void ) const + { return ( float )(( float ) bytes_received / + ( float ) aud_info.byte_rate()); } + + + unsigned int total_samples( void ) const + { + + return ( aud_info.samples_in_seconds( fseconds_total() )); + + } + + + unsigned int samples_received( void ) const + { + + + return ( aud_info.samples_in_bytes( bytes_received )); + + } + + + + //returns a pointer to the audio buffer + BYTE * audio_buffer( void ) const + { return audio_data; } + + + + //frees memory and resets values. + void clear( void ); + + + audio_format & audinfo( void ) { return aud_info; } + + + //discard audio data, resets values, + //but, instead of clear() which frees memory, + //reset the memory to the initial size, ready + //for receiving "new" audio data. + void reset( void ); + + + //truncates and discards unused memory. + //`buf_size' will be the same as `bytes_received'. + void truncate( void ) + { truncate_( ); }//TODO: fare truncate N bytes + + + //if there is a buffer, discards current buffer + //memory and realloc a new memory buffer with a + //new size expressed in bytes. + void alloc_bytes( unsigned int ); + + + + //if there is a buffer, discards current buffer + //memory and realloc a new memory buffer with a + //new size expressed in seconds, integer and float. + void alloc_seconds( unsigned int ); + void alloc_seconds( float ); + + + + //resizes in bytes the current buffer, + //without discarding previsiously audio data received. + void resize_bytes( unsigned int ); + + + //resizes in seconds the current buffer, + //without discarding previsiously audio data received. + void resize_seconds( unsigned int ); + void resize_seconds( float ); + + + + + + + + + + // + // Inherited Functions from `audio_receiver' + // + + void audio_receive( unsigned char *, unsigned int ); + + + + + // + // Inherited Functions from `audio_buffer' + // + + + unsigned int read( BYTE *, unsigned int ); + bool finished( void ); + + + +}; + + + + + + + +_AUDIO_NAMESPACE_END_ + + + + + +#endif //ifdef _AUDIOMEMBUFFER__H_ diff --git a/reactos/base/applications/sndrec32/audio_producer.cpp b/reactos/base/applications/sndrec32/audio_producer.cpp new file mode 100644 index 00000000000..6afcbb4271b --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_producer.cpp @@ -0,0 +1,12 @@ +/* + * PROJECT: ReactOS Sound Record Application + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sndrec32/audio_producer.cpp + * PURPOSE: Audio Format + * PROGRAMMERS: Marco Pagliaricci + */ + + +#include "StdAfx.h" +#include "audio_producer.hpp" + diff --git a/reactos/base/applications/sndrec32/audio_producer.hpp b/reactos/base/applications/sndrec32/audio_producer.hpp new file mode 100644 index 00000000000..8fe534854ca --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_producer.hpp @@ -0,0 +1,112 @@ +#ifndef _AUDIOAUDBUF__H_ +#define _AUDIOAUDBUF__H_ + + + +#include "audio_def.hpp" + + +_AUDIO_NAMESPACE_START_ + + +class audio_producer +{ + + + protected: + + + unsigned int bytes_played_; + + + + + + public: + + + // + // Ctors + // + + audio_producer ( ) : bytes_played_( 0 ) + { } + + + + + + + + + + // + // Dtor + // + + virtual ~audio_producer( void ) + { } + + + + + // + // Public Functions + // + + + //reads N bytes from the buffer + virtual unsigned int read( BYTE *, unsigned int ) = 0; + + virtual bool finished ( void ) = 0; + + + + + unsigned int bytes_played( void ) const + { + return bytes_played_; + } + + + void set_position( unsigned int pos ) + { + bytes_played_ = pos; + } + + void set_position_start( void ) + { + bytes_played_ = 0 ; + } + + + + void forward( unsigned int bytes ) + { + bytes_played_ += bytes ; + } + + + void backward( unsigned int bytes ) + { + bytes_played_ += bytes ; + } + + void ( * play_finished )( void ); + + + + +}; + + + + +_AUDIO_NAMESPACE_END_ + + + + + + +#endif //ifdef _AUDIOAUDBUF__H_ diff --git a/reactos/base/applications/sndrec32/audio_receiver.cpp b/reactos/base/applications/sndrec32/audio_receiver.cpp new file mode 100644 index 00000000000..77b7c3f3d50 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_receiver.cpp @@ -0,0 +1,17 @@ +/* + * PROJECT: ReactOS Sound Record Application + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sndrec32/audio_producer.cpp + * PURPOSE: Audio Format + * PROGRAMMERS: Marco Pagliaricci + */ + +#include "stdafx.h" +#include "audio_receiver.hpp" + + + + +_AUDIO_NAMESPACE_START_ + +_AUDIO_NAMESPACE_END_ diff --git a/reactos/base/applications/sndrec32/audio_receiver.hpp b/reactos/base/applications/sndrec32/audio_receiver.hpp new file mode 100644 index 00000000000..6d6e693cee1 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_receiver.hpp @@ -0,0 +1,103 @@ +#ifndef _AUDIORECEIVER_DEF__H_ +#define _AUDIORECEIVER_DEF__H_ + + + +#include "audio_def.hpp" + + + + +_AUDIO_NAMESPACE_START_ + + + + +//TODO: differenziare audio_receiver da audio_sink? +//TODO: creare un audio_receiver Tee + + + + + +class audio_receiver +{ + + // + // The `audio_wavein' class, while is + // recording audio, has to access to + // protected members of `audio_receiver' + // such as `bytes_received' protected + // variable. + // + + friend class audio_wavein; + + + + + + + protected: + + + unsigned int bytes_received; + unsigned int status; + + + + public: + + + // + // Ctors + // + + audio_receiver( void ) + : bytes_received( 0 ) + { } + + + + + + // + // Dtor + // + + virtual ~audio_receiver( void ) + { } + + + + + // + // Public Functions + // + + virtual void audio_receive( unsigned char *, unsigned int ) = 0; + + //virtual void start_rec( void ) = 0; + //virtual void stop_rec( void ) = 0; + + + + void set_b_received( unsigned int r ) + { bytes_received = r; } +}; + + + + + + + +_AUDIO_NAMESPACE_END_ + + + + + + + +#endif //ifdef _AUDIORECEIVER_DEF__H_ diff --git a/reactos/base/applications/sndrec32/audio_resampler_acm.cpp b/reactos/base/applications/sndrec32/audio_resampler_acm.cpp new file mode 100644 index 00000000000..fa2617ac177 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_resampler_acm.cpp @@ -0,0 +1,387 @@ +/* + * PROJECT: ReactOS Sound Record Application + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sndrec32/audio_resampler_acm.cpp + * PURPOSE: Audio Resampler + * PROGRAMMERS: Marco Pagliaricci + */ + +#include "stdafx.h" +#include "audio_resampler_acm.hpp" + +_AUDIO_NAMESPACE_START_ + + + ///////////////////////////////////////// + /////// Private Functions //////// + ///////////////////////////////////////// + + + void + audio_resampler_acm::init_( void ) +{ + + + + // + // Zeroing structures + // + + ZeroMemory( &acm_header, sizeof( ACMSTREAMHEADER )); + ZeroMemory( &wformat_src, sizeof( WAVEFORMATEX )); + ZeroMemory( &wformat_dst, sizeof( WAVEFORMATEX )); + + + + + // + // Setting structures sizes + // + + acm_header.cbStruct = sizeof( ACMSTREAMHEADER ); + wformat_src.cbSize = sizeof( WAVEFORMATEX ); + wformat_dst.cbSize = sizeof( WAVEFORMATEX ); + + + + + // + // Setting WAVEFORMATEX structure parameters + // according to `audio_format' in/out classes + // + + wformat_src.wFormatTag = WAVE_FORMAT_PCM; + wformat_src.nSamplesPerSec = audfmt_in.sample_rate(); + wformat_src.nChannels = audfmt_in.channels(); + wformat_src.wBitsPerSample = audfmt_in.bits(); + wformat_src.nAvgBytesPerSec = audfmt_in.byte_rate(); + wformat_src.nBlockAlign = audfmt_in.block_align(); + + + wformat_dst.wFormatTag = WAVE_FORMAT_PCM; + wformat_dst.nSamplesPerSec = audfmt_out.sample_rate(); + wformat_dst.nChannels = audfmt_out.channels(); + wformat_dst.wBitsPerSample = audfmt_out.bits(); + wformat_dst.nAvgBytesPerSec = audfmt_out.byte_rate(); + wformat_dst.nBlockAlign = audfmt_out.block_align(); + + + + // + // Init acm structures completed successfull + // +} + + + + + + + + + + + +///////////////////////////////////////// +/////// Public Functions //////// +///////////////////////////////////////// + + + + +void + audio_resampler_acm::open( void ) +{ + + + MMRESULT err; + + + // + // Opens ACM stream + // + + err = acmStreamOpen( &acm_stream, 0, &wformat_src, &wformat_dst, + 0, 0, 0, ACM_STREAMOPENF_NONREALTIME ); + + + if ( err != MMSYSERR_NOERROR ) + { + //TODO: throw error + printf("acmOpen error: %i\n", err); + + } + + + + // + // Calcs source buffer lenght + // + + src_buflen = ( unsigned int ) + (( float )audfmt_in.byte_rate() * ( float )buf_secs ); + + + + + + + // + // Calcs destination source buffer lenght + // with help of ACM apis + // + + err = acmStreamSize( acm_stream, + src_buflen, &dst_buflen, ACM_STREAMSIZEF_SOURCE ); + + + if ( err != MMSYSERR_NOERROR ) + { + //TODO: throw error + printf("acmSize error\n"); + + } + + + + // + // Initialize ACMSTREAMHEADER structure, + // and alloc memory for source and destination + // buffers. + // + + acm_header.fdwStatus = 0; + acm_header.dwUser = 0; + + + acm_header.pbSrc = ( LPBYTE ) new BYTE [ src_buflen ]; + acm_header.cbSrcLength = src_buflen; + acm_header.cbSrcLengthUsed = 0; + acm_header.dwSrcUser = src_buflen; + + + acm_header.pbDst = ( LPBYTE ) new BYTE [ dst_buflen ]; + acm_header.cbDstLength = dst_buflen; + acm_header.cbDstLengthUsed = 0; + acm_header.dwDstUser = dst_buflen; + + + + + // + // Give ACMSTREAMHEADER initialized correctly to the + // driver. + // + + err = acmStreamPrepareHeader( acm_stream, &acm_header, 0L ); + + if ( err != MMSYSERR_NOERROR ) + { + //TODO: throw error + printf("prep. header error\n"); + } + + + + + // + // ACM stream successfully opened. + // + + stream_opened = true; + +} + + + + +void + audio_resampler_acm::close( void ) +{ + + + MMRESULT err; + + + if ( acm_stream ) + { + + if ( acm_header.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED ) + { + + acm_header.cbSrcLength = src_buflen; + acm_header.cbDstLength = dst_buflen; + + err = acmStreamUnprepareHeader( acm_stream, &acm_header, 0L ); + + + if ( err != MMSYSERR_NOERROR ) + { + + // + // Free buffer memory + // + + if ( acm_header.pbSrc != 0 ) + delete[] acm_header.pbSrc; + + if ( acm_header.pbDst != 0 ) + delete[] acm_header.pbDst; + + + // + // Re-init structures + // + + init_(); + + // + // Updating status + // + + stream_opened = false; + + + //TODO: throw error + + } + } + + + err = acmStreamClose( acm_stream, 0 ); + acm_stream = 0; + + if ( err != MMSYSERR_NOERROR ) + { + + // + // Free buffer memory + // + + if ( acm_header.pbSrc != 0 ) + delete[] acm_header.pbSrc; + + if ( acm_header.pbDst != 0 ) + delete[] acm_header.pbDst; + + + // + // Re-init structures + // + + init_(); + + + // + // Updating status + // + + stream_opened = false; + + + //TODO: throw error! + + } + + + }//if acm_stream != 0 + + + + + + + // + // Free buffer memory + // + + if ( acm_header.pbSrc != 0 ) + delete[] acm_header.pbSrc; + + if ( acm_header.pbDst != 0 ) + delete[] acm_header.pbDst; + + + // + // Re-init structures + // + + init_(); + + + // + // Updating status + // + + stream_opened = false; + + + + // + // ACM sream successfully closed. + // + + +} + + + + +void + audio_resampler_acm::audio_receive( unsigned char * data, unsigned int size ) +{ + + MMRESULT err; + + // + // Checking for acm stream opened + // + + if ( stream_opened ) + { + + + // + // Copy audio data from extern to + // internal source buffer + // + + memcpy( acm_header.pbSrc, data, size ); + + + acm_header.cbSrcLength = size; + acm_header.cbDstLengthUsed = 0; + + err = acmStreamConvert( acm_stream, &acm_header, ACM_STREAMCONVERTF_BLOCKALIGN ); + + if ( err != MMSYSERR_NOERROR ) + { + //TODO: throw error + printf("acm convert error\n"); + + } + + + // + // Wait for sound conversion + // + + while(( ACMSTREAMHEADER_STATUSF_DONE & acm_header.fdwStatus ) == 0 ); + + + printf("Processed successfully %lu bytes of audio.\n", acm_header.cbDstLengthUsed ); + + + + // + // Copy resampled audio, to destination buffer. + // + + //memcpy( pbOutputData, acm_header.pbDst, acm_header.cbDstLengthUsed ); + + + } + +} + +_AUDIO_NAMESPACE_END_ diff --git a/reactos/base/applications/sndrec32/audio_resampler_acm.hpp b/reactos/base/applications/sndrec32/audio_resampler_acm.hpp new file mode 100644 index 00000000000..bce7b32ae9e --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_resampler_acm.hpp @@ -0,0 +1,99 @@ +#ifndef _AUDIORESAMPLERACM__H_ +#define _AUDIORESAMPLERACM__H_ + + + +#include "audio_def.hpp" +#include "audio_receiver.hpp" +#include "audio_format.hpp" + + + + +_AUDIO_NAMESPACE_START_ + + + +//TODO: inherit from a base resampler? +class audio_resampler_acm : public audio_receiver +{ + + private: + void init_( void ); + + + protected: + + + HACMSTREAM acm_stream; + ACMSTREAMHEADER acm_header; + DWORD src_buflen; + DWORD dst_buflen; + bool stream_opened; + + audio_format audfmt_in; + audio_format audfmt_out; + + float buf_secs; + + WAVEFORMATEX wformat_src; + WAVEFORMATEX wformat_dst; + + + + + public: + + + // + // Ctors + // + + audio_resampler_acm( audio_format fmt_in, audio_format fmt_out ) + : acm_stream( 0 ), src_buflen( 0 ), dst_buflen( 0 ), + stream_opened( false ), audfmt_in( fmt_in ), audfmt_out( fmt_out ), + buf_secs( _AUDIO_DEFAULT_BUFSECS ) + + { + + + init_(); + + + } + + + + + + // + // Dtor + // + + ~audio_resampler_acm( void ) + { } + + + + // + // Public functions + // + + void open( void ); + void close( void ); + + + + void audio_receive( unsigned char *, unsigned int ); + + + +}; + + +_AUDIO_NAMESPACE_END_ + + + + +#endif //ifdef _AUDIORESAMPLERACM_H_ diff --git a/reactos/base/applications/sndrec32/audio_wavein.cpp b/reactos/base/applications/sndrec32/audio_wavein.cpp new file mode 100644 index 00000000000..4d92f24e4e1 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_wavein.cpp @@ -0,0 +1,880 @@ +/* +* PROJECT: ReactOS Sound Record Application +* LICENSE: GPL - See COPYING in the top level directory +* FILE: base/applications/sndrec32/audio_wavein.cpp +* PURPOSE: Audio WaveIn +* PROGRAMMERS: Marco Pagliaricci +*/ + +#include "stdafx.h" +#include "audio_wavein.hpp" + + + +_AUDIO_NAMESPACE_START_ + + + void + audio_wavein::init_( void ) +{ + ZeroMemory(( LPVOID ) &wave_format, + sizeof( WAVEFORMATEX )); + + wave_format.cbSize = sizeof( WAVEFORMATEX ); + + wavein_handle = 0; + recthread_id = 0; + wakeup_recthread = 0; + + buf_secs = _AUDIO_DEFAULT_WAVEINBUFSECS; + + + status = WAVEIN_NOTREADY; +} + + +void + audio_wavein::alloc_buffers_mem_( unsigned int buffs, float secs ) +{ + + + unsigned int + onebuf_size = 0, tot_size = 0; + + + // + // Release old memory + // + + if ( main_buffer ) + delete[] main_buffer; + + + if ( wave_headers ) + delete[] wave_headers; + + + + // + // Calcs size of the buffers + // + + onebuf_size = ( unsigned int ) + (( float )aud_info.byte_rate() * secs ); + + + tot_size = onebuf_size * buffs; + + + + + // + // Allocs memory for the audio buffers + // + + main_buffer = new BYTE [ tot_size ]; + + + + // + // Allocs memory for the `WAVEHDR' structures. + // + + wave_headers = ( WAVEHDR * ) + new BYTE [ sizeof( WAVEHDR ) * buffs ]; + + + + // + // Zeros memory. + // + + ZeroMemory( main_buffer, tot_size ); + + ZeroMemory( wave_headers, + sizeof( WAVEHDR ) * buffs ); + + + // + // Updates total size of the buffers. + // + + mb_size = tot_size; + +} + + +void + audio_wavein::free_buffers_mem_( void ) +{ + + + // + // Frees memory + // + + if ( main_buffer ) + delete[] main_buffer; + + + if ( wave_headers ) + delete[] wave_headers; + + + main_buffer = 0; + wave_headers = 0; + +} + + +void + audio_wavein::init_headers_( void ) +{ + + + + // + // If there is no memory for memory or + // headers, simply return. + // + + if (( !wave_headers ) || ( !main_buffer )) + return; + + + // + // This is the size for one buffer + // + + DWORD buf_sz = mb_size / buffers; + + + + // + // This is the base address for one buffer + // + + BYTE * buf_addr = main_buffer; + + + // + // Initializes headers. + // + + for ( unsigned int i = 0; i < buffers; ++i ) + { + wave_headers[ i ].dwBufferLength = mb_size / buffers; + wave_headers[ i ].lpData = ( LPSTR ) buf_addr; + + buf_addr += buf_sz; + } + +} + + +void + audio_wavein::prep_headers_( void ) +{ + MMRESULT err; + bool error = false; + + + // + // If there is no memory for memory or + // headers, throw error. + // + + if (( !wave_headers ) + || ( !main_buffer ) || ( !wavein_handle )) + {} //TODO: throw error! + + + + for ( unsigned int i = 0; i < buffers; ++i ) + { + err = waveInPrepareHeader( wavein_handle, + &wave_headers[ i ], sizeof( WAVEHDR )); + + + if ( err != MMSYSERR_NOERROR ) + error = true; + + } + + + if ( error ) + MessageBox( 0, TEXT("waveInPrepareHeader Error."), 0, 0 ); + + + +} + +void + audio_wavein::unprep_headers_( void ) +{ + MMRESULT err; + bool error = false; + + + + // + // If there is no memory for memory or + // headers, throw error. + // + + if (( !wave_headers ) + || ( !main_buffer ) || ( !wavein_handle )) + {} //TODO: throw error! + + + + for ( unsigned int i = 0; i < buffers; ++i ) + { + err = waveInUnprepareHeader( wavein_handle, + &wave_headers[ i ], sizeof( WAVEHDR )); + + + if ( err != MMSYSERR_NOERROR ) + error = true; + + } + + + if ( error ) + MessageBox( 0, TEXT("waveInUnPrepareHeader Error."), 0, 0 ); + +} + + +void + audio_wavein::add_buffers_to_driver_( void ) +{ + MMRESULT err; + bool error = false; + + + + // + // If there is no memory for memory or + // headers, throw error. + // + + if (( !wave_headers ) + || ( !main_buffer ) || ( !wavein_handle )) + {} //TODO: throw error! + + + + + for ( unsigned int i = 0; i < buffers; ++i ) + { + err = waveInAddBuffer( wavein_handle, + &wave_headers[ i ], sizeof( WAVEHDR )); + + + if ( err != MMSYSERR_NOERROR ) + error = true; + + } + + + if ( error ) + MessageBox( 0, TEXT("waveInAddBuffer Error."), 0, 0 ); + +} + + + +void + audio_wavein::close( void ) +{ + + + + + // + // If wavein object is already in the status + // NOTREADY, nothing to do. + // + + if ( status == WAVEIN_NOTREADY ) + return; + + + + // + // If the wavein is recording, + // then stop recording and close it. + // + + if ( status == WAVEIN_RECORDING ) + stop_recording(); + + + // + // Updating status. + // + + status = WAVEIN_NOTREADY; + + + + + // + // Wakeing up recording thread, so it + // can receive the `MM_WIM_CLOSE' message + // then dies. + // + if ( wakeup_recthread ) + SetEvent( wakeup_recthread ); + + + + // + // Closing wavein stream + // + + while (( waveInClose( wavein_handle )) + != MMSYSERR_NOERROR ) Sleep( 1 ); + + + + // + // Release buffers memory. + // + + free_buffers_mem_(); + + + // + // Re-initialize variables to the + // initial state. + // + + init_(); + +} + + +void + audio_wavein::open( void ) +{ + + MMRESULT err; + HANDLE recthread_handle = 0; + + + // + // Checkin the status of the object + // + + if ( status != WAVEIN_NOTREADY ) + {} //TODO: throw error + + + + // + // Creating the EVENT object that will be signaled + // when the recording thread has to wake up. + // + + wakeup_recthread = + CreateEvent( 0, FALSE, FALSE, 0 ); + + + data_flushed_event = + CreateEvent( 0, FALSE, FALSE, 0 ); + + + + if (( !wakeup_recthread ) || ( !data_flushed_event )) + { + + + status = WAVEIN_ERR; + + MessageBox( 0, TEXT("Thread Error."), 0, 0 ); + + //TODO: throw error + } + + + + // + // Inialize buffers for recording audio + // data from the wavein audio line. + // + + alloc_buffers_mem_( buffers, buf_secs ); + init_headers_(); + + + + + + + // + // Sound format that will be captured by wavein + // + + wave_format.wFormatTag = WAVE_FORMAT_PCM; + + wave_format.nChannels = aud_info.channels(); + wave_format.nSamplesPerSec = aud_info.sample_rate(); + wave_format.wBitsPerSample = aud_info.bits(); + wave_format.nBlockAlign = aud_info.block_align(); + wave_format.nAvgBytesPerSec = aud_info.byte_rate(); + + + + // + // Creating the recording thread + // + + recthread_handle = + CreateThread( NULL, + 0, + audio_wavein::recording_procedure, + ( PVOID ) this, + 0, + &recthread_id + ); + + + + // + // Checking thread handle + // + + if ( !recthread_handle ) + { + + // + // Updating status + // + + status = WAVEIN_ERR; + + MessageBox( 0, TEXT("Thread Error."), 0, 0 ); + //TODO: throw error + + } + + + // + // We don't need the thread handle anymore, + // so we can close it from now. (We'll just + // need the thread ID for the `waveInOpen' API) + // + + CloseHandle( recthread_handle ); + + + + // + // Opening audio line wavein + // + + err = waveInOpen( &wavein_handle, + 0, + &wave_format, + recthread_id, + 0, + CALLBACK_THREAD + ); + + + if ( err != MMSYSERR_NOERROR ) + { + + + // + // Updating status + // + + status = WAVEIN_ERR; + + if ( err == WAVERR_BADFORMAT ) + MessageBox( 0, TEXT("waveInOpen Error"), 0, 0 ); + + + //TODO: throw error + } + + + // + // Update object status + // + + status = WAVEIN_READY; + + + + // + // Now `audio_wavein' object is ready + // for audio recording! + // +} + + + +void + audio_wavein::start_recording( void ) +{ + + MMRESULT err; + BOOL ev; + + + + if (( status != WAVEIN_READY ) + && ( status != WAVEIN_STOP )) + {} //TODO: throw error + + + + + // + // Updating to the recording status + // + + status = WAVEIN_RECORDING; + + + + + // + // Let's prepare header of type WAVEHDR that + // we will pass to the driver with our + // audio informations, and buffer informations. + // + + prep_headers_(); + + + + // + // The waveInAddBuffer function sends an input buffer + // to the given waveform-audio input device. + // When the buffer is filled, the application is notified. + // + + add_buffers_to_driver_(); + + + + + + // + // Signaling event for waking up + // the recorder thread. + // + + ev = SetEvent( wakeup_recthread ); + + + if ( !ev ) + { + + + MessageBox( 0, TEXT("Event Error."), 0, 0 ); + + } + + + // + // Start recording + // + + + err = waveInStart( wavein_handle ); + + + if ( err != MMSYSERR_NOERROR ) + { + + // + // Updating status + // + + status = WAVEIN_ERR; + + MessageBox( 0, TEXT("waveInStart Error."), 0, 0 ); + + + //TODO: throw error + + } + +} + + + +void + audio_wavein::stop_recording( void ) +{ + + + MMRESULT err; + DWORD wait; + + + if ( status != WAVEIN_RECORDING ) + return; + + + + status = WAVEIN_FLUSHING; + + + if ( data_flushed_event ) + wait = WaitForSingleObject( + data_flushed_event, INFINITE + ); + + + + // + // waveInReset will make all pending buffer as done. + // + + err = waveInReset( wavein_handle ); + + + if ( err != MMSYSERR_NOERROR ) + { + + //TODO: throw error + + MessageBox( 0, TEXT("waveInReset Error."), 0, 0 ); + + + + } + + + + // + // Stop recording. + // + + err = waveInStop( wavein_handle ); + + + if ( err != MMSYSERR_NOERROR ) + { + + //TODO: throw error + + MessageBox( 0, TEXT("waveInStop Error."), 0, 0 ); + + + + } + + + // + // The waveInUnprepareHeader function cleans up the + // preparation performed by the waveInPrepareHeader function. + // + + unprep_headers_(); + + + + + + + + + + + + status = WAVEIN_STOP; + +} + + + +DWORD WINAPI + audio_wavein::recording_procedure( LPVOID arg ) +{ + + + MSG msg; + WAVEHDR * phdr; + DWORD wait; + audio_wavein * _this = ( audio_wavein * ) arg; + + + + + // + // Check the arg pointer + // + + if ( _this == 0 ) + return 0; + + + + // + // The thread can go to sleep for now. + // It will be wake up only when there is audio data + // to be recorded. + // + + if ( _this->wakeup_recthread ) + wait = WaitForSingleObject( + _this->wakeup_recthread, INFINITE + ); + + + + + + + // + // If status of the `audio_wavein' object + // is not ready or recording the thread can exit. + // + + if (( _this->status != WAVEIN_READY ) && + ( _this->status != WAVEIN_RECORDING )) + return 0; + + + + + + + + // + // Entering main polling loop + // + + while ( GetMessage( &msg, 0, 0, 0 )) + { + + switch ( msg.message ) + { + + case MM_WIM_DATA: + + phdr = ( WAVEHDR * ) msg.lParam; + + if (( _this->status == WAVEIN_RECORDING ) + || ( _this->status == WAVEIN_FLUSHING )) + { + + // + // Flushes recorded audio data to + // the `audio_receiver' object. + // + + _this->audio_rcvd.audio_receive( + ( unsigned char * )phdr->lpData, + phdr->dwBytesRecorded + ); + + + // + // Updating `audio_receiver' total + // bytes received _AFTER_ calling + // `audio_receive' function. + // + + _this->audio_rcvd.bytes_received += + phdr->dwBytesRecorded; + + + + + // + // If status is not flushing data, then + // we can re-add the buffer for reusing it. + // Otherwise, if we are flushing pending data, + // we cannot re-add buffer because we don't need + // it anymore + // + + if ( _this->status != WAVEIN_FLUSHING ) + { + + // + // Let the audio driver reuse the buffer + // + + waveInAddBuffer( _this->wavein_handle, + phdr, sizeof( WAVEHDR )); + + + } else { + + // + // If we are flushing pending data, we have + // to prepare to stop recording. + // Set WAVEHDR flag to 0, and fires the event + // `data_flushed_event', that will wake up + // the main thread that is sleeping into + // wavein_in::stop_recording() member function, + // waiting the last `MM_WIM_DATA' message that + // contain pending data. + // + + + + + phdr->dwFlags = 0; + + SetEvent( _this->data_flushed_event ); + + + // + // The recording is gooing to stop, so the + // recording thread can go to sleep! + // + + wait = WaitForSingleObject( + _this->wakeup_recthread, INFINITE ); + + } + + + }//if WAVEIN_RECORDING || WAVEIN_FLUSHING + + break; + + + + + + + + + + case MM_WIM_CLOSE: + + // + // The thread can exit now. + // + + return 0; + + break; + + + + } //end switch( msg.message ) + + } //end while( GetMessage( ... )) + + return 0; +} + + + + + + +_AUDIO_NAMESPACE_END_ diff --git a/reactos/base/applications/sndrec32/audio_wavein.hpp b/reactos/base/applications/sndrec32/audio_wavein.hpp new file mode 100644 index 00000000000..3c73077729e --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_wavein.hpp @@ -0,0 +1,271 @@ +#ifndef _AUDIOWAVEIN_H_ +#define _AUDIOWAVEIN_H_ + + + +#include "audio_def.hpp" +#include "audio_format.hpp" +#include "audio_receiver.hpp" + + + +_AUDIO_NAMESPACE_START_ + + + + +enum audio_wavein_status { WAVEIN_NOTREADY, WAVEIN_READY, + WAVEIN_RECORDING, WAVEIN_ERR, + WAVEIN_STOP, WAVEIN_FLUSHING + + }; + + + + + +class audio_wavein +{ + private: + + + + // + // The new recording thread sends message to this procedure + // about open recording, close, and sound data recorded + // + + static DWORD WINAPI recording_procedure( LPVOID ); + + // + // When this event is signaled, then the previsiously created + // recording thread will wake up and start recording audio + // and will pass audio data to an `audio_receiver' object. + // + + HANDLE wakeup_recthread; + HANDLE data_flushed_event; + + + + + protected: + + +//TODO: puts these structs in private?! + + + + + // + // Audio wavein device stuff + // + + WAVEFORMATEX wave_format; + WAVEHDR * wave_headers; + HWAVEIN wavein_handle; + + + + + + audio_format aud_info; + + audio_receiver & audio_rcvd; + + + + // + // Audio Recorder Thread id + // + + DWORD recthread_id; + + + + + // + // Object status + // + + audio_wavein_status status; + + + + + + + + // + // How many seconds of audio + // can record the internal buffer + // before flushing audio data + // to the `audio_receiver' class? + // + + float buf_secs; + + + // + // The temporary buffers for the audio + // data incoming from the wavein device + // and its size, and its total number. + // + + BYTE * main_buffer; + unsigned int mb_size; + + unsigned int buffers; + + + + + + // + // Protected Functions + // + + + //initialize all structures and variables. + void init_( void ); + + void alloc_buffers_mem_( unsigned int, float ); + void free_buffers_mem_( void ); + + void init_headers_( void ); + void prep_headers_( void ); + void unprep_headers_( void ); + void add_buffers_to_driver_( void ); + + + + + + + + public: + + + // + // Ctors + // + + audio_wavein( + const audio_format & a_info, audio_receiver & a_receiver ) + + : wave_headers( 0 ), + aud_info( a_info ), audio_rcvd( a_receiver ), + status( WAVEIN_NOTREADY ), main_buffer( 0 ), mb_size( 0 ), + buffers( _AUDIO_DEFAULT_WAVEINBUFFERS ) + { + + // + // Initializing internal wavein data + // + + + init_(); + + aud_info = a_info; + } + + + + + + + + // + // Dtor + // + + ~audio_wavein( void ) + { + + //close(); TODO! + + } + + + + // + // Public functions + // + + void open( void ); + void close ( void ); + + + void start_recording( void ); + void stop_recording( void ); + + + + audio_wavein_status current_status ( void ) const + { + return status; + } + + float buffer_secs( void ) const + { return buf_secs; } + + + void buffer_secs( float bsecs ) + { + // + // Some checking + // + + if ( bsecs <= 0 ) + return; + + + // + // Set seconds lenght for each + // buffer. + // + + buf_secs = bsecs; + } + + + unsigned int total_buffers( void ) const + { return buffers; } + + + + void total_buffers( unsigned int tot_bufs ) + { + + // + // Some checking + // + + if ( tot_bufs == 0 ) + return; + + + // + // Sets the number of total buffers. + // + + buffers = tot_bufs; + } + + + audio_format format( void ) const + { return aud_info; } + + + +}; + + + + +_AUDIO_NAMESPACE_END_ + + + + +#endif //ifdef _AUDIOWAVEIN_H_ diff --git a/reactos/base/applications/sndrec32/audio_waveout.cpp b/reactos/base/applications/sndrec32/audio_waveout.cpp new file mode 100644 index 00000000000..18405b3d0b3 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_waveout.cpp @@ -0,0 +1,889 @@ +/* + * PROJECT: ReactOS Sound Record Application + * LICENSE: GPL - See COPYING in the top level directory + * FILE: base/applications/sndrec32/audio_waveout.cpp + * PURPOSE: Audio WaveOut + * PROGRAMMERS: Marco Pagliaricci + */ + + +#include "stdafx.h" +#include "audio_waveout.hpp" + + +_AUDIO_NAMESPACE_START_ + + + +void +audio_waveout::init_( void ) +{ + + ZeroMemory(( LPVOID ) &wave_format, + sizeof( WAVEFORMATEX )); + + wave_format.cbSize = sizeof( WAVEFORMATEX ); + + waveout_handle = 0; + + playthread_id = 0; + wakeup_playthread = 0; + + buf_secs = _AUDIO_DEFAULT_WAVEOUTBUFSECS; + + + status = WAVEOUT_NOTREADY; + +} + + + + +void +audio_waveout::alloc_buffers_mem_( unsigned int buffs, float secs ) +{ + + + unsigned int + onebuf_size = 0, tot_size = 0; + + + // + // Release old memory + // + + if ( main_buffer ) + delete[] main_buffer; + + + if ( wave_headers ) + delete[] wave_headers; + + + + // + // Calcs size of the buffers + // + + onebuf_size = ( unsigned int ) + (( float )aud_info.byte_rate() * secs ); + + + tot_size = onebuf_size * buffs; + + + + + // + // Allocs memory for the audio buffers + // + + main_buffer = new BYTE [ tot_size ]; + + + + // + // Allocs memory for the `WAVEHDR' structures. + // + + wave_headers = ( WAVEHDR * ) + new BYTE [ sizeof( WAVEHDR ) * buffs ]; + + + + // + // Zeros memory. + // + + ZeroMemory( main_buffer, tot_size ); + + ZeroMemory( wave_headers, + sizeof( WAVEHDR ) * buffs ); + + + // + // Updates total size of the buffers. + // + + mb_size = tot_size; +} + + +void +audio_waveout::init_headers_( void ) +{ + + + + // + // If there is no memory for memory or + // headers, simply return. + // + + if (( !wave_headers ) || ( !main_buffer )) + return; + + + // + // This is the size for one buffer + // + + DWORD buf_sz = mb_size / buffers; + + + + // + // This is the base address for one buffer + // + + BYTE * buf_addr = main_buffer; + + + + ZeroMemory( wave_headers, sizeof( WAVEHDR ) * buffers ); + + + // + // Initializes headers. + // + + for ( unsigned int i = 0; i < buffers; ++i ) + { + + // + // Sets the correct base address and + // lenght for the little buffer. + // + + wave_headers[ i ].dwBufferLength = mb_size / buffers; + wave_headers[ i ].lpData = ( LPSTR ) buf_addr; + + // + // Unsets the WHDR_DONE flag. + // + + wave_headers[ i ].dwFlags &= ~WHDR_DONE; + + + + // + // Sets the WAVEHDR user data with an + // unique little buffer ID# + // + + wave_headers[ i ].dwUser = ( unsigned int ) i; + + + + // + // Increments little buffer base address. + // + + buf_addr += buf_sz; + } + +} + + +void +audio_waveout::prep_headers_( void ) +{ + MMRESULT err; + bool error = false; + + + // + // If there is no memory for memory or + // headers, throw error. + // + + if (( !wave_headers ) + || ( !main_buffer ) || ( !waveout_handle )) + {} //TODO: throw error! + + + + for ( unsigned int i = 0; i < buffers; ++i ) + { + err = waveOutPrepareHeader( waveout_handle, + &wave_headers[ i ], sizeof( WAVEHDR )); + + + if ( err != MMSYSERR_NOERROR ) + error = true; + + } + + + if ( error ) + {} //TODO: throw error indicating which + //header i-th is errorneous + + + +} + +void +audio_waveout::unprep_headers_( void ) +{ + MMRESULT err; + bool error = false; + + + + // + // If there is no memory for memory or + // headers, throw error. + // + + if (( !wave_headers ) + || ( !main_buffer ) || ( !waveout_handle )) + {} //TODO: throw error! + + + + for ( unsigned int i = 0; i < buffers; ++i ) + { + err = waveOutUnprepareHeader( waveout_handle, + &wave_headers[ i ], sizeof( WAVEHDR )); + + + if ( err != MMSYSERR_NOERROR ) + error = true; + + } + + + if ( error ) + {} //TODO: throw error indicating which + //header i-th is errorneous + +} + + + + + + + + + +void +audio_waveout::free_buffers_mem_( void ) +{ + + + + // + // Frees memory + // + + if ( main_buffer ) + delete[] main_buffer; + + + if ( wave_headers ) + delete[] wave_headers; + + + main_buffer = 0; + wave_headers = 0; + + + + +} + + + + + + + + + + + + + + +void +audio_waveout::open( void ) +{ + + MMRESULT err; + HANDLE playthread_handle = 0; + + + // + // Checkin the status of the object + // + + if ( status != WAVEOUT_NOTREADY ) + {} //TODO: throw error + + + // + // Creating the EVENT object that will be signaled + // when the playing thread has to wake up. + // + + wakeup_playthread = + CreateEvent( 0, FALSE, FALSE, 0 ); + + if ( !wakeup_playthread ) + { + + + status = WAVEOUT_ERR; + + //TODO: throw error + } + + + + // + // Inialize buffers for recording audio + // data from the wavein audio line. + // + + alloc_buffers_mem_( buffers, buf_secs ); + init_headers_(); + + + + + + + // + // Sound format that will be captured by wavein + // + + wave_format.wFormatTag = WAVE_FORMAT_PCM; + + wave_format.nChannels = aud_info.channels(); + wave_format.nSamplesPerSec = aud_info.sample_rate(); + wave_format.wBitsPerSample = aud_info.bits(); + wave_format.nBlockAlign = aud_info.block_align(); + wave_format.nAvgBytesPerSec = aud_info.byte_rate(); + + + + // + // Creating the recording thread + // + + playthread_handle = + CreateThread( NULL, + 0, + audio_waveout::playing_procedure, + ( PVOID ) this, + 0, + &playthread_id + ); + + + + // + // Checking thread handle + // + + if ( !playthread_handle ) + { + + // + // Updating status + // + + status = WAVEOUT_ERR; + //TODO: throw error + + } + + + // + // We don't need the thread handle anymore, + // so we can close it from now. (We'll just + // need the thread ID for the `waveInOpen' API) + // + + CloseHandle( playthread_handle ); + + + + // + // Reset the `audio_source' to the start + // position. + // + + audio_buf.set_position_start(); + + + + + // + // Opens the WAVE_OUT device. + // + + err = waveOutOpen( + &waveout_handle, + WAVE_MAPPER, + &wave_format, + playthread_id, + 0, + CALLBACK_THREAD | WAVE_ALLOWSYNC + ); + + + + if ( err != MMSYSERR_NOERROR ) + { + MessageBox(0, _T("waveOutOpen Error"), 0, 0); + //TODO: throw error + + } + + + + + status = WAVEOUT_READY; + + +} + + + +void +audio_waveout::play( void ) +{ + + + MMRESULT err; + unsigned int i; + BOOL ev; + + + if ( !main_buffer ) + { return; } //TODO; throw error, or assert + + + + + // + // If the status is PAUSED, we have to + // resume the audio playing. + // + if ( status == WAVEOUT_PAUSED ) + { + + // + // Updates status. + // + + status = WAVEOUT_PLAYING; + + + // + // Tells to the driver to resume + // audio playing. + // + + waveOutRestart( waveout_handle ); + + + // + // Wakeup playing thread. + // + + ev = SetEvent( wakeup_playthread ); + + return; + + } //if status == WAVEOUT_PAUSED + + + + + + if ( status != WAVEOUT_READY ) + return; + + + + + // + // Prepares WAVEHDR structures. + // + + prep_headers_(); + + + + // + // Sets correct status. + // + + status = WAVEOUT_PLAYING; + + + + // + // Reads the audio from the start. + // + + audio_buf.set_position_start(); + + + + + // + // Reads the first N bytes from the audio + // buffer, where N = the total size of all + // little buffers. + // + + audio_buf.read( main_buffer, mb_size ); + + + + + + + // + // Wakeup the playing thread. + // + + ev = SetEvent( wakeup_playthread ); + + + + + // + // Sends all the little buffers to the + // audio driver, so it can play the sound + // data. + // + + for ( i = 0; i < buffers; ++ i ) + { + + + err = waveOutWrite( waveout_handle, &wave_headers[ i ], sizeof( WAVEHDR )); + + if ( err != MMSYSERR_NOERROR ) + { + + + MessageBox(0, _T("waveOutWrite Error"), 0, 0); + + //TODO: throw error + } + + } + +} + + +void +audio_waveout::pause( void ) +{ + + MMRESULT err; + + + // + // If the waveout object is not playing audio, + // do nothing. + // + + if ( status == WAVEOUT_PLAYING ) + { + + // + // Updating status. + // + + status = WAVEOUT_PAUSED; + + + // + // Tells to audio driver to pause audio. + // + + err = waveOutPause( waveout_handle ); + + + if ( err != MMSYSERR_NOERROR ) + { + + MessageBox(0, _T("waveOutPause Error"), 0, 0); + //TODO: throw error + + } + + } + +} + + +void +audio_waveout::stop( void ) +{ + + MMRESULT err; + + + status = WAVEOUT_STOP; + + + err = waveOutReset( waveout_handle ); + + + + if ( err != MMSYSERR_NOERROR ) + { + + MessageBox(0, _T("err waveout reset.\n"),_T("ERROR"), 0); + //TODO: throw error + + } + + + + // + // Sets the start position of the audio + // buffer. + // + + audio_buf.set_position_start(); + + + unprep_headers_(); + + + init_headers_(); + + + status = WAVEOUT_READY; + +} + +void +audio_waveout::close( void ) +{ + + MMRESULT err; + + + // + // If the `wave_out' object is playing audio, + // or it is in paused state, we have to call + // the `stop' member function, to flush + // pending buffers. + // + + if (( status == WAVEOUT_PLAYING ) + || ( status== WAVEOUT_PAUSED )) + { + + stop(); + + } + + + + // + // When we have flushed all pending buffers, + // the wave out handle can be successfully closed. + // + + err = waveOutClose( waveout_handle ); + + + if ( err != MMSYSERR_NOERROR ) + { + + MessageBox(0, _T("waveOutClose Error"), 0, 0); + //TODO: throw error + + } + + free_buffers_mem_(); + +} + + +DWORD WINAPI +audio_waveout::playing_procedure( LPVOID arg ) +{ + MSG msg; + WAVEHDR * phdr; + DWORD wait; + MMRESULT err; + audio_waveout * _this = ( audio_waveout * ) arg; + unsigned int read_size; + + + + // + // Check the arg pointer + // + + if ( _this == 0 ) + return 0; + + + + // + // The thread can go to sleep for now. + // It will be wake up only when there is audio data + // to be recorded. + // + + if ( _this->wakeup_playthread ) + wait = WaitForSingleObject( + _this->wakeup_playthread, INFINITE + ); + + + + // + // Entering main polling loop + // + + while ( GetMessage( &msg, 0, 0, 0 )) + { + + switch ( msg.message ) + { + + case MM_WOM_DONE: + + phdr = ( WAVEHDR * ) msg.lParam; + + + // + // If the status of the `wave_out' object + // is different than playing, then the thread + // can go to sleep. + // + + if (( _this->status != WAVEOUT_PLAYING ) + && ( _this->wakeup_playthread )) + { + + wait = WaitForSingleObject( + _this->wakeup_playthread, + INFINITE + ); + } + + //TODO: quando il thread si risveglia, deve + //entrare nel prossimo if o no? o metter un else { ? + + + + if ( phdr->dwFlags & WHDR_DONE ) + { + + read_size = + _this->audio_buf.read( + ( BYTE * ) phdr->lpData, + phdr->dwBufferLength + ); + + + if ( read_size ) + { + phdr->dwBufferLength = read_size; + + phdr->dwFlags &= ~WHDR_DONE; + + err = waveOutWrite( + _this->waveout_handle, + phdr, + sizeof( WAVEHDR ) + ); + + if ( err != MMSYSERR_NOERROR ) + { + MessageBox(0, _T("waveOutWrite Error"), 0, 0); + //TODO: throw error + } + + + } else { + + // + // Here `read_sizep' is 0 + // + + if ( phdr->dwUser == ( _this->buffers - 1 )) + { + + // + // Here `read_size' and the buffer user + // data, that contain a buffer ID#, + // is equal to the number of the total + // buffers - 1. This means that this is the + // _LAST_ little buffer that has been played + // by the audio driver. We can STOP the + // `wave_out' object now, or restart the + // sound playing, if we have a infinite loop. + // + + + _this->stop(); + + // + // Let the thread go to sleep. + // + + if ( _this->audio_buf.play_finished ) + _this->audio_buf.play_finished(); + + + if ( _this->wakeup_playthread ) + wait = WaitForSingleObject( + _this->wakeup_playthread, + INFINITE + ); + + } + + } //if read_size != 0 + + } //( phdr->dwFlags & WHDR_DONE ) + + + break; // end case + + + + case MM_WOM_CLOSE: + // + // The thread can exit now. + // + + return 0; + + break; + + + case MM_WOM_OPEN: + + // + // Do nothing. + // + + break; + + + } //end switch( msg.message ) + + } //end while( GetMessage( ... )) + + return 0; +} + +_AUDIO_NAMESPACE_END_ diff --git a/reactos/base/applications/sndrec32/audio_waveout.hpp b/reactos/base/applications/sndrec32/audio_waveout.hpp new file mode 100644 index 00000000000..fd8debe8168 --- /dev/null +++ b/reactos/base/applications/sndrec32/audio_waveout.hpp @@ -0,0 +1,186 @@ +#ifndef _AUDIOWAVEOUT__H_ +#define _AUDIOWAVEOUT__H_ + + +#include "audio_def.hpp" +#include "audio_format.hpp" +#include "audio_producer.hpp" + + + +_AUDIO_NAMESPACE_START_ + +enum audio_waveout_status { WAVEOUT_NOTREADY, WAVEOUT_READY, + WAVEOUT_PLAYING, WAVEOUT_ERR, + WAVEOUT_PAUSED, WAVEOUT_STOP + + }; + + +class audio_waveout +{ + + friend class audio_buffer; + + + + private: + + + static DWORD WINAPI playing_procedure( LPVOID ); + + + + HANDLE wakeup_playthread; + + + + + protected: + + + WAVEFORMATEX wave_format; + WAVEHDR * wave_headers; + HWAVEOUT waveout_handle; + + + + + + const audio_format & aud_info; + audio_producer & audio_buf; + + + + + + + // + // Audio Playing Thread id + // + + DWORD playthread_id; + + + + + + audio_waveout_status status; + + + + + float buf_secs; + + + + // + // The temporary buffers for the audio + // data outgoing to the waveout device + // and its size, and its total number. + // + + + //base address for entire memory + BYTE * main_buffer; + + //size in bytes for the entire memory + unsigned int mb_size; + + //number of little buffers + unsigned int buffers; + + + + + + + // + // Protected Functions + // + + void init_( void ); + void alloc_buffers_mem_( unsigned int, float ); + void free_buffers_mem_( void ); + + + void init_headers_( void ); + void prep_headers_( void ); + void unprep_headers_( void ); + + + + + + + + public: + + // + // Ctors + // + + audio_waveout( const audio_format & aud_fmt, + audio_producer & a_buf ) + + : wave_headers( 0 ), aud_info( aud_fmt ), + audio_buf( a_buf ), status( WAVEOUT_NOTREADY ), + main_buffer( 0 ), mb_size( 0 ), + buffers( _AUDIO_DEFAULT_WAVEOUTBUFFERS ) + { + + // + // Initializing internal wavein data + // + + + init_(); + + } + + + + + + + // + // Dtor + // + + ~audio_waveout( void ) + { } + + + + + // + // Public Functions + // + + void open ( void ); + void play ( void ); + void pause ( void ); + void stop ( void ); + void close ( void ); + + + audio_waveout_status current_status( void ) + { return status; } + + + + + + + + +}; + + + +_AUDIO_NAMESPACE_END_ + + + + +#endif //ifdef _AUDIOWAVEOUT__H_ diff --git a/reactos/base/applications/sndrec32/bitmap1.bmp b/reactos/base/applications/sndrec32/bitmap1.bmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/reactos/base/applications/sndrec32/but_end.bmp b/reactos/base/applications/sndrec32/but_end.bmp new file mode 100644 index 0000000000000000000000000000000000000000..036ccb115fbc9110f5e728c83ee55107b44bfa5b GIT binary patch literal 1046 zcmeH^F%kkH3`M`AGqzTC_TItH-n&q_El2Sv+zkH@&SnEMasbVeknH;`ki9?72bet> zuk;)JLf@f**Pg}4PMqbG-#?Bqs*tyG}VC_*jN^e$N%2HcG?2yJu+UKFlH2+#0v9J!* zNcB{M0=5q?XMEYSN(6w35K3d^h!`V#2I)wolqZTOKe4P=@yE;W@24|sy+4>ixEYkI c!MGTl*9PbH7me3=RW4Y$V&R5`+j^hCcK}kE+W-In literal 0 HcmV?d00001 diff --git a/reactos/base/applications/sndrec32/but_rec.bmp b/reactos/base/applications/sndrec32/but_rec.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3e7249d64b397bcb82027a37ec1d50f49e1e9f4e GIT binary patch literal 1046 zcmZ?r6=PulgEAng0mRloEDOYp3=oM0%s>tl2momihJXeJ1|VW+Xn;^a63ApYaNq!t z21)z}BZmL~K`bB!LXZ%UD8~m17>1aqKvee=lm{z7(q4|HzZ|FlSsGIw5wu_yhW_Cv4*tl2momihJXeJ1|VW+Xn;^a63ApYaNq!t z21)z}BZmL~K`bB!LXZ%UD8~m17)FvjFl2y$9VtLi{XZ&CS@<9YER=~FzN7N!Api^? E0OoRr%m4rY literal 0 HcmV?d00001 diff --git a/reactos/base/applications/sndrec32/kkaudio.hpp b/reactos/base/applications/sndrec32/kkaudio.hpp new file mode 100644 index 00000000000..285b1d399c4 --- /dev/null +++ b/reactos/base/applications/sndrec32/kkaudio.hpp @@ -0,0 +1,18 @@ +#ifndef _AUDIO__H_ +#define _AUDIO__H_ + + +#include "audio_def.hpp" +#include "audio_wavein.hpp" +#include "audio_waveout.hpp" +#include "audio_resampler_acm.hpp" +#include "audio_format.hpp" +#include "audio_membuffer.hpp" +#include "audio_producer.hpp" +#include "audio_receiver.hpp" + + + + +#endif //ifdef _KKAUDIO__H_ + diff --git a/reactos/base/applications/sndrec32/reactOS_sndrec32.ico b/reactos/base/applications/sndrec32/reactOS_sndrec32.ico new file mode 100644 index 0000000000000000000000000000000000000000..d92d91e87d695a3f14b0c478c845c44ac18ed2bf GIT binary patch literal 23558 zcmeHP33yf2wf@6AC1BA=KuQ<{WKbwirS>bLf=a7Jp{*b?2vrFp1QJb{BOsDGfEb1_ zDh3Cv)h|6O~pz1Ci9 z?{n^O&fWh7g3t)z;Vl5v!xwdc1+2Ab;k3I30h8(iy?RkeyO%?NW%WRNx7`Tn*HZ1B z_W1h1(KgmT94}uE{HDFNXPb8ay4l)?V?4)Ndl%4^?mA?DB8YjI!dz_8;Y|pmhy(bK zxHw1fkyRoNJ9qA6hnRneXpP{Xs`#+5hL-phPGT``NnGw!Y`Teww&uuq({_~RQ3s%s zUeg@kM6JcpIzG{iO)FbdheQ+686cj`g{B>EqE1_$sJ>d9Xf$&y7dm;wudw;Lc{w3y zY@8U`m9D=t%IQ2>KPykirz$o)9nNdf^IXs4aKfJFaje^Nw$Ag7Zn5LK>lqo#Cjm>< zr87We?0^9Sii(PiWHmC@S^P+QyaMCe_*Ipuy0ah z>=@q|X)z&qXL3ut7u^cGrggxcSzYjtCwgGl+&=hn)j*^@-5-TXzr!~>X5!noA4OUe zaBvFn*8R+39GC+^nGwxg9u7hp<;PQl@XmxF?6@z8Hq4WFZDbI0BkobVI?RoEYwoP4 zQSP{}4sAGxd$g}E^#o-a<^Cykv72usyC>JBzxLNdMoc~05Ui(DX2jG-`XlvmIHm#X z4RPp^hDeWTg!I_P$l!c4r!__9^rpy|-VBF{%o!m#Fs&s%hzUi`+}8M8bQs==ZiD>A zUGU}NuE<}~1NqPPK*6&;DHT_uaA_|TBoHc>DSD$|c^_mwsqz{WuDBM3EBm5g1(Dd7 z_3Kc$`jFxy z3i+N>MEsNZhWM8Fj`%;~Kg9P$32}4e5saIXV&0>oqM{HP8HtF92;6(`y%;lQ3`UP0 zjgccqV#J6M7(RSBh7B9$douiZt1n*YC8;VCsFJZ6xauA@pELKgBh+|V)hW`xQkPAe zHkF$%jZ;!9E;Qd%u7}1|wXZB69lu;gl^JW|yZ7R*j(c6C4u&jMj z)$L2y(^)tUn3`%HjPTae^wKymA17^-TiIMxMdPa4bCAGsoOYnrSq|qk^skxf%MIZg zyIpn-J?%;C%RT3eqU^Gi+N7jg=hH z8|CmJgR%bh4tSn;jz}8Z2`>)qilm`eAokW?n0;Fx#N5&gF|1D=cqL*7^+x>g8*$HX z@4ztnKL6{sSkD`3NrO93avTN6h#k}mk+i>i=wNIfe;tx1-hfRL`eRo@6#l+^I-a`` z;H3*vBCf>;%cfxW(y16u+p(iZVmihfQ!{w9k z{_-e{`0Zf4avSjCAmUd*66JeQJ@M|;EAiivz3}$r-bi0P0Xv@VN(?1|}y_aEtjthM8ju_glhB7n{8-#C=lrZYNW|Mbq-8_Vn1_4gs? z`TKG3A>hD+#6&{tlZeT{e#(6l29r{0HQT?| z55S=(eu2E@{Za7zohW*BERMZ04xhg;7M~LPINsa5CO$Z&4h~MO%WKa1$eYsuU(9QY zBXfg!y&24FPlEE$^bqWSI2c)REs-5}F%gRFM-`VMdoD4r6=fK5=Cwx7{MN`Oa^|-| z&SRIM@agu*SP$M&_$ zSIc)NC;P27q;4r&l9QADiqyaX*zX^pe0*Pja!Tp^d|tMito^A@0y?Z0*R8UDi;b`S zUfyn%{mEYZQUmr{+YQMnzWmJqrpxP3O7YE~VNGOzDmK1}?YLQIquP*?;%jTw*VN-v zrk|aqv!Flw-TB+Omo9>%Vf+e;vl4pbO{de;NB3m#pLAB|7 ze7ql4O}`t*{<;F+aLgSKgy7TU`FK4c7P(J$!qG*Y@jr{Z;nv%$bAPvu9)0tXXz7Yh~>UT#zepgIjKAv309b zsd|6$+o*^3c{*0hw99$>Y(1xwSNyTdj(u{!)9wAC2TfmROTV`a|DnUx`q!?&$yT5h zJ1<1&oHXwziI*-gEYjS$&p>K2xc@=8529R-?pn86e`n_$?uQTs_e~gS+g8@J`El=t zZs*eTr4{#d2)|z!ey8q%_bI%()${vz;rH(b+F#w^_x>g)&6Rsly!^Q@rA)3BLu+_)di%b$D1OpZ2J&BxYNR(F1pH;odJZ2bDD~-@tq{ zf9`Yi^5?!slfUMEA>^+)a=)gRKlg8X`E&nWjbDGwUvsvfe`@ou-eXp~{?)tQfv-Qc z>tD0hpL^UzUpMu*C<2dHO=@d?nycn)Uq87|pBkss^w)pQPoX*6{K+?Pvv-7DZ*AFn zO_2U1$&aYbznYIvCF>tXK8n{>6V8*$a`2L5h5Q+*Tet2jd=9iFug2e1qt1E%T>MFr z2PDm!HTx6uZ%=NJzw5l`ugTcF1M4V21Er2- z;rjX8I<{$BzfxOr37KOZA^%ax@6*@Mjm$rcTtgv$QOHje@)LzzN=i^d$W;{bDxJC~ zRZp<(^iisx`uOy=-!FA+<6~`ge62GUd6zyJR9g*{-=;P zNjnGRTGFp#=-A|Gax4XH2y!i1uP5Y(3VESI{-lXRo~V!`%CYJRd9^}bqL7y;L?0oqQplea@+gIT zN+GY(h1M$ud6+^Tr;x8Hb2Uf^26>>?198)3pRLG637(6cIxEheFD&-KK^1-t^zhaK~qB&?RoIGvM!U*-io z$7)ZV>sHyi2I_U6Ryfh02r@NRYD;A+5X=t#%Fh|$O!p^+FrGdWH1;TB9uZG0tOA~* z?RuiBdyLl5hm0hIF1;l@A--SOmycZ+S~TzH7Z=Uz>w~thJ0(ugrb>wTS!iD4dUal4 z{2t_c3Hf0{o|usLRR-jK2{~j!E}4*1c4lzLFyk-=d1#E)LE45i*uwa|$s==~Iu$(X zcgo}kneSjL=&rI#@6&1_&rCWtub;~JJ;`Bnlzg=JL9O&UD(JH|Rgrc)^5vvWlb~eA z?@lhAQR{ci_WNd?_ql+MuZ5gF32O`!pL{)|)3wo4^Z#5t5AEv@`MA=ep)-H-biMc*+aFiY*RwTm9orUig1z|U02{Tw z{@68FdA8!(HTB0Q-`I;!934M)m@#jVcoM;8y8OBRv`~t$iEiyuUStal7;+iAy1q4liw9`xFz)B zpP1Jla^i)2dm%?($j=vY^MxFJM{3(bb#9$pey{G?s*WJ9U&z@P^6X_ze+W7JLN34X z_W^{wd?7zy$kUh5&`^!viF|k=uU^Q%7xM3gyn7+%-bnKBgZH^6?GG z*LQT2*;YhA$iEkI?}fa5ArD{3%NPE}fRIlv{G9}2*REZ=4UFGz?<5qH3oqof3pwsW zt~=%RLjJpu6EEbv3pw&auDlej>PuWJasx zDao4IjIwb_*0d%i*)u~*ve}&2CYgIiqQD=FDcrnbR8=XH08Q zoE`;(%xMja)1y&*nD}f4ijU30KXYdWefPmbSgf&$+H#&(z`pFnRbL)KHl|9wPf^O- z4L?;DYWfr6qAEb`n-J>DU(i4t@#tw{F70LzgVzo2ymjHt9rNbh)V@G5*Oj&%DCgV| zUa(+br{hDqw%kYm$h0>Sza!^Z$Q>4PeTDp7Q`dGyu(neNcF$4&jFhz}biMR_L}5Rt zR3_C%-*=}BxFSpavr-a`|LMM`>3b&m!4iFQ7vuj)>hd%4kGa+H|7`2BD*Kb0EYk;d zHt}<}CwTsv+v&`M9A}wz+vUdp=$lJC|5N$u_zLxp`;FsYu+zz(YO}7owicD?R6pzAp=Z~M50-;g^l=!}4<% zw9e0sZ=0X1?Z+<8|9tL6`FRV%@{c{HXDTA8Hy&|Hj05EpfQc+(p(q LpjCk$11DMJ&~?Z`Rv6fQi+BE?wA2yG_2p%IcuKt6mG})llut`nVdv zw@oek0BmXl+}+Z$XPtKc?r+%#U>wI|!ofTYVJ?>F@J0xuAr9bw#KoD4 zuPhRA*t2I3JH+@85iJq?r%im>>>=zfAu%N-Dt2)RiHe=WQEd77-0Q1W(W}^g6~(Qt zRW{iD9`#?$`g*J1vu<{;T4nWL?7C+>&$^faHGgCM=9u-LVy*Qv3}o@*sMvm{ut5)v zUGFCnx42eZalK!tN8RwV#m|CK2Z7#HNd0&lycG4h_P_dxDTWBnZnxTjS+nfkYd;IJ7NZ9M%>o)G4%i zW858h?cSDn^-ry^nb`El)7@i1D{X! z!huP(@L5zXWW{=8-^AM3J+3wm#rWdgNe%ISbYpxltrhmp3c^2@cEktsy5jq!5FC1@ zH%_Mf5kK#qiC^BCi$ha^1CxQbA7Ty>U=9RzW;Ano%z;DHUrce}-SH0W9_yeD^CVs$ z;b3mW18V1FZp>SAXZaBI?y*kVa1IY>Up2N9)Q70|Pp*cK_=n`9N!94D{ne2fQ=K*h z%ZI5mV`|{=<2CSQOih-(aPV<29FD1l!?CrI$@ykYtAniRb&xr|F1{qPX87W>X$|pl zj3096HNoGa{qb&eQ{*oT!uQMCA%A&Ct>}!CE4tuB0-<`PA{ZwUyCVB3 z)i>ef^WAZBbq}0)o>JnNxqp1h<_136Tc9@68}&9hxm;sBKk)iMa1Oo#^0!^Q>P*- zDhiR2k$CXI2Qhl|Xp9;)3L{30!0_S25gs0n`|i8X?alDNTXbIOvOVKGWV_S*9HpjV zm*Mm|M|;yO!|DBUs!KL)-fR`i)SFXZ_NINAedRRLzFs+9soM-G*;}t1do?wWyOxT5 z%C@&`tuv+Aqj84Quh`oxd0MNNk1 zT$YD*J?XR48R=tV40$B*bbwro+KZQDxp^<0qQj5w?G9oRb} zBqX9E8ZMyyy^ll&yJV&zR?XI-cg~wRXmGG2ZR>!!>CQ*uQeF%V-MBF{DRg6ed{R`Omp(3WZ;Ol!o~h>lYhv84na?)#zD++r zme6tf(NOP|RI2ou*P$ApA*qE|>2>s6SF2v~xs~fawYnL`cy-;U&YtpwQ4Jp&hUB|i z;RRv?krEb&mxi@N%CPGY8`=f42X{rxfG&t(c}hrU#10I`lJLHG;15G^AAMiAvpJIa zKrJP#6*b3EaE#c2T@Xe4`-g>L>$slSHlYvF#`net2~+X+#Oc`37vQZ6wnuiy$15k} zqZLySPTMh~Mj)Bb<2Hl<>+c}?5iGA`Ib&isq))gBYaZ%_PZKBN!^Ei={)aHUG8lMi zATbC?p?-gAC%iYMGyWRY1@BA>#^E*Nv1jQh987uy2UbtO{#B3Se)_!?&Nz1hO9uL4 zZ%li9_;^QTuN#NVwUO8t32bHm=3%@yoe_xr)7#>cSl-7bk45ea58=S0z-NyT69_F& zBqjm-srQX1*tS>uC)dCivzp=XoIrfFs6BF*w8wWVx}$*iZ2wN~hl5LRL0)2SoOt0L z6udeH$6txSHyg*`2(gdjy~BIr1CyONFr^yrIcp$qPEC9_zYdPh^Wpub5AQt*>VwmL zvHvk2WXCl`PFy3x4>@xc*C1yeF~2djKXT_cLGFSk$RTnUG)3;hW;ppwOXMzUfs@Mu zsaxWQruF>D+-?PiXYc?L&55saB6iooKE7L z4D>+3np-%(+i-gQ?fBwp-oL*5Cw%ip6gH)-!^jcCarD4uE}rwW`%mcQi|* zxO&xO#|~{UCGZBb-}JR+T5QmQ{Y~j@^|-Wcp#GiD+VAPk9Ngk}Dm8p@e;1B_rvBU5 z-{TDa+TZ=G{iO`7^wQKnW?D%Vo*TdxzrJAO8=}+|w0H!h-Qu+!#z9ayy>7=LRe#62foB z!jS`TI4uc_M~5JL*G4=Y5rQYjgdlgf@uS0r()c9X@@c7m}vmkK=!N9zS!;-4FZX z$hHM|BOw;Yo(jab&$h)sm$k?7XFK5Ac;eZPIKHeCzEv#09>20Ks^wLV z>%wm8*0oFL>u(6|(7sd08(ZJ#HnFmcB0JLJuw@HMBMoq-13R_?Z@yWg-?3$j$d)%n zoauU9{SU%@5T$Z-t##w% zd)nr5KZGc_Z^F=4-O`n9e%!mkC!EIl(wKWXgx{|Vzf-rt=M;9?YUlUw!tdV=Xn#e6 z-}@UmX|CLZV&~6&DJ60(D=%vfW%XT-Htwgf^XGn<3SZ0LJ7@0mvGeD?AK^X>dk$9F z(!V#>#rD^8f%}#0{JDS0$Y1lVtT}tG0ryhb`E!4ja1V?<2eq~4qV1l2o?}&XU324p zFgt(l5i@eMa@BmSvg(S??`-ijf9`Fw^XDG6N}aFgd~{8@_s-6r`|*VPr;ItM_O!2T zb-mzB*_Dkx^?Tm#{6578|2<~+4I+Ath_zTR-&5o)mLBr z2J>%4ev{Q~X!Ug$Ypjc*t#L1OEX!YWzUG>1jQq)+vYHKjp<`EspOvWQY~@cLnAKcq z^DmJgE99-&`IFP;*tE%Yw_#y{=;$b<3~VmRv&S=oIoFh5SCfer{&| z{^S}8`HMn+qL7~`t-Ld`l*jwyVdWmb!@}Oveogm%vj`I z3i*{n9;T54`IkcerD0F5r;wj26mlJf+($!`|0v{t3VD;XGeNE;{mO=pO`aylQqYDV*OKMxLVl=_ z7b@gW8ga-I6>>y5R&^n-R>(^f@)CtyQX$V$KfkTi{K?}KaxaB^MPs-(OX@L@;8 z3&e%)Px56veJ5z_k;Hsr39_aF z=J#-e)_a~6r)hIuh`hlsuXc6kM#k?*zL$_6Cgh0;d0!*vzdd=K6&|0wQE65e+-Hr} zmn(j~nlPRdlG|G5{H=4*I(8RJYcTR>rM@dZIkI+qjbXk2FU9-Ny8e)lEA_q1`IDz> z$Jf~IarJz?So7AgEg>h^j!zD-(X7`WYt2<(thm;iy2mHq*p5#gvX#~a#kX?y%vaY= zuj#6-xmkh8d6ovQ^(PnFYBuI z*h2obkblkcc4C{5pDpBR^Lg@nLJqh1HM+{U{*V(dEd>06Y;{+wC$igM;O zEXtnKurPae{lcsnbqcd))-BAMUb`@JTFt`4Q(+)$npffBXcT@)d_4n&$7kVR$7VWy z{rFKV)7V6nT;>(9E<14*mxsfOsal^?6!Ufi&X$FmUPUxG52(F2p}zbD4TF|Em-<{V zk9ISNu=QbWcP{SVI&c0REl()sxwKXH)N}d-oLCeRcxq_7hWqFrb!f|~U&%QZa)*Un zUm-u&C~LheShiC_I^?Q<=Js``b-ncOh{F1uQl3^D{kuE4-*wsQpS^vR;eW1w)AVm9 z`N0z1KgjU^Dn0Rn{9{5*|F3thJa2z;lV$qAwnqG8Zzb6Nn%lX|gB)j>HMou8|82%{ z+y897I=({v2FDynZHkT*xCA^2uHBHR|M=Q!DBUdF4WWxsabOGys@|DlJb`RqCNO#9P$ORmk&d!lLnvBm!R#}+loKenWK{xPjDY?S}ayaxGsi~RGC pKhZe<>&1a5_Rb0Z;V+NYiK2gP;<8E{dh)w1^B17bN9!?A`7d1liXZ?0 literal 0 HcmV?d00001 diff --git a/reactos/base/applications/sndrec32/sndrec32.cpp b/reactos/base/applications/sndrec32/sndrec32.cpp new file mode 100644 index 00000000000..b1b6a30a214 --- /dev/null +++ b/reactos/base/applications/sndrec32/sndrec32.cpp @@ -0,0 +1,1042 @@ +/* +* PROJECT: ReactOS Sound Record Application +* LICENSE: GPL - See COPYING in the top level directory +* FILE: base/applications/sndrec32/sndrec32.cpp +* PURPOSE: Application Startup +* PROGRAMMERS: Marco Pagliaricci +*/ + + + +#include "stdafx.h" +#include "sndrec32.h" + +#include "kkaudio.hpp" + + + +HINSTANCE hInst; +TCHAR szTitle[MAX_LOADSTRING]; +TCHAR szWindowClass[MAX_LOADSTRING]; + + +ATOM MyRegisterClass(HINSTANCE hInstance); +BOOL InitInstance(HINSTANCE, int); +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); + + + +HWND main_win; +HWND slider; +HWND buttons[5]; +HBITMAP butbmps[5]; +WNDPROC buttons_std_proc; + +BOOL butdisabled[5]; +BOOL stopped_flag; +BOOL isnew; + + +DWORD slider_pos; +WORD slider_min; +WORD slider_max; + +long long samples_max; + +OPENFILENAME ofn; +TCHAR file_path[MAX_PATH]; +BOOL path_set; + +using snd::audio_membuffer; +using snd::audio_wavein; +using snd::audio_waveout; + +audio_membuffer * AUD_BUF; +audio_waveout * AUD_OUT; +audio_wavein * AUD_IN; + + +BOOL s_recording; + + +int APIENTRY _tWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) +{ + + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + + + MSG msg; + HACCEL hAccelTable; + + InitCommonControls(); + + + + + + + + + butbmps[0] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_START )); + butbmps[1] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_END )); + butbmps[2] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_PLAY )); + butbmps[3] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_STOP )); + butbmps[4] = LoadBitmap( hInstance, MAKEINTRESOURCE( IDB_BITMAP2_REC )); + + + + + + + snd::audio_membuffer AUD_buffer( snd::A44100_16BIT_STEREO ); + snd::audio_waveout AUD_waveout( snd::A44100_16BIT_STEREO, AUD_buffer ); + snd::audio_wavein AUD_wavein( snd::A44100_16BIT_STEREO, AUD_buffer ); + + AUD_buffer.play_finished = l_play_finished; + AUD_buffer.audio_arrival = l_audio_arrival; + AUD_buffer.buffer_resized = l_buffer_resized; + + AUD_buffer.alloc_seconds( INITIAL_BUFREC_SECONDS ); + + AUD_IN = &AUD_wavein; + AUD_OUT = &AUD_waveout; + AUD_BUF = &AUD_buffer; + + + + slider_pos = 0; + slider_min = 0; + slider_max = 32767; + + + stopped_flag = FALSE; + path_set = FALSE; + isnew = TRUE; + + + + samples_max = AUD_buffer.total_samples(); + + + + + LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); + LoadString(hInstance, IDC_REACTOS_SNDREC32, szWindowClass, MAX_LOADSTRING); + MyRegisterClass(hInstance); + + + if (!InitInstance (hInstance, nCmdShow)) + { + MessageBox(0, 0, TEXT("CreateWindow() Error!"), 0); + return FALSE; + } + + hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_REACTOS_SNDREC32)); + + + + + + + s_recording = false; + + + + + AUD_wavein.open(); + AUD_waveout.open(); + + + + + + + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + AUD_waveout.close(); + AUD_wavein.close(); + + AUD_buffer.clear(); + + + return (int) msg.wParam; +} + + + + +ATOM MyRegisterClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_REACTOS_SNDREC32LL)); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(16); + wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1); + wcex.lpszClassName = szWindowClass; + wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_REACTOS_SNDREC32LL)); + + + return RegisterClassEx(&wcex); +} + +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + HWND hWnd; + + hInst = hInstance; + + hWnd = CreateWindow( + szWindowClass, + szTitle, + WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, + CW_USEDEFAULT, + CW_USEDEFAULT, + MAINWINDOW_W, + MAINWINDOW_H, + NULL, NULL, + hInstance, NULL + ); + + if (!hWnd) + { + return FALSE; + } + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + main_win = hWnd; + + + return TRUE; +} + + +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + RECT rect; + PAINTSTRUCT ps; + HDC hdc; + + + // + // Checking for global pointers to buffer and + // io audio devices. + // + + if (( !AUD_IN ) || ( !AUD_OUT ) || ( !AUD_BUF )) + { + MessageBox( 0, TEXT("Buffer Error"), 0, 0 ); + return 1; + } + + + switch (message) + { + + + case WM_CREATE: + + + + // + // Creating ALL the buttons + // + + for ( int i = 0; i < 5; ++ i ) + { + + buttons[i] = CreateWindow( + TEXT("button"), + TEXT(""), + WS_CHILD|WS_VISIBLE| BS_BITMAP, + BUTTONS_CX + ( i * (BUTTONS_W+((i == 0)?0:BUTTONS_SPACE))), + BUTTONS_CY, BUTTONS_W, BUTTONS_H, hWnd, + (HMENU)i, hInst, 0 + ); + + if ( !buttons[i] ) + { + MessageBox(0, 0, TEXT("CreateWindow() Error!"), 0); + return FALSE; + + } + + butdisabled[ i ] = TRUE; + + + + // + // Realize the button bmp image + // + + SendMessage(buttons[i], BM_SETIMAGE, ( WPARAM )IMAGE_BITMAP, ( LPARAM )butbmps[i]); + + + UpdateWindow( buttons[i] ); + + } + + + // + // Creating the SLIDER window + // + + slider = CreateWindow( + TRACKBAR_CLASS, + TEXT(""), + WS_CHILD|WS_VISIBLE|TBS_NOTICKS|TBS_HORZ|TBS_ENABLESELRANGE, + SLIDER_CX, SLIDER_CY, SLIDER_W, SLIDER_H, hWnd, + (HMENU)SLIDER_ID, hInst, 0 + ); + + + if ( !slider ) + { + MessageBox(0, 0, TEXT("CreateWindow() Error!"), 0); + return FALSE; + + } + + + // + // Sets slider limits + // + + //slider_min = 0; + //slider_max = 100; + + SendMessage( + slider, + TBM_SETRANGE, + (WPARAM)TRUE, + (LPARAM)MAKELONG(slider_min,slider_max) + ); + + + UpdateWindow( slider ); + + + // + // Enables REC button. + // + + butdisabled[ BUTREC_ID ] = FALSE; + + + + + break; + + + + // + // Implements slider logic + // + + case WM_HSCROLL : + { + switch( LOWORD( wParam )) + { + + case SB_ENDSCROLL: + break; + + case SB_PAGERIGHT: + case SB_PAGELEFT: + case TB_THUMBTRACK: + slider_pos = SendMessage(slider, TBM_GETPOS, 0, 0); + break; + + } + + break; + } + + + + + + + case WM_COMMAND: + + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + + if (( wmId >= 0 ) && ( wmId < 5 ) && (butdisabled[wmId] == TRUE)) + break; + + switch (wmId) + { + + case ID_NEW: + + if ( !isnew ) + { + + if ( AUD_IN->current_status() == snd::WAVEIN_RECORDING ) + AUD_IN->stop_recording(); + + + if (( AUD_OUT->current_status() == snd::WAVEOUT_PLAYING ) || + ( AUD_OUT->current_status() == snd::WAVEOUT_PAUSED )) + AUD_OUT->stop(); + + + AUD_BUF->reset(); + + butdisabled[ BUTREC_ID ] = FALSE; + butdisabled[ BUTSTART_ID ] = TRUE; + butdisabled[ BUTEND_ID ] = TRUE; + butdisabled[ BUTSTOP_ID ] = TRUE; + butdisabled[ BUTPLAY_ID ] = TRUE; + + samples_max = AUD_BUF->total_samples(); + slider_pos = 0; + + SendMessage(slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos); + + } + + + + break; + + + + + case ID_FILE_OPEN: + + ZeroMemory( &ofn, sizeof( ofn )); + + ofn.lStructSize = sizeof( ofn ); + ofn.hwndOwner = hWnd; + ofn.lpstrFilter = TEXT("Audio Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0"); + ofn.lpstrFile = file_path; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + ofn.lpstrDefExt = TEXT("wav"); + + if( GetOpenFileName( &ofn )) + { + open_wav( file_path ); + } + + break; + + + + + case ID__ABOUT: + + + + break; + + + case ID_FILE_SAVEAS: + + ZeroMemory( &ofn, sizeof( ofn )); + + ofn.lStructSize = sizeof( ofn ); + ofn.hwndOwner = hWnd ; + ofn.Flags = OFN_OVERWRITEPROMPT; + ofn.lpstrFilter = TEXT("Audio Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0"); + ofn.lpstrFile = file_path; + ofn.nMaxFile = MAX_PATH; + + ofn.lpstrDefExt = TEXT("wav"); + + if ( GetSaveFileName ( &ofn )) + { + + write_wav( file_path ); + + } + + break; + + case ID_EXIT: + DestroyWindow( hWnd ); + break; + + + // + // Sndrec32 buttons routines + // + + case BUTSTART_ID: + Beep(200,200); + break; + + + case BUTEND_ID: + Beep(300,200); + break; + + case BUTPLAY_ID: + + AUD_OUT->play(); + + butdisabled[ BUTSTART_ID ] = TRUE; + butdisabled[ BUTEND_ID ] = TRUE; + butdisabled[ BUTREC_ID ] = TRUE; + butdisabled[ BUTPLAY_ID ] = TRUE; + + SetTimer( hWnd, 1, 250, 0 ); + + break; + + case BUTSTOP_ID: + if ( s_recording ) + { + s_recording = FALSE; + + AUD_IN->stop_recording(); + + butdisabled[ BUTSTART_ID ] = FALSE; + butdisabled[ BUTEND_ID ] = FALSE; + butdisabled[ BUTREC_ID ] = FALSE; + butdisabled[ BUTPLAY_ID ] = FALSE; + + + + // + // Resetting slider position + // + + slider_pos = 0; + SendMessage(slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos); + + + samples_max = AUD_BUF->samples_received(); + + EnableMenuItem((HMENU)IDR_MENU1, ID_FILE_SAVEAS, MF_ENABLED ); + + } else { + + AUD_OUT->pause(); + + butdisabled[ BUTSTART_ID ] = FALSE; + butdisabled[ BUTEND_ID ] = FALSE; + butdisabled[ BUTREC_ID ] = FALSE; + butdisabled[ BUTPLAY_ID ] = FALSE; + + } + + KillTimer( hWnd, 1 ); + + break; + + case BUTREC_ID: + + s_recording = TRUE; + + samples_max = AUD_BUF->total_samples(); + + AUD_IN->start_recording(); + + butdisabled[ BUTSTOP_ID ] = FALSE; + butdisabled[ BUTSTART_ID ] = TRUE; + butdisabled[ BUTEND_ID ] = TRUE; + butdisabled[ BUTREC_ID ] = TRUE; + butdisabled[ BUTPLAY_ID ] = TRUE; + + isnew = FALSE; + + + + SetTimer( hWnd, 1, 150, 0 ); + + break; + + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + break; + + + case WM_TIMER: + + if ( stopped_flag ) + { + KillTimer(hWnd, 1); + slider_pos = 0; + + butdisabled[ BUTPLAY_ID ] = FALSE; + + stopped_flag = FALSE; + } + + SendMessage(slider, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) slider_pos); + + + + break; + + + + case WM_PAINT: + + InvalidateRect( hWnd, &rect, TRUE ); + hdc = BeginPaint(hWnd, &ps); + + EndPaint(hWnd, &ps); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + + +BOOL open_wav( TCHAR * f ) +{ + + + HANDLE file; + + riff_hdr r; + wave_hdr w; + data_chunk d; + + BOOL b; + + DWORD bytes_recorded_in_wav = 0; + DWORD is_read = 0; + + + + + file = CreateFile( + f, + GENERIC_READ, + 0, 0, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + 0 + ); + + + + if ( !file ) + { + MessageBox( + main_win, + TEXT("Cannot open file. CreateFile() error."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + return FALSE; + + } + + + b = ReadFile( file, ( LPVOID ) &r, sizeof ( r ), &is_read, 0 ); + + if ( !b ) + { + DWORD t = GetLastError(); + TCHAR p[100]; + wsprintf(p,TEXT("Errore n: %i"),t); + + MessageBox( + main_win, + //TEXT("Cannot read RIFF header."), + p, + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + return FALSE; + + } + + + b = ReadFile( file, ( LPVOID ) &w, sizeof ( w ), &is_read, 0 ); + + + if ( !b ) + { + + MessageBox( + main_win, + TEXT("Cannot read WAVE header."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + return FALSE; + + } + + + + b = ReadFile( file, ( LPVOID ) &d, sizeof ( d ), &is_read, 0 ); + + if ( !b ) + { + + MessageBox( + main_win, + TEXT("Cannot read WAVE subchunk."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + return FALSE; + + } + + bytes_recorded_in_wav = r.chunksize - 36; + + + /* + unsigned char * gg = (unsigned char*)&bytes_recorded_in_wav; + + gg[0] = gg[3]; + gg[1] = gg[2]; + + bytes_recorded_in_wav = (DWORD) *gg; + + + + TCHAR p [100]; + wsprintf(p,TEXT("bytes: %i"),bytes_recorded_in_wav); + MessageBox(0,p,0,0); + + */ + + if ( bytes_recorded_in_wav == 0 ) + { + + MessageBox( + main_win, + TEXT("Cannot read file. No audio data."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + return FALSE; + + } + + + snd::audio_format openfmt + ( w.SampleRate, w.BitsPerSample, w.NumChannels ); + + + + AUD_BUF->clear(); + + + AUD_BUF->alloc_bytes( bytes_recorded_in_wav ); + + + b = ReadFile( + file, + ( LPVOID ) AUD_BUF->audio_buffer(), + bytes_recorded_in_wav, + &is_read, + 0 + ); + + + AUD_BUF->set_b_received( bytes_recorded_in_wav ); + + + if (( !b ) || ( is_read != bytes_recorded_in_wav )) + { + + MessageBox( + main_win, + TEXT("Cannot read file. Error reading audio data."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + + AUD_BUF->reset(); + return FALSE; + + } + + CloseHandle( file ); + + butdisabled[ BUTPLAY_ID ] = FALSE; + butdisabled[ BUTSTOP_ID ] = FALSE; + butdisabled[ BUTEND_ID ] = FALSE; + butdisabled[ BUTSTART_ID ] = FALSE; + butdisabled[ BUTREC_ID ] = FALSE; + + + + samples_max = AUD_BUF->samples_received(); + + isnew = FALSE; + + return TRUE; + +} + + +BOOL + write_wav( TCHAR * f ) +{ + + HANDLE file; + + + DWORD written; + BOOL is_writ; + int i; + riff_hdr r; + wave_hdr w; + data_chunk d; + + + + file = CreateFile( + f, + GENERIC_WRITE, + 0, 0, + CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + 0 + ); + + + + if ( !file ) + { + i = MessageBox( + main_win, + TEXT("File already exist. Overwrite it?"), + TEXT("Warning"), + MB_YESNO|MB_ICONQUESTION + ); + + if ( i == IDYES ) + { + + file = CreateFile( + f, + GENERIC_WRITE, + 0, 0, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + 0 + ); + + if ( !file ) + { + MessageBox( + main_win, + TEXT("File Error, CreateFile() failed."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + + return FALSE; + + } + + + } else + return FALSE; + } + + + + + r.magic = 0x46464952; + + + r.format = 0x45564157; + r.chunksize = 36 + AUD_BUF->bytes_recorded(); + + + w.Subchunkid = 0x20746d66; + + w.Subchunk1Size = 16; + w.AudioFormat = 1; + w.NumChannels = AUD_BUF->audinfo().channels(); + w.SampleRate = AUD_BUF->audinfo().sample_rate(); + w.ByteRate = AUD_BUF->audinfo().byte_rate(); + w.BlockAlign = AUD_BUF->audinfo().block_align(); + w.BitsPerSample = AUD_BUF->audinfo().bits(); + + + d.subc = 0x61746164; + d.subc_size = AUD_BUF->bytes_recorded(); + + + + // + // Writing headers + // + + + is_writ = WriteFile( file, ( LPCVOID ) &r, sizeof ( r ), &written, 0 ); + + if ( !is_writ ) + { + MessageBox( + main_win, + TEXT("File Error, WriteFile() failed."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + + return FALSE; + + } + + + is_writ = WriteFile( file, ( LPCVOID ) &w, sizeof ( w ), &written, 0 ); + + if ( !is_writ ) + { + MessageBox( + main_win, + TEXT("File Error, WriteFile() failed."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + + return FALSE; + + } + + + is_writ = WriteFile( file, ( LPCVOID ) &d, sizeof ( d ), &written, 0 ); + + + if ( !is_writ ) + { + MessageBox( + main_win, + TEXT("File Error, WriteFile() failed."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + + return FALSE; + + } + + + + is_writ = WriteFile( + file, + ( LPCVOID ) AUD_BUF->audio_buffer(), + AUD_BUF->bytes_recorded(), + &written, + 0 + ); + + if ( !is_writ ) + { + MessageBox( + main_win, + TEXT("File Error, WriteFile() failed."), + TEXT("ERROR"), + MB_OK|MB_ICONERROR + ); + + CloseHandle( file ); + + return FALSE; + + } + + + CloseHandle( file ); + + return TRUE; +} + + + +void l_play_finished ( void ) +{ + + stopped_flag = true; + + + +} + +void l_audio_arrival ( unsigned int samples_arrival ) +{ + + + slider_pos += (DWORD) (( slider_max * samples_arrival ) / samples_max ); + + +} + +void l_buffer_resized ( unsigned int new_size ) +{ + + + + + +} + +VOID enable_but( DWORD id ) +{ + + + + + +} +VOID disable_but( DWORD id ) +{ + + + +} + + diff --git a/reactos/base/applications/sndrec32/sndrec32.h b/reactos/base/applications/sndrec32/sndrec32.h new file mode 100644 index 00000000000..530e53e93a6 --- /dev/null +++ b/reactos/base/applications/sndrec32/sndrec32.h @@ -0,0 +1,96 @@ +#pragma once + +#include "resource.h" + + + +#define MAX_LOADSTRING 100 + +#define MAINWINDOW_W 350 +#define MAINWINDOW_H 190 + + +#define CONTROLS_CX 10 + +#define INITIAL_BUFREC_SECONDS 30.0f + + +#define BUTSTART_ID 0 +#define BUTEND_ID 1 +#define BUTPLAY_ID 2 +#define BUTSTOP_ID 3 +#define BUTREC_ID 4 +#define SLIDER_ID 5 + +#define BUTTONS_H 30 +#define BUTTONS_W 60 +#define BUTTONS_CY 100 +#define BUTTONS_CX CONTROLS_CX +#define BUTTONS_SPACE 5 + + +#define SLIDER_CX CONTROLS_CX +#define SLIDER_CY 65 +#define SLIDER_H 30 +#define SLIDER_W 320 + + + + +struct riff_hdr +{ + DWORD magic; + DWORD chunksize; + DWORD format; +}; + + +struct wave_hdr +{ + + DWORD Subchunkid; + DWORD Subchunk1Size; + WORD AudioFormat; + WORD NumChannels; + DWORD SampleRate; + DWORD ByteRate; + WORD BlockAlign; + WORD BitsPerSample; +}; + +struct data_chunk +{ + DWORD subc; + DWORD subc_size; + //unsigned char data[]; +}; + + + +// +// Functions prototypes +// +LRESULT CALLBACK +Buttons_proc(HWND, UINT, WPARAM, LPARAM); + + +BOOL +write_wav( TCHAR * ); + +BOOL +open_wav( TCHAR * ); + + +VOID enable_but( DWORD ); +VOID disable_but( DWORD ); + + + +void +l_play_finished ( void ); + +void +l_audio_arrival ( unsigned int ); + +void +l_buffer_resized ( unsigned int ); diff --git a/reactos/base/applications/sndrec32/sndrec32.rbuild b/reactos/base/applications/sndrec32/sndrec32.rbuild new file mode 100644 index 00000000000..291555117e4 --- /dev/null +++ b/reactos/base/applications/sndrec32/sndrec32.rbuild @@ -0,0 +1,20 @@ + + + + . + winmm + user32 + kernel32 + msacm32 + comctl32 + comdlg32 + audio_format.cpp + audio_membuffer.cpp + audio_producer.cpp + audio_receiver.cpp + audio_resampler_acm.cpp + audio_wavein.cpp + audio_waveout.cpp + sndrec32.cpp + sndrec32.rc + diff --git a/reactos/base/applications/sndrec32/sndrec32.rc b/reactos/base/applications/sndrec32/sndrec32.rc new file mode 100644 index 00000000000..e4de736ec11 --- /dev/null +++ b/reactos/base/applications/sndrec32/sndrec32.rc @@ -0,0 +1,179 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#ifndef APSTUDIO_INVOKED +#include "targetver.h" +#endif +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Italiano (Italia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA) +#ifdef _WIN32 +LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_REACTOS_SNDREC32LL ICON "reactOS_sndrec32.ico" +IDI_SMALL ICON "small.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDC_REACTOS_SNDREC32 ACCELERATORS +BEGIN + "?", IDM_ABOUT, ASCII, ALT + "/", IDM_ABOUT, ASCII, ALT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOGEX 0, 0, 196, 75 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Informazioni su reactOS_sndrec32" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + ICON 128,IDC_REACTOS_SNDREC32,19,14,21,20 + LTEXT "reactOS_sndrec32, versione 1.0",IDC_STATIC,56,16,114,8,SS_NOPREFIX + LTEXT "Copyright (C) 2009",IDC_STATIC,55,25,114,8 + DEFPUSHBUTTON "OK",IDOK,139,54,50,14,WS_GROUP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 189 + TOPMARGIN, 7 + BOTTOMMARGIN, 68 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#ifndef APSTUDIO_INVOKED\r\n" + "#include ""targetver.h""\r\n" + "#endif\r\n" + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_BITMAP2_START BITMAP "but_start.bmp" +IDB_BITMAP2_END BITMAP "but_end.bmp" +IDB_BITMAP2_PLAY BITMAP "but_play.bmp" +IDB_BITMAP2_STOP BITMAP "but_stop.bmp" +IDB_BITMAP2_REC BITMAP "but_rec.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU +BEGIN + POPUP "File" + BEGIN + MENUITEM "New", ID_NEW + MENUITEM "Open...", ID_FILE_OPEN + MENUITEM "Save", ID_FILE_SAVE, GRAYED + MENUITEM "Save As...", ID_FILE_SAVEAS + MENUITEM SEPARATOR + MENUITEM "Exit", ID_EXIT + END + MENUITEM "todo1", 0 + MENUITEM "todo2", 0 + POPUP "?" + BEGIN + MENUITEM "About...", ID__ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_TITLE "reactOS_sndrec32" + IDC_REACTOS_SNDREC32 "REACTOS_SNDREC32" +END + +#endif // Italiano (Italia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/reactos/base/applications/sndrec32/stdafx.h b/reactos/base/applications/sndrec32/stdafx.h new file mode 100644 index 00000000000..69ca28669ec --- /dev/null +++ b/reactos/base/applications/sndrec32/stdafx.h @@ -0,0 +1,23 @@ +// stdafx.h : file di inclusione per file di inclusione di sistema standard +// o file di inclusione specifici del progetto utilizzati di frequente, ma +// modificati raramente +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Escludere gli elementi utilizzati di rado dalle intestazioni di Windows +// File di intestazione di Windows: +#include +#include +#include + +// File di intestazione Runtime C +#include +#include +#include +#include + + +// TODO: fare riferimento qui alle intestazioni aggiuntive richieste dal programma diff --git a/reactos/base/applications/sndrec32/targetver.h b/reactos/base/applications/sndrec32/targetver.h new file mode 100644 index 00000000000..92426c66d27 --- /dev/null +++ b/reactos/base/applications/sndrec32/targetver.h @@ -0,0 +1,24 @@ +#pragma once + +// Le macro seguenti definiscono la piattaforma minima richiesta. La piattaforma minima richiesta +// č costituita dalla versione meno recente di Windows, Internet Explorer e cosě via contenenti le funzionalitŕ necessarie per eseguire +// l'applicazione. Le macro consentono di attivare tutte le funzionalitŕ disponibili nelle versioni delle piattaforme fino +// alla versione specificata compresa. + +// Modificare le seguenti definizioni se č necessario utilizzare come destinazione una piattaforma prima di quelle specificate di seguito. +// Fare riferimento a MSDN per informazioni aggiornate sui valori corrispondenti per le differenti piattaforme. +#ifndef WINVER // Specifica che la piattaforma minima richiesta č Windows Vista. +#define WINVER 0x0600 // Modificare il valore con quello appropriato per altre versioni di Windows. +#endif + +#ifndef _WIN32_WINNT // Specifica che la piattaforma minima richiesta č Windows Vista. +#define _WIN32_WINNT 0x0600 // Modificare il valore con quello appropriato per altre versioni di Windows. +#endif + +#ifndef _WIN32_WINDOWS // Specifica che la piattaforma minima richiesta č Windows 98. +#define _WIN32_WINDOWS 0x0410 // Modificare il valore con quello appropriato per Windows Me o versioni successive. +#endif + +#ifndef _WIN32_IE // Specifica che la piattaforma minima richiesta č Internet Explorer 7.0. +#define _WIN32_IE 0x0700 // Modificare il valore con quello appropriato per altre versioni di IE. +#endif From 78365fd832b60efaa6ec1b1afd006641acc7e13e Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 30 Nov 2009 19:21:27 +0000 Subject: [PATCH 118/140] - [Win32k] Use PostMessage to send broadcast messages to the queues. co_IntPostOrSendMessage does not support it. svn path=/trunk/; revision=44332 --- .../subsystems/win32/win32k/ntuser/class.c | 19 ++++++++++--------- .../subsystems/win32/win32k/ntuser/focus.c | 6 ++++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/class.c b/reactos/subsystems/win32/win32k/ntuser/class.c index 04008afabea..3828a37b710 100644 --- a/reactos/subsystems/win32/win32k/ntuser/class.c +++ b/reactos/subsystems/win32/win32k/ntuser/class.c @@ -628,7 +628,7 @@ IntDereferenceClass(IN OUT PCLS Class, { ASSERT(Class->pclsBase == Class); - DPRINT("IntDereferenceClass 0x%x\n", Class); + DPRINT1("IntDereferenceClass 0x%x\n", Class); /* check if there are clones of the class on other desktops, link the first clone in if possible. If there are no clones then leave the class on the desktop heap. It will get moved @@ -666,7 +666,7 @@ IntDereferenceClass(IN OUT PCLS Class, } else { - DPRINT("IntDereferenceClass1 0x%x\n", Class); + DPRINT1("IntDereferenceClass1 0x%x\n", Class); /* locate the cloned class and unlink it */ PrevLink = &BaseClass->pclsClone; @@ -1154,7 +1154,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, &pi->pclsPrivateList, Link); if (Class != NULL) - { + { DPRINT1("Step 1: 0x%x\n",Class ); goto FoundClass; } @@ -1165,7 +1165,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, &pi->pclsPublicList, Link); if (Class != NULL) - { + { DPRINT1("Step 2: 0x%x 0x%x\n",Class, Class->hModule); goto FoundClass; } @@ -1175,7 +1175,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, &pi->pclsPrivateList, Link); if (Class != NULL) - { + { DPRINT1("Step 3: 0x%x\n",Class ); goto FoundClass; } @@ -1188,7 +1188,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, { SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST); return (RTL_ATOM)0; - } + }else{DPRINT1("Step 4: 0x%x\n",Class );} FoundClass: *BaseClass = Class; @@ -1294,7 +1294,7 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName, pi = GetW32ProcessInfo(); - DPRINT("UserUnregisterClass(%wZ, 0x%x)\n", ClassName, hInstance); + DPRINT1("UserUnregisterClass(%wZ, 0x%x)\n", ClassName, hInstance); /* NOTE: Accessing the buffer in ClassName may raise an exception! */ ClassAtom = IntGetClassAtom(ClassName, @@ -1326,8 +1326,8 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName, if (NT_SUCCESS(IntDeregisterClassAtom(Class->atomClassName))) { - DPRINT("Class 0x%x\n", Class); - DPRINT("UserUnregisterClass: Good Exit!\n"); + DPRINT1("Class 0x%x\n", Class); + DPRINT1("UserUnregisterClass: Good Exit!\n"); /* finally free the resources */ IntDestroyClass(Class); return TRUE; @@ -2402,6 +2402,7 @@ InvalidParameter: if (Ret) { + DPRINT1("GetClassInfo(%wZ, 0x%x)\n", ClassName, hInstance); ClassAtom = IntGetClassAtom( &SafeClassName, hInstance, ppi, diff --git a/reactos/subsystems/win32/win32k/ntuser/focus.c b/reactos/subsystems/win32/win32k/ntuser/focus.c index dd2fd4db1cf..3614b736283 100644 --- a/reactos/subsystems/win32/win32k/ntuser/focus.c +++ b/reactos/subsystems/win32/win32k/ntuser/focus.c @@ -77,8 +77,10 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate) /* Send palette messages */ if (co_IntPostOrSendMessage(hWnd, WM_QUERYNEWPALETTE, 0, 0)) { - co_IntPostOrSendMessage(HWND_BROADCAST, WM_PALETTEISCHANGING, - (WPARAM)hWnd, 0); + UserPostMessage( HWND_BROADCAST, + WM_PALETTEISCHANGING, + (WPARAM)hWnd, + 0); } if (UserGetWindow(hWnd, GW_HWNDPREV) != NULL) From c4e84dd68241cbfbc155b28277543e5137c9ddcd Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 30 Nov 2009 19:24:23 +0000 Subject: [PATCH 119/140] - [Win32k] Remove debug prints from classes. svn path=/trunk/; revision=44333 --- .../subsystems/win32/win32k/ntuser/class.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/class.c b/reactos/subsystems/win32/win32k/ntuser/class.c index 3828a37b710..5e8f074bb41 100644 --- a/reactos/subsystems/win32/win32k/ntuser/class.c +++ b/reactos/subsystems/win32/win32k/ntuser/class.c @@ -628,7 +628,7 @@ IntDereferenceClass(IN OUT PCLS Class, { ASSERT(Class->pclsBase == Class); - DPRINT1("IntDereferenceClass 0x%x\n", Class); + DPRINT("IntDereferenceClass 0x%x\n", Class); /* check if there are clones of the class on other desktops, link the first clone in if possible. If there are no clones then leave the class on the desktop heap. It will get moved @@ -666,7 +666,7 @@ IntDereferenceClass(IN OUT PCLS Class, } else { - DPRINT1("IntDereferenceClass1 0x%x\n", Class); + DPRINT("IntDereferenceClass1 0x%x\n", Class); /* locate the cloned class and unlink it */ PrevLink = &BaseClass->pclsClone; @@ -1154,7 +1154,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, &pi->pclsPrivateList, Link); if (Class != NULL) - { DPRINT1("Step 1: 0x%x\n",Class ); + { DPRINT("Step 1: 0x%x\n",Class ); goto FoundClass; } @@ -1165,7 +1165,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, &pi->pclsPublicList, Link); if (Class != NULL) - { DPRINT1("Step 2: 0x%x 0x%x\n",Class, Class->hModule); + { DPRINT("Step 2: 0x%x 0x%x\n",Class, Class->hModule); goto FoundClass; } @@ -1175,7 +1175,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, &pi->pclsPrivateList, Link); if (Class != NULL) - { DPRINT1("Step 3: 0x%x\n",Class ); + { DPRINT("Step 3: 0x%x\n",Class ); goto FoundClass; } @@ -1188,7 +1188,7 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, { SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST); return (RTL_ATOM)0; - }else{DPRINT1("Step 4: 0x%x\n",Class );} + }else{DPRINT("Step 4: 0x%x\n",Class );} FoundClass: *BaseClass = Class; @@ -1294,7 +1294,7 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName, pi = GetW32ProcessInfo(); - DPRINT1("UserUnregisterClass(%wZ, 0x%x)\n", ClassName, hInstance); + DPRINT("UserUnregisterClass(%wZ, 0x%x)\n", ClassName, hInstance); /* NOTE: Accessing the buffer in ClassName may raise an exception! */ ClassAtom = IntGetClassAtom(ClassName, @@ -1326,8 +1326,8 @@ UserUnregisterClass(IN PUNICODE_STRING ClassName, if (NT_SUCCESS(IntDeregisterClassAtom(Class->atomClassName))) { - DPRINT1("Class 0x%x\n", Class); - DPRINT1("UserUnregisterClass: Good Exit!\n"); + DPRINT("Class 0x%x\n", Class); + DPRINT("UserUnregisterClass: Good Exit!\n"); /* finally free the resources */ IntDestroyClass(Class); return TRUE; @@ -2402,7 +2402,7 @@ InvalidParameter: if (Ret) { - DPRINT1("GetClassInfo(%wZ, 0x%x)\n", ClassName, hInstance); + DPRINT("GetClassInfo(%wZ, 0x%x)\n", ClassName, hInstance); ClassAtom = IntGetClassAtom( &SafeClassName, hInstance, ppi, From 4b9396cef94e26f483c89333b8e0cd623bbcac6b Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 30 Nov 2009 20:13:05 +0000 Subject: [PATCH 120/140] - [Win32k] Test thread death before posting to queue. svn path=/trunk/; revision=44334 --- reactos/subsystems/win32/win32k/ntuser/message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index c9681928a7b..c11c35beede 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -1324,7 +1324,7 @@ UserPostThreadMessage( DWORD idThread, if( Status == STATUS_SUCCESS ) { pThread = (PTHREADINFO)peThread->Tcb.Win32Thread; - if( !pThread || !pThread->MessageQueue ) + if( !pThread || !pThread->MessageQueue || (pThread->TIF_flags & TIF_INCLEANUP)) { ObDereferenceObject( peThread ); return FALSE; From 378568a6d95a922b8a32b56d76f73610c9afcd07 Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Mon, 30 Nov 2009 21:49:18 +0000 Subject: [PATCH 121/140] Update log2lines to version 1.4. Jan Roeloffzen, bug #4342. svn path=/trunk/; revision=44335 --- reactos/tools/rsym/log2lines.c | 441 +++++++++++++++++++++------------ 1 file changed, 277 insertions(+), 164 deletions(-) diff --git a/reactos/tools/rsym/log2lines.c b/reactos/tools/rsym/log2lines.c index d79d5cc59af..c2616c25946 100644 --- a/reactos/tools/rsym/log2lines.c +++ b/reactos/tools/rsym/log2lines.c @@ -1,14 +1,6 @@ /* - * Usage: log2lines [-cd:fFhmrv] [ ] - * Try log2lines -h - * - * This is a tool and is compiled using the host compiler, - * i.e. on Linux gcc and not mingw-gcc (cross-compiler). - * Therefore we can't include SDK headers and we have to - * duplicate some definitions here. - * Also note that the internal functions are "old C-style", - * returning an int, where a return of 0 means success and - * non-zero is failure. + * ReactOS log2lines + * Written by Jan Roeloffzen */ #include @@ -18,7 +10,7 @@ #include "rsym.h" -#define LOG2LINES_VERSION "1.1" +#define LOG2LINES_VERSION "1.4" #define INVALID_BASE 0xFFFFFFFFL @@ -34,7 +26,7 @@ #define CP_CMD "copy /Y " #define DIR_FMT "dir /a:-d /s /b %s > %s" -#else /* not defined (__DJGPP__) || defined (__WIN32__) */ +#else /* not defined (__DJGPP__) || defined (__WIN32__) */ #include #include @@ -48,17 +40,26 @@ #define CP_CMD "cp -f " #define DIR_FMT "find %s -type f > %s" -#endif /* not defined (__DJGPP__) || defined (__WIN32__) */ +#endif /* not defined (__DJGPP__) || defined (__WIN32__) */ #define CP_FMT CP_CMD "%s %s > " DEV_NULL #define CMD_7Z "7z" +//#define UNZIP_FMT_7Z "%s e -y %s -o%s > " DEV_NULL +#define UNZIP_FMT_7Z "%s e -y %s -o%s" #define UNZIP_FMT "%s x -y -r %s -o%s > " DEV_NULL #define UNZIP_FMT_CAB \ "%s x -y -r %s" PATH_STR "reactos" PATH_STR "reactos.cab -o%s" PATH_STR "reactos" PATH_STR "reactos > " DEV_NULL #define LINESIZE 1024 +#define log(outFile, fmt, ...) \ + { \ + fprintf(outFile, fmt, ##__VA_ARGS__); \ + if (logFile) \ + fprintf(logFile, fmt, ##__VA_ARGS__); \ + } + struct entry_struct { char *buf; @@ -79,20 +80,21 @@ struct cache_struct struct summ_struct { - int translated; - int undo; - int redo; - int skipped; - int diff; - int offset_errors; - int total; + int translated; + int undo; + int redo; + int skipped; + int diff; + int majordiff; + int offset_errors; + int total; }; typedef struct cache_struct CACHE; -typedef struct summ_struct SUMM; +typedef struct summ_struct SUMM; -static CACHE cache; -static SUMM summ; +static CACHE cache; +static SUMM summ; static char *optchars = "bcd:fFhl:mMrstTuUvz:"; static int opt_buffered= 0; // -b @@ -112,7 +114,7 @@ static int opt_redo = 0; // -U static char opt_dir[MAX_PATH]; // -d static char opt_logFile[MAX_PATH]; // -l static char opt_7z[MAX_PATH]; // -z -static char opt_scanned[LINESIZE]; // all scanned options +static char opt_scanned[LINESIZE]; // all scanned options static FILE *logFile = NULL; static char *cache_name; @@ -152,11 +154,11 @@ find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESec } static PROSSYM_ENTRY -find_offset(void *data, size_t offset, char *toString) +find_offset(void *data, size_t offset) { - PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data; - PROSSYM_ENTRY Entries = (PROSSYM_ENTRY) ((char *)data + RosSymHeader->SymbolsOffset); - size_t symbols = RosSymHeader->SymbolsLength / sizeof (ROSSYM_ENTRY); + PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data; + PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset); + size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY); size_t i; for (i = 0; i < symbols; i++) @@ -177,80 +179,108 @@ find_offset(void *data, size_t offset, char *toString) static int print_offset(void *data, size_t offset, char *toString) { - PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER) data; + PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data; PROSSYM_ENTRY e = NULL; PROSSYM_ENTRY e2 = NULL; + int bFileOffsetChanged = 0; + char fmt[LINESIZE]; char *Strings = (char *)data + RosSymHeader->StringsOffset; - - e = find_offset(data, offset, toString); + fmt[0] = '\0'; + e = find_offset(data, offset); if (opt_twice) { - e2 = find_offset(data, offset-1, toString); - - if ( e == e2 ) - e2 = NULL; + e2 = find_offset(data, offset - 1); - if ( opt_Twice && e2 ) + if (e == e2) + e2 = NULL; + else + summ.diff++; + + if (opt_Twice && e2) { e = e2; e2 = NULL; - /* replaced (transparantly), but update stats: */ - summ.diff ++; + /* replaced (transparantly), but updated stats */ } } - if ( e || e2 ) + if (e || e2) { - if (toString) - { // put in toString if provided - if ( e2 ) - { - snprintf(toString, LINESIZE, "%s:%u (%s) [%s:%u (%s)]", + if (e2) + { + bFileOffsetChanged = e->FileOffset != e2->FileOffset; + if (e->FileOffset != e2->FileOffset || e->FunctionOffset != e2->FunctionOffset) + summ.majordiff++; + + /* + * - "%.0s" displays nothing, but processes argument + * - bFileOffsetChanged implies always display 2nd SourceLine even if the same + * - also for FunctionOffset + */ + strcat(fmt, "%s"); + if (bFileOffsetChanged) + strcat(fmt, "[%s]"); + else + strcat(fmt, "%.0s"); + + strcat(fmt, ":%u"); + if (e->SourceLine != e2->SourceLine || bFileOffsetChanged) + strcat(fmt, "[%u]"); + else + strcat(fmt, "%.0u"); + + strcat(fmt, " (%s"); + if (e->FunctionOffset != e2->FunctionOffset || bFileOffsetChanged) + strcat(fmt, "[%s])"); + else + strcat(fmt, "%.0s)"); + + if (toString) + { // put in toString if provided + snprintf(toString, LINESIZE, fmt, &Strings[e->FileOffset], - (unsigned int)e->SourceLine, - &Strings[e->FunctionOffset], &Strings[e2->FileOffset], + (unsigned int)e->SourceLine, (unsigned int)e2->SourceLine, + &Strings[e->FunctionOffset], &Strings[e2->FunctionOffset]); - summ.diff ++; } else { + strcat(fmt, "\n"); + printf(fmt, + &Strings[e->FileOffset], + &Strings[e2->FileOffset], + (unsigned int)e->SourceLine, + (unsigned int)e2->SourceLine, + &Strings[e->FunctionOffset], + &Strings[e2->FunctionOffset]); + } + } + else + { + if (toString) + { // put in toString if provided snprintf(toString, LINESIZE, "%s:%u (%s)", &Strings[e->FileOffset], (unsigned int)e->SourceLine, &Strings[e->FunctionOffset]); } - return 0; - } - else - { // to stdout - if ( e2 ) - { - printf("%s:%u (%s) [%s:%u (%s)]\n", - &Strings[e->FileOffset], - (unsigned int)e->SourceLine, - &Strings[e->FunctionOffset], - &Strings[e2->FileOffset], - (unsigned int)e2->SourceLine, - &Strings[e2->FunctionOffset]); - summ.diff ++; - } else { printf("%s:%u (%s)\n", - &Strings[e->FileOffset], + &Strings[e->FileOffset], (unsigned int)e->SourceLine, &Strings[e->FunctionOffset]); } - return 0; } + return 0; } return 1; } static int -process_data(const void *FileData, size_t FileSize, size_t offset, char *toString) +process_data(const void *FileData, size_t offset, char *toString) { PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_FILE_HEADER PEFileHeader; @@ -261,24 +291,24 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin int res; /* Check if MZ header exists */ - PEDosHeader = (PIMAGE_DOS_HEADER) FileData; + PEDosHeader = (PIMAGE_DOS_HEADER)FileData; if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L) { fprintf(stderr, "Input file is not a PE image.\n"); - summ.offset_errors ++; + summ.offset_errors++; return 1; } /* Locate PE file header */ /* sizeof(ULONG) = sizeof(MAGIC) */ - PEFileHeader = (PIMAGE_FILE_HEADER) ((char *)FileData + PEDosHeader->e_lfanew + sizeof (ULONG)); + PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG)); /* Locate optional header */ - PEOptHeader = (PIMAGE_OPTIONAL_HEADER) (PEFileHeader + 1); + PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1); ImageBase = PEOptHeader->ImageBase; /* Locate PE section headers */ - PESectionHeaders = (PIMAGE_SECTION_HEADER) ((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader); + PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader); /* make sure offset is what we want */ offset = fixup_offset(ImageBase, offset); @@ -288,7 +318,7 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin if (!PERosSymSectionHeader) { fprintf(stderr, "Couldn't find rossym section in executable\n"); - summ.offset_errors ++; + summ.offset_errors++; return 1; } res = print_offset((char *)FileData + PERosSymSectionHeader->PointerToRawData, offset, toString); @@ -303,16 +333,15 @@ process_data(const void *FileData, size_t FileSize, size_t offset, char *toStrin printf("??:0\n"); } fprintf(stderr, "Offset not found.\n"); - summ.offset_errors ++; + summ.offset_errors++; } return res; } -static long -my_atoi(const char *a) +static const char * +getFmt(const char *a) { - int i = 0; const char *fmt = "%x"; if (*a == '0') @@ -332,10 +361,26 @@ my_atoi(const char *a) break; } } - sscanf(a, fmt, &i); + return fmt; +} + +static long +my_atoi(const char *a) +{ + int i = 0; + sscanf(a, getFmt(a), &i); return i; } +static int +isOffset(const char *a) +{ + int i = 0; + if (strchr(a, '.')) + return 0; + return sscanf(a, getFmt(a), &i); +} + static int file_exists(char *name) { @@ -387,7 +432,7 @@ process_file(const char *file_name, size_t offset, char *toString) } else { - res = process_data(FileData, FileSize, offset, toString); + res = process_data(FileData, offset, toString); free(FileData); } return res; @@ -408,12 +453,12 @@ get_ImageBase(char *fname, size_t *ImageBase) fr = fopen(fname, "rb"); if (!fr) { - if (opt_verbose) + if (opt_verbose > 2) fprintf(stderr, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno)); return 1; } - readLen = fread(&PEDosHeader, sizeof (IMAGE_DOS_HEADER), 1, fr); + readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr); if (1 != readLen) { if (opt_verbose) @@ -432,8 +477,8 @@ get_ImageBase(char *fname, size_t *ImageBase) } /* Locate PE file header */ - res = fseek(fr, PEDosHeader.e_lfanew + sizeof (ULONG), SEEK_SET); - readLen = fread(&PEFileHeader, sizeof (IMAGE_FILE_HEADER), 1, fr); + res = fseek(fr, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET); + readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr); if (1 != readLen) { if (opt_verbose) @@ -443,7 +488,7 @@ get_ImageBase(char *fname, size_t *ImageBase) } /* Locate optional header */ - readLen = fread(&PEOptHeader, sizeof (IMAGE_OPTIONAL_HEADER), 1, fr); + readLen = fread(&PEOptHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, fr); if (1 != readLen) { if (opt_verbose) @@ -453,8 +498,8 @@ get_ImageBase(char *fname, size_t *ImageBase) } /* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */ - if ((PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) && - (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)) + if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC && + PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { if (opt_verbose > 1) fprintf(stderr, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR<32|64>\n", fname); @@ -500,7 +545,7 @@ entry_create(char *Line) if (!Line) return NULL; - pentry = malloc(sizeof (CACHE_ENTRY)); + pentry = malloc(sizeof(CACHE_ENTRY)); if (!pentry) return NULL; @@ -557,7 +602,7 @@ entry_lookup(char *name) if (PATHCMP(name, pnext->name) == 0) { if (pprev) - { // move to head for faster lookup next time + { // move to head for faster lookup next time pprev->pnext = pnext->pnext; pnext->pnext = cache.phead; cache.phead = pnext; @@ -680,7 +725,7 @@ create_cache(int force, int skipImageBase) if (*Fname == '\n') *Fname = '\0'; - while ((Fname > Line) && (*Fname != PATH_CHAR)) + while (Fname > Line && *Fname != PATH_CHAR) Fname--; if (*Fname == PATH_CHAR) Fname++; @@ -770,9 +815,9 @@ translate_char(int c, FILE *outFile) static char * remove_mark(char *Line) { - if( Line[1] == ' ' && Line[2] == '<' ) - if ( Line[0] == '*' || Line[0] == '?' ) - return Line+2; + if (Line[1] == ' ' && Line[2] == '<') + if (Line[0] == '*' || Line[0] == '?') + return Line + 2; return Line; } @@ -799,33 +844,29 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut) if (cnt == 3 && ch == ' ') { tail = strchr(s, '>'); - tail = tail ? tail-1 : tail; - if (tail && (tail[0] == ')') && (tail[1] == '>') ) + tail = tail ? tail - 1 : tail; + if (tail && tail[0] == ')' && tail[1] == '>') { res = 0; tail += 2; mark = opt_mark ? "* " : ""; if (opt_redo && !(res = translate_file(path, offset, LineOut))) { - fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); - if (logFile) - fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); - summ.redo ++; + log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); + summ.redo++; } else { - fprintf(outFile, "%s<%s:%x>%s", mark, path, offset, tail); - if (logFile) - fprintf(logFile, "%s<%s:%x>%s", mark, path, offset, tail); - summ.undo ++; + log(outFile, "%s<%s:%x>%s", mark, path, offset, tail); + summ.undo++; } } else { mark = opt_Mark ? "? " : ""; - summ.skipped ++; + summ.skipped++; } - summ.total ++; + summ.total++; } } @@ -837,17 +878,15 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut) if (!(res = translate_file(path, offset, LineOut))) { mark = opt_mark ? "* " : ""; - fprintf(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); - if (logFile) - fprintf(logFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); - summ.translated ++; + log(outFile, "%s<%s:%x (%s)>%s", mark, path, offset, LineOut, tail); + summ.translated++; } else { mark = opt_Mark ? "? " : ""; - summ.skipped ++; + summ.skipped++; } - summ.total ++; + summ.total++; } } } @@ -855,36 +894,35 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut) { if (sep) *sep = ':'; // restore because not translated - fprintf(outFile, "%s%s", mark, s); // just copy - if (logFile) - fprintf(logFile, "%s%s", mark, s); // just copy + log(outFile, "%s%s", mark, s); } memset(Line, '\0', LINESIZE); // flushed } static void -print_summary(FILE * outFile) +print_summary(FILE *outFile) { if (outFile) { fprintf(outFile, "\n*** LOG2LINES SUMMARY ***\n"); - fprintf(outFile, "Translated: %d\n", summ.translated); - fprintf(outFile, "Reverted: %d\n", summ.undo); - fprintf(outFile, "Retranslated: %d\n", summ.redo); - fprintf(outFile, "Skipped: %d\n", summ.skipped); - fprintf(outFile, "Differ: %d\n", summ.diff); - fprintf(outFile, "Offset error: %d\n", summ.offset_errors); - fprintf(outFile, "Total: %d\n", summ.total); + fprintf(outFile, "Translated: %d\n", summ.translated); + fprintf(outFile, "Reverted: %d\n", summ.undo); + fprintf(outFile, "Retranslated: %d\n", summ.redo); + fprintf(outFile, "Skipped: %d\n", summ.skipped); + fprintf(outFile, "Differ: %d\n", summ.diff); + fprintf(outFile, "Differ (function/source): %d\n", summ.majordiff); + fprintf(outFile, "Offset error: %d\n", summ.offset_errors); + fprintf(outFile, "Total: %d\n", summ.total); fprintf(outFile, "-------------------------------\n"); fprintf(outFile, "Log2lines version: " LOG2LINES_VERSION "\n"); - fprintf(outFile, "Directory: %s\n",opt_dir); - fprintf(outFile, "Passed options: %s\n",opt_scanned); + fprintf(outFile, "Directory: %s\n", opt_dir); + fprintf(outFile, "Passed options: %s\n", opt_scanned); fprintf(outFile, "-------------------------------\n"); } } static int -translate_files(FILE * inFile, FILE * outFile) +translate_files(FILE *inFile, FILE *outFile) { char *Line = malloc(LINESIZE + 1); char *path = malloc(LINESIZE + 1); @@ -927,7 +965,6 @@ translate_files(FILE * inFile, FILE * outFile) translate_line(outFile, Line, path, LineOut); translate_char(c, outFile); } - i = 0; } else { @@ -962,7 +999,7 @@ translate_files(FILE * inFile, FILE * outFile) } } else - { // Line by line, slightly faster but less interactive + { // Line by line, slightly faster but less interactive while (fgets(Line, LINESIZE, inFile) != NULL) { if (!opt_raw) @@ -971,9 +1008,7 @@ translate_files(FILE * inFile, FILE * outFile) } else { - fprintf(outFile, "%s", Line); // just copy - if (logFile) - fprintf(logFile, "%s", Line); // just copy + log(outFile, "%s", Line); } } } @@ -993,9 +1028,12 @@ translate_files(FILE * inFile, FILE * outFile) static char *verboseUsage = "\n" "Description:\n" -" When are given, log2lines works just like raddr2line\n" +" When are given, log2lines works like raddr2line:\n" +" - The combination can be repeated\n" +" - Also, can be repeated for each \n" +" - NOTE: some of the options below will have no effect in this form.\n" " Otherwise it reads stdin and tries to translate lines of the form:\n" -" \n\n" +" \n\n" " The result is written to stdout.\n" " log2lines uses a cache in order to avoid a directory scan at each\n" " image lookup, greatly increasing performance. Only image path and its\n" @@ -1008,7 +1046,9 @@ static char *verboseUsage = " -d |\n" " Directory to scan for images. (Do not append a '" PATH_STR "')\n" " This option also takes an ISO image as argument:\n" -" - The image is recognized by the '.iso' extension.\n" +" - The image is recognized by the '.iso' or '.7z' extension.\n" +" - NOTE: The '.7z' and extracted '.iso' basenames must be identical,\n" +" which is normally true for Reactos trunk builds.\n" " - The image will be unpacked to a directory with the same name.\n" " - The embedded reactos.cab file will also be unpacked.\n" " - Combined with -f the file will be re-unpacked.\n" @@ -1026,17 +1066,20 @@ static char *verboseUsage = " -r Raw output without translation.\n\n" " -s Statistics. A summary with the following info is printed after EOF:\n" " *** LOG2LINES SUMMARY ***\n" -" - Translated: Translated lines.\n" -" - Reverted: Lines translated back. See -u option\n" -" - Retranslated: Lines retranslated. See -U option\n" -" - Skipped: Lines not translated.\n" -" - Differ: Lines where (addr-1) info differs. See -tT options\n" -" - Offset error: Image exists, but error retrieving offset info.\n" -" - Total: Total number of lines attempted to translate.\n" +" - Translated: Translated lines.\n" +" - Reverted: Lines translated back. See -u option\n" +" - Retranslated: Lines retranslated. See -U option\n" +" - Skipped: Lines not translated.\n" +" - Differ: Lines where (addr-1) info differs. See -tT options\n" +" - Differ(func/src):Lines where also function or source info differ.\n" +" - Offset error: Image exists, but error retrieving offset info.\n" +" - Total: Total number of lines attempted to translate.\n" " Also some version info is displayed.\n\n" " -t Translate twice. The address itself and for (address - 1)\n" -" Display extra filename and linenumber between [..] if they differ\n\n" -" -T As -t, but the original filename+linenumber gets replaced\n\n" +" Show extra filename, func and linenumber between [..] if they differ\n" +" So if only the linenumbers differ, then only show the extra\n" +" linenumber.\n\n" +" -T As -t, but the original filename+func+linenumber gets replaced\n\n" " -u Undo translations.\n" " Lines are translated back (reverted) to the form \n" " Overrides console mode -c.\n\n" @@ -1053,7 +1096,7 @@ static char *verboseUsage = "Examples:\n" " Setup is a VMware machine with its serial port set to: '\\\\.\\pipe\\kdbg'.\n\n" " Just recreate cache after a svn update or a new module has been added:\n" -" log2lines -F\n\n" +" log2lines -F\n\n" " Use kdbg debugger via console (interactive):\n" " log2lines -c < \\\\.\\pipe\\kdbg\n\n" " Use kdbg debugger via console, and append copy to logFile:\n" @@ -1061,14 +1104,22 @@ static char *verboseUsage = " Use kdbg debugger to send output to logfile:\n" " log2lines < \\\\.\\pipe\\kdbg > dbg.log\n\n" " Re-translate a debug log:\n" -" log2lines -d bootcd-38701-dbg.iso < bugxxxx.log\n\n" +" log2lines -U -d bootcd-38701-dbg.iso < bugxxxx.log\n\n" +" Re-translate a debug log. Specify a 7z file, which wil be decompressed.\n" +" Also check for (address) - (address - 1) differences:\n" +" log2lines -U -t -d bootcd-38701-dbg.7z < bugxxxx.log\n" +" This would generate loglines like:\n" +" ''\n\n" +" The following command line invocations are equivalent:\n" +" log2lines msi.dll 2e35d msi.dll 2235 msiexec.exe 30a8 msiexec.exe 2e89\n" +" log2lines msi.dll 2e35d 2235 msiexec.exe 30a8 2e89\n\n" "\n"; static void usage(int verbose) { fprintf(stderr, "log2lines " LOG2LINES_VERSION "\n\n"); - fprintf(stderr, "Usage: log2lines [-%s] [ ]\n", optchars); + fprintf(stderr, "Usage: log2lines -%s { {}}\n", optchars); if (verbose) { fprintf(stderr, "%s", verboseUsage); @@ -1085,7 +1136,7 @@ unpack_iso(char *dir, char *iso) char Line[LINESIZE]; int res = 0; char iso_tmp[MAX_PATH]; - int iso_copied = 0; + int iso_copied = 0; FILE *fiso; strcpy(iso_tmp, iso); @@ -1094,8 +1145,8 @@ unpack_iso(char *dir, char *iso) if (opt_verbose) fprintf(stderr, "Open of %s failed (locked for writing?), trying to copy first\n", iso); - strcat(iso_tmp,"~"); - if (copy_file(iso,iso_tmp)) + strcat(iso_tmp, "~"); + if (copy_file(iso, iso_tmp)) return 3; iso_copied = 1; } @@ -1135,10 +1186,51 @@ unpack_iso(char *dir, char *iso) static int check_directory(int force) { + char Line[LINESIZE]; char freeldr_path[MAX_PATH]; char iso_path[MAX_PATH]; + char compressed_7z_path[MAX_PATH]; + char *check_iso; + char *check_dir; + + check_iso = strrchr(opt_dir, '.'); + if (check_iso && PATHCMP(check_iso, ".7z") == 0) + { + if (opt_verbose) + fprintf(stderr, "Uncompressing 7z image: %s\n", opt_dir); + + // First attempt to decompress to a .iso image + strcpy(compressed_7z_path, opt_dir); + if ((check_dir = strrchr(compressed_7z_path, PATH_CHAR))) + { + *check_dir = '\0'; + } + else + strcpy(compressed_7z_path, "."); // default to current dir + + sprintf(Line, UNZIP_FMT_7Z, opt_7z, opt_dir, compressed_7z_path); + + /* This of course only works if the .7z and .iso basenames are identical + * which is normally true for our trunk builds: + */ + strcpy(check_iso, ".iso"); + if (!file_exists(opt_dir) || force) + { + if (system(Line) < 0) + { + fprintf(stderr, "\nCannot decompress to iso image %s\n", opt_dir); + if (opt_verbose) + fprintf(stderr, "Failed to execute: '%s'\n", Line); + return 2; + } + } + else + { + if (opt_verbose > 1) + fprintf(stderr, "%s already decompressed\n", opt_dir); + } + } - char *check_iso = strrchr(opt_dir, '.'); if (check_iso && PATHCMP(check_iso, ".iso") == 0) { if (opt_verbose) @@ -1187,7 +1279,7 @@ main(int argc, const char **argv) int i; strcpy(opt_scanned, ""); - for (i=1; i - translate_file(argv[optCount + 1], my_atoi(argv[optCount + 2]), NULL); + + if (argc > 1) + { // translate { } + int i = 1; + const char *base = NULL; + const char *offset = NULL; + while (i < argc) + { + offset = argv[optCount + i++]; + if (isOffset(offset)) + { + if (base) + { + if (opt_verbose > 1) + fprintf(stderr, "translating %s %s\n", base, offset); + translate_file(base, my_atoi(offset), NULL); + } + else + { + fprintf(stderr, " expected\n"); + res = 3; + break; + } + } + else + { + // Must be exefile + base = offset; + } + } } else - { // translate logging from stdin + { // translate logging from stdin translate_files(stdin, stdout); } if (logFile) fclose(logFile); + return res; } From 4a32024814f765856ea5f20d4ceb95474aaa9d07 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 1 Dec 2009 05:35:05 +0000 Subject: [PATCH 122/140] - [Win32k] Make DispatchMessage call direct to WinProc callback. Add more thread death checks. svn path=/trunk/; revision=44340 --- .../subsystems/win32/win32k/ntuser/message.c | 53 ++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index c11c35beede..683612d4662 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -335,6 +335,9 @@ IntDispatchMessage(PMSG pMsg) LARGE_INTEGER TickCount; LONG Time; LRESULT retval; + PMSGMEMORY MsgMemoryEntry; + INT lParamBufferSize; + LPARAM lParamPacked; PWINDOW_OBJECT Window = NULL; if (pMsg->hwnd) @@ -376,9 +379,37 @@ IntDispatchMessage(PMSG pMsg) } } // Need a window! - if (!Window) return 0; + if ( !Window || !Window->Wnd ) return 0; - retval = co_IntPostOrSendMessage(pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam); + /* See if this message type is present in the table */ + MsgMemoryEntry = FindMsgMemory(pMsg->message); + if ( !MsgMemoryEntry ) + { + lParamBufferSize = -1; + } + else + { + lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam); + } + + if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam))) + { + DPRINT1("Failed to pack message parameters\n"); + return 0; + } + + retval = co_IntCallWindowProc( Window->Wnd->lpfnWndProc, + !Window->Wnd->Unicode, + pMsg->hwnd, + pMsg->message, + pMsg->wParam, + lParamPacked, + lParamBufferSize); + + if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam))) + { + DPRINT1("Failed to unpack message parameters\n"); + } if (pMsg->message == WM_PAINT) { @@ -1324,7 +1355,7 @@ UserPostThreadMessage( DWORD idThread, if( Status == STATUS_SUCCESS ) { pThread = (PTHREADINFO)peThread->Tcb.Win32Thread; - if( !pThread || !pThread->MessageQueue || (pThread->TIF_flags & TIF_INCLEANUP)) + if( !pThread || !pThread->MessageQueue || (pThread->TIF_flags & TIF_INCLEANUP)) { ObDereferenceObject( peThread ); return FALSE; @@ -1370,7 +1401,6 @@ UserPostMessage(HWND Wnd, wParam, lParam); - pti = PsGetCurrentThreadWin32Thread(); if (Wnd == HWND_BROADCAST) { HWND *List; @@ -1392,11 +1422,19 @@ UserPostMessage(HWND Wnd, PWINDOW_OBJECT Window; Window = UserGetWindowObject(Wnd); - if (NULL == Window) + if ( !Window || !Window->Wnd ) { return FALSE; } - if(Window->Status & WINDOWSTATUS_DESTROYING) + + pti = Window->Wnd->head.pti; + if ( pti->TIF_flags & TIF_INCLEANUP ) + { + DPRINT1("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd); + return FALSE; + } + + if ( Window->Status & WINDOWSTATUS_DESTROYING ) { DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd); /* FIXME - last error code? */ @@ -1761,6 +1799,9 @@ co_IntDoSendMessage(HWND hWnd, Info.Ansi = !Window->Wnd->Unicode; Info.Proc = Window->Wnd->lpfnWndProc; + // Make the call from here if CALLWNDPROC or CALLWNDPROCRET are hooked + // or just do it in User32! + IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, &Result); } else From db4cbee9dc0c0872b4736ad1073e5cc373c73114 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Tue, 1 Dec 2009 11:48:06 +0000 Subject: [PATCH 123/140] [kernel32] - Fix broken code inside SXS_SUPPORT_ENABLED define and add some DPRINTs. Still unused. svn path=/trunk/; revision=44341 --- reactos/dll/win32/kernel32/thread/thread.c | 72 +++++++++++++--------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/reactos/dll/win32/kernel32/thread/thread.c b/reactos/dll/win32/kernel32/thread/thread.c index 3fb6a6da7e7..8bbe32c7fe0 100644 --- a/reactos/dll/win32/kernel32/thread/thread.c +++ b/reactos/dll/win32/kernel32/thread/thread.c @@ -160,46 +160,60 @@ CreateRemoteThread(HANDLE hProcess, #ifdef SXS_SUPPORT_ENABLED /* Are we in the same process? */ - if (Process = NtCurrentProcess()) + if (hProcess == NtCurrentProcess()) { PTEB Teb; PVOID ActivationContextStack; - PTHREAD_BASIC_INFORMATION ThreadBasicInfo; - PACTIVATION_CONTEXT_BASIC_INFORMATION ActivationCtxInfo; + THREAD_BASIC_INFORMATION ThreadBasicInfo; + ACTIVATION_CONTEXT_BASIC_INFORMATION ActivationCtxInfo; ULONG_PTR Cookie; + ULONG retLen; /* Get the TEB */ Status = NtQueryInformationThread(hThread, - ThreadBasicIformation, + ThreadBasicInformation, &ThreadBasicInfo, sizeof(ThreadBasicInfo), - NULL); - - /* Allocate the Activation Context Stack */ - Status = RtlAllocateActivationContextStack(&ActivationContextStack); - Teb = ThreadBasicInfo.TebBaseAddress; - - /* Save it */ - Teb->ActivationContextStackPointer = ActivationContextStack; - - /* Query the Context */ - Status = RtlQueryInformationActivationContext(1, - 0, - NULL, - ActivationContextBasicInformation, - &ActivationCtxInfo, - sizeof(ActivationCtxInfo), - NULL); - - /* Does it need to be activated? */ - if (!ActivationCtxInfo.hActCtx) + &retLen); + if (NT_SUCCESS(Status)) { - /* Activate it */ - Status = RtlActivateActivationContextEx(1, - Teb, - ActivationCtxInfo.hActCtx, - &Cookie); + /* Allocate the Activation Context Stack */ + Status = RtlAllocateActivationContextStack(&ActivationContextStack); } + + if (NT_SUCCESS(Status)) + { + Teb = ThreadBasicInfo.TebBaseAddress; + + /* Save it */ + Teb->ActivationContextStackPointer = ActivationContextStack; + + /* Query the Context */ + Status = RtlQueryInformationActivationContext(1, + 0, + NULL, + ActivationContextBasicInformation, + &ActivationCtxInfo, + sizeof(ActivationCtxInfo), + &retLen); + if (NT_SUCCESS(Status)) + { + /* Does it need to be activated? */ + if (!ActivationCtxInfo.hActCtx) + { + /* Activate it */ + Status = RtlActivateActivationContext(1, + ActivationCtxInfo.hActCtx, + &Cookie); + if (!NT_SUCCESS(Status)) + DPRINT1("RtlActivateActivationContext failed %x\n", Status); + } + } + else + DPRINT1("RtlQueryInformationActivationContext failed %x\n", Status); + } + else + DPRINT1("RtlAllocateActivationContextStack failed %x\n", Status); } #endif From 26b1e5ce542de2ae97b3ac2cbab8daa448afdaf0 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 1 Dec 2009 18:39:49 +0000 Subject: [PATCH 124/140] Add a root level batch file which allows building reactos without invoking RosBE. It won't currently work without RosBE as it relies in the gcc toolset installed along with RosBE to go about its business. It currently checks for RosBE existence with a rather hackish ^H^H^H^H ... elaborate string parser using the 'reg' command line util output. I'd be happy for anyone to improve on this. svn path=/trunk/; revision=44342 --- reactos/rosbuild.bat | 108 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 reactos/rosbuild.bat diff --git a/reactos/rosbuild.bat b/reactos/rosbuild.bat new file mode 100644 index 00000000000..e985273e907 --- /dev/null +++ b/reactos/rosbuild.bat @@ -0,0 +1,108 @@ +:: +:: Call from Makefile command line within Visual Studio with the following parameters: +:: +:: %1 - $(build) +:: %2 - $(target) +:: +:: Examples: +:: +:: Call build.bat build ntoskrnl +:: Call build.bat clean win32k +:: + +@echo off + +if "%1"=="" goto :err_params +if "%2"=="" goto :err_params + + +:: Get the RosBE path... :: + +:: Set the command we'll use to check if RosBE exists +set _IS_ROSBE_INSTALLED_COMMAND="reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\ReactOS Build Environment for Windows" /v UninstallString" + +:: Check the key actually exists !!!!FIXME: Why is this returning 'The system cannot find the path specified.'!!!! +%_IS_ROSBE_INSTALLED_COMMAND% +IF NOT errorlevel 0 goto :err_no_rosbe + +:: This is a bit hackish. What we do is look for REG_SZ which is the second token on the second line and dump it into i +:: We then assign all remaining text to the next variable in the sequence, which is j. This leaves us with the path +for /F "tokens=2,* skip=1 delims=\ " %%i in ('%_IS_ROSBE_INSTALLED_COMMAND%') do ( + set _ROSBE_UNINSTALL_PATH_=%%j +) + + +:: Now strip the file name from the end of the path and we should have our RosBE install directory +set _ROSBE_PATH_DIR= +set _ROSBE_PATH_= +for %%i in ("%_ROSBE_UNINSTALL_PATH_%") do set _ROSBE_PATH_DIR=%%~di +for %%i in ("%_ROSBE_UNINSTALL_PATH_%") do set "_ROSBE_PATH_=%%~pi" +set "_ROSBE_FULL_PATH_=%_ROSBE_PATH_DIR%%_ROSBE_PATH_%" +::echo RosBE insall path = %_ROSBE_FULL_PATH_% + +:: Set the path which contains our build tools +set _ROSBE_BIN_PATH=%_ROSBE_FULL_PATH_%\i386\bin + +:: Set the make.exe path +set _MAKE_COMMAND=%_ROSBE_BIN_PATH%\mingw32-make.exe + +:: This file is located in the source root +set _ROS_SOURCE_ROOT=%~dp0 + +:: Add the path to the search path +path=%path%;%_ROSBE_BIN_PATH% + +:: Change the current dir to the source root +cd %_ROS_SOURCE_ROOT% + + + +:: Run the requested build task +if "%1" == "build" ( + goto :build +) +if "%1" == "rebuild" ( + goto clean +) +if "%1" == "clean" ( + goto :clean +) +goto :err_params + +:clean +echo. +echo Cleaning... +echo. +call "%_MAKE_COMMAND%" -j 1 %2%_clean + +if "%1" == "rebuild" ( + goto :build +) + +goto :exit + +:build +echo. +echo Building... +echo. +call "%_MAKE_COMMAND%" -j 1 %2% + +goto :exit + + +:err_no_rosbe +echo. +echo You need to have RosBE installed to use this configuration +echo. +exit 1 + +:err_params +echo. +echo Invalid parameters required, Check your command line. +echo. +exit 2 + +:exit +echo. +echo done +echo. \ No newline at end of file From 9d7f91d6cae0bb1c1519e5a47685ca7717edf6cc Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 1 Dec 2009 18:44:16 +0000 Subject: [PATCH 125/140] - Include support for makefile configurations. - Add a new makefile config to the global configuration called RosBuild - Use the new makefile config to process and external batch file which make use of rbuild. - Split and partially rewrite _generate_vcproj. Configurations are now written in support functions. - Remove the creation of .vcproj.user files. They're rather pointless for our needs - Start to add support for VS2010 (make msvc10), it's very incomplete at the moment so don't bother trying it. After this commit, you can now use Visual Studio to build individual reactos components. Run 'make msvc9', open up any vcproj file, select the RosBuild config and hit the build/rebuild button. Working build features are 'build', 'rebuild' and 'clean' svn path=/trunk/; revision=44343 --- reactos/tools/rbuild/backend/msvc/msvc.cpp | 11 +- reactos/tools/rbuild/backend/msvc/msvc.h | 38 +- .../tools/rbuild/backend/msvc/vcprojmaker.cpp | 963 ++++++++++-------- .../rbuild/backend/msvc/vcxprojmaker.cpp | 177 ++++ reactos/tools/rbuild/rbuild.mak | 5 + reactos/tools/rbuild/rbuild.sln | 4 +- reactos/tools/rbuild/rbuild.vcproj | 17 +- 7 files changed, 784 insertions(+), 431 deletions(-) create mode 100644 reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp diff --git a/reactos/tools/rbuild/backend/msvc/msvc.cpp b/reactos/tools/rbuild/backend/msvc/msvc.cpp index 31c638a1d72..08c0479f6b7 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.cpp +++ b/reactos/tools/rbuild/backend/msvc/msvc.cpp @@ -70,6 +70,7 @@ void MSVCBackend::Process() m_configurations.push_back ( new MSVCConfiguration( Debug )); m_configurations.push_back ( new MSVCConfiguration( Release )); m_configurations.push_back ( new MSVCConfiguration( Speed )); + m_configurations.push_back ( new MSVCConfiguration( RosBuild )); if (!only_msvc_headers) { @@ -123,6 +124,8 @@ void MSVCBackend::ProcessModules() if (configuration.VSProjectVersion == "6.00") _generate_dsp ( module ); + else if (configuration.VSProjectVersion == "10.00") + _generate_vcxproj ( module ); else _generate_vcproj ( module ); } @@ -285,10 +288,12 @@ std::string MSVCBackend::_get_vc_dir ( void ) const return "vc70"; else if ( configuration.VSProjectVersion == "7.10" ) return "vc71"; - else if ( configuration.VSProjectVersion == "9.00" ) - return "vc9"; - else /* must be VS2005 */ + else if ( configuration.VSProjectVersion == "8.00" ) return "vc8"; + else if ( configuration.VSProjectVersion == "10.00" ) + return "vc10"; + else /* default to VS2008 */ + return "vc9"; } diff --git a/reactos/tools/rbuild/backend/msvc/msvc.h b/reactos/tools/rbuild/backend/msvc/msvc.h index 19845f6a6cd..8f3f3a88ec3 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.h +++ b/reactos/tools/rbuild/backend/msvc/msvc.h @@ -25,6 +25,7 @@ #include "../backend.h" + class FileUnit { public: @@ -34,9 +35,28 @@ class FileUnit enum OptimizationType { + RosBuild, Debug, Release, - Speed + Speed, +}; + +enum ConfigurationType +{ + ConfigUnknown, + ConfigApp, + ConfigDll, + ConfigEmpty, + ConfigLib +}; + +enum BinaryType +{ + BinUnknown, + Lib, + Dll, + Exe, + Sys }; enum HeadersType @@ -123,7 +143,23 @@ class MSVCBackend : public Backend std::string _get_vc_dir ( void ) const; + // These are used in both _generate_vcproj and _generate_standard_configuration + std::vector header_files; + std::vector includes; + std::vector includes_ros; + std::vector libraries; + std::set common_defines; + std::string baseaddr; + + void _generate_standard_configuration( + FILE* OUT, + const Module& module, + const MSVCConfiguration& cfg, + BinaryType binaryType ); + void _generate_makefile_configuration( FILE* OUT, const Module& module, const MSVCConfiguration& cfg ); + void _generate_vcproj ( const Module& module ); + void _generate_vcxproj ( const Module& module ); void _generate_sln_header ( FILE* OUT ); void _generate_sln_footer ( FILE* OUT ); diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index 812e11c4b0e..2d143af44a7 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -3,6 +3,7 @@ * Copyright (C) 2005 Royce Mitchell III * Copyright (C) 2006 Hervé Poussineau * Copyright (C) 2006 Christoph von Wittich + * Copyright (C) 2009 Ged Murphy * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -71,6 +72,8 @@ MSVCConfiguration::MSVCConfiguration ( const OptimizationType optimization, cons this->name = "Release" + headers_name; else if ( optimization == Speed ) this->name = "Speed" + headers_name; + else if ( optimization == RosBuild ) + this->name = "RosBuild"; else this->name = "Unknown" + headers_name; } @@ -84,7 +87,13 @@ MSVCBackend::_generate_vcproj ( const Module& module ) string vcproj_file = VcprojFileName(module); string computername; string username; - string intermediatedir = ""; + + // make sure the containers are empty + header_files.clear(); + includes.clear(); + includes_ros.clear(); + libraries.clear(); + common_defines.clear(); if (getenv ( "USERNAME" ) != NULL) username = getenv ( "USERNAME" ); @@ -101,13 +110,6 @@ MSVCBackend::_generate_vcproj ( const Module& module ) printf ( "Creating MSVC.NET project: '%s'\n", vcproj_file.c_str() ); FILE* OUT = fopen ( vcproj_file.c_str(), "wb" ); - vector imports; - string module_type = GetExtension(*module.output); - bool lib = (module.type == ObjectLibrary) || (module.type == RpcClient) ||(module.type == RpcServer) || (module_type == ".lib") || (module_type == ".a"); - bool dll = (module_type == ".dll") || (module_type == ".cpl"); - bool exe = (module_type == ".exe") || (module_type == ".scr"); - bool sys = (module_type == ".sys"); - string path_basedir = module.GetPathToBaseDir (); string intenv = Environment::GetIntermediatePath (); string outenv = Environment::GetOutputPath (); @@ -115,7 +117,6 @@ MSVCBackend::_generate_vcproj ( const Module& module ) string intdir; string vcdir; - if ( intenv == "obj-i386" ) intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ else @@ -130,19 +131,14 @@ MSVCBackend::_generate_vcproj ( const Module& module ) { vcdir = DEF_SSEP + _get_vc_dir(); } - // TODO FIXME - need more checks here for 'sys' and possibly 'drv'? - bool console = exe && (module.type == Win32CUI); bool include_idl = false; - vector source_files, resource_files, header_files, includes, includes_ros, libraries; - StringSet common_defines; + vector source_files, resource_files; vector ifs_list; ifs_list.push_back ( &module.project.non_if_data ); ifs_list.push_back ( &module.non_if_data ); - string baseaddr; - while ( ifs_list.size() ) { const IfableData& data = *ifs_list.back(); @@ -245,417 +241,38 @@ MSVCBackend::_generate_vcproj ( const Module& module ) fprintf ( OUT, "\t\t\tName=\"Win32\"/>\r\n" ); fprintf ( OUT, "\t\r\n" ); - //fprintf ( OUT, "\t\r\n" ); - //fprintf ( OUT, "\t\t\r\n", path.c_str() ); - //fprintf ( OUT, "\t\r\n" ); - - int n = 0; - - std::string output_dir; - string importLib; - - // don't do the work m_configurations.size() times - if (module.importLibrary != NULL) - { - intermediatedir = module.output->relative_path + vcdir; - importLib = _strip_gcc_deffile(module.importLibrary->source->name, module.importLibrary->source->relative_path, intermediatedir); - importLib = Path::RelativeFromDirectory ( - importLib, - module.output->relative_path ); - } + // Set the binary type + string module_type = GetExtension(*module.output); + BinaryType binaryType; + if ((module.type == ObjectLibrary) || (module.type == RpcClient) ||(module.type == RpcServer) || (module_type == ".lib") || (module_type == ".a")) + binaryType = Lib; + else if ((module_type == ".dll") || (module_type == ".cpl")) + binaryType = Dll; + else if ((module_type == ".exe") || (module_type == ".scr")) + binaryType = Exe; + else if (module_type == ".sys") + binaryType = Sys; + else + binaryType = BinUnknown; + // Write out all the configurations fprintf ( OUT, "\t\r\n" ); for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) { const MSVCConfiguration& cfg = *m_configurations[icfg]; - bool debug = ( cfg.optimization == Debug ); - bool release = ( cfg.optimization == Release ); - bool speed = ( cfg.optimization == Speed ); - - fprintf ( OUT, "\t\trelative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); - fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); + _generate_makefile_configuration( OUT, module, cfg ); } else { - fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); - fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); + _generate_standard_configuration( OUT, module, cfg, binaryType ); } - - fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", exe ? 1 : dll ? 2 : lib ? 4 : -1 ); - fprintf ( OUT, "\t\t\tCharacterSet=\"2\">\r\n" ); - - fprintf ( OUT, "\t\t\t 0 ) - fprintf ( OUT, ";" ); - - string unescaped = *it1; - fprintf ( OUT, "%s", _replace_str(unescaped, "\"","").c_str() ); - } - fprintf ( OUT, "\"\r\n" ); - fprintf ( OUT, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h"); - fprintf ( OUT, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed ? "TRUE" : "FALSE" ); - fprintf ( OUT, "\t\t\t\tBasicRuntimeChecks=\"0\"\r\n" ); - fprintf ( OUT, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug ? 3 : 2 ); // 3=/MDd 2=/MD - fprintf ( OUT, "\t\t\t\tBufferSecurityCheck=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" ); - - if ( module.pch != NULL ) - { - fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" ); - string pch_path = Path::RelativeFromDirectory ( - module.pch->file->name, - module.output->relative_path ); - string::size_type pos = pch_path.find_last_of ("/"); - if ( pos != string::npos ) - pch_path.erase(0, pos+1); - fprintf ( OUT, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path.c_str() ); - - // Only include from the same module - pos = pch_path.find("../"); - if (pos == string::npos && std::find(header_files.begin(), header_files.end(), pch_path) == header_files.end()) - header_files.push_back(pch_path); - } - else - { - fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" ); - } - - fprintf ( OUT, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release ? "FALSE" : "FALSE"); - if ( release ) - { - fprintf ( OUT, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" ); - fprintf ( OUT, "\t\t\t\tStringPooling=\"true\"\r\n" ); - } - - fprintf ( OUT, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed ? "0" : "3" ); - fprintf ( OUT, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE"); - if ( !module.cplusplus ) - fprintf ( OUT, "\t\t\t\tCompileAs=\"1\"\r\n" ); - - if ( module.type == Win32CUI || module.type == Win32GUI ) - { - fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 ); // 0=__cdecl - } - else - { - fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 ); // 2=__stdcall - } - - fprintf ( OUT, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed ? "0" : release ? "3": "4"); // 3=/Zi 4=ZI - - fprintf ( OUT, "\t\t\t\r\n" ); - - if ( lib ) - { - fprintf ( OUT, "\t\t\t\r\n", module.name.c_str() ); - } - else - { - fprintf ( OUT, "\t\t\t 0 ) - fprintf ( OUT, " " ); - string libpath = libraries[i].c_str(); - libpath = libpath.erase (0, libpath.find_last_of ("\\") + 1 ); - if ( libpath == "msvcrt.lib" ) - { - use_msvcrt_lib = true; - } - fprintf ( OUT, "%s", libpath.c_str() ); - } - fprintf ( OUT, "\"\r\n" ); - - fprintf ( OUT, "\t\t\t\tAdditionalLibraryDirectories=\"" ); - - // Add WDK libs paths, if needed - if (getenv ( "BASEDIR" ) != NULL && - (module.type == Kernel || - module.type == KernelModeDLL || - module.type == KernelModeDriver || - module.type == KeyboardLayout)) - { - string WdkBase, CrtPath, DdkPath; - WdkBase = getenv ( "BASEDIR" ); - CrtPath = WdkBase + "\\lib\\crt\\i386"; - DdkPath = WdkBase + "\\lib\\wnet\\i386"; - - fprintf ( OUT, "%s;", CrtPath.c_str() ); - fprintf ( OUT, "%s", DdkPath.c_str() ); - - if (libraries.size () > 0) - fprintf ( OUT, ";" ); - } - - // Add conventional libraries dirs - for (i = 0; i < libraries.size (); i++) - { - if ( i > 0 ) - fprintf ( OUT, ";" ); - - string libpath = libraries[i].c_str(); - libpath.replace (libpath.find("---"), 3, cfg.name); - libpath = libpath.substr (0, libpath.find_last_of ("\\") ); - fprintf ( OUT, "%s", libpath.c_str() ); - } - - fprintf ( OUT, "\"\r\n" ); - - fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() ); - fprintf ( OUT, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 ); - fprintf ( OUT, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" ); - fprintf ( OUT, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 0 : 0); // whole program optimization - - if ( debug ) - fprintf ( OUT, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module.name.c_str() ); - - if ( sys ) - { - if (module.GetEntryPoint() == "0") - fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /noentry /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" ); - else - fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" ); - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 ); - fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 ); - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint() == "" ? "DriverEntry" : module.GetEntryPoint().c_str ()); - fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x10000" : baseaddr.c_str ()); - } - else if ( exe ) - { - if ( module.type == Kernel ) - { - fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" ); - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 ); - fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 ); - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" ); - fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ()); - } - else if ( module.type == NativeCUI ) - { - fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" ); - fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 ); - fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" ); - fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ()); - } - else if ( module.type == Win32CUI || module.type == Win32GUI || module.type == Win32SCR) - { - if ( use_msvcrt_lib ) - { - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - } - fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", console ? 1 : 2 ); - } - } - else if ( dll ) - { - if (module.GetEntryPoint() == "0") - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" ); - else - { - // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12 - // when using CRT - if (module.GetEntryPoint() == "DllMain@12") - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" ); - else - fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint().c_str ()); - } - fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x40000" : baseaddr.c_str ()); - if ( use_msvcrt_lib ) - { - fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); - } - } - fprintf ( OUT, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 ); - } - - fprintf ( OUT, "\t\t\t\r\n " ); - - fprintf ( OUT, "\t\t\t\r\n" ); - if (configuration.VSProjectVersion == "8.00") - { - fprintf ( OUT, "\t\t\t\r\n" ); - } - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\r\n" ); - - n++; } fprintf ( OUT, "\t\r\n" ); + // Write out the project files fprintf ( OUT, "\t\r\n" ); // Source files @@ -825,6 +442,7 @@ MSVCBackend::_generate_vcproj ( const Module& module ) fprintf ( OUT, "\r\n" ); fclose ( OUT ); +#if 0 /* User configuration file */ if (vcproj_file_user != "") { @@ -881,9 +499,511 @@ MSVCBackend::_generate_vcproj ( const Module& module ) fprintf ( OUT, "\r\n" ); fclose ( OUT ); } - +#endif } +void MSVCBackend::_generate_standard_configuration( FILE* OUT, + const Module& module, + const MSVCConfiguration& cfg, + BinaryType binaryType ) +{ + string path_basedir = module.GetPathToBaseDir (); + string intenv = Environment::GetIntermediatePath (); + string outenv = Environment::GetOutputPath (); + string outdir; + string intdir; + string vcdir; + + bool debug = ( cfg.optimization == Debug ); + bool release = ( cfg.optimization == Release ); + bool speed = ( cfg.optimization == Speed ); + + bool include_idl = false; + string include_string; + + size_t i; + string intermediatedir = ""; + string importLib; + // don't do the work m_configurations.size() times + if (module.importLibrary != NULL) + { + intermediatedir = module.output->relative_path + vcdir; + importLib = _strip_gcc_deffile(module.importLibrary->source->name, module.importLibrary->source->relative_path, intermediatedir); + importLib = Path::RelativeFromDirectory ( + importLib, + module.output->relative_path ); + } + + string module_type = GetExtension(*module.output); + + // Set the configuration type for this config + ConfigurationType CfgType; + if ( binaryType == Exe ) + CfgType = ConfigApp; + else if ( binaryType == Lib ) + CfgType = ConfigLib; + else if ( binaryType == Dll || binaryType == Sys ) + CfgType = ConfigDll; + else + CfgType = ConfigUnknown; + + + if ( intenv == "obj-i386" ) + intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ + else + intdir = intenv; + + if ( outenv == "output-i386" ) + outdir = path_basedir + "output-i386"; + else + outdir = outenv; + + if ( configuration.UseVSVersionInPath ) + { + vcdir = DEF_SSEP + _get_vc_dir(); + } + + fprintf ( OUT, "\t\trelative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); + } + else + { + fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); + } + + fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", CfgType ); + fprintf ( OUT, "\t\t\tCharacterSet=\"2\"\r\n" ); + fprintf ( OUT, "\t\t\t>\r\n" ); + + fprintf ( OUT, "\t\t\t 0 ) + fprintf ( OUT, ";" ); + + string unescaped = *it1; + fprintf ( OUT, "%s", _replace_str(unescaped, "\"","").c_str() ); + } + fprintf ( OUT, "\"\r\n" ); + fprintf ( OUT, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h"); + fprintf ( OUT, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed ? "TRUE" : "FALSE" ); + fprintf ( OUT, "\t\t\t\tBasicRuntimeChecks=\"0\"\r\n" ); + fprintf ( OUT, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug ? 3 : 2 ); // 3=/MDd 2=/MD + fprintf ( OUT, "\t\t\t\tBufferSecurityCheck=\"FALSE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" ); + + if ( module.pch != NULL ) + { + fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" ); + string pch_path = Path::RelativeFromDirectory ( + module.pch->file->name, + module.output->relative_path ); + string::size_type pos = pch_path.find_last_of ("/"); + if ( pos != string::npos ) + pch_path.erase(0, pos+1); + fprintf ( OUT, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path.c_str() ); + + // Only include from the same module + pos = pch_path.find("../"); + if (pos == string::npos && std::find(header_files.begin(), header_files.end(), pch_path) == header_files.end()) + header_files.push_back(pch_path); + } + else + { + fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" ); + } + + fprintf ( OUT, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release ? "FALSE" : "FALSE"); + if ( release ) + { + fprintf ( OUT, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" ); + fprintf ( OUT, "\t\t\t\tStringPooling=\"true\"\r\n" ); + } + + fprintf ( OUT, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed ? "0" : "3" ); + fprintf ( OUT, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE"); + if ( !module.cplusplus ) + fprintf ( OUT, "\t\t\t\tCompileAs=\"1\"\r\n" ); + + if ( module.type == Win32CUI || module.type == Win32GUI ) + { + fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 ); // 0=__cdecl + } + else + { + fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 ); // 2=__stdcall + } + + fprintf ( OUT, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed ? "0" : release ? "3": "4"); // 3=/Zi 4=ZI + + fprintf ( OUT, "\t\t\t\r\n" ); + + if ( binaryType == Lib ) + { + fprintf ( OUT, "\t\t\t\r\n", module.name.c_str() ); + } + else + { + fprintf ( OUT, "\t\t\t 0 ) + fprintf ( OUT, " " ); + string libpath = libraries[i].c_str(); + libpath = libpath.erase (0, libpath.find_last_of ("\\") + 1 ); + if ( libpath == "msvcrt.lib" ) + { + use_msvcrt_lib = true; + } + fprintf ( OUT, "%s", libpath.c_str() ); + } + fprintf ( OUT, "\"\r\n" ); + + fprintf ( OUT, "\t\t\t\tAdditionalLibraryDirectories=\"" ); + + // Add WDK libs paths, if needed + if (getenv ( "BASEDIR" ) != NULL && + (module.type == Kernel || + module.type == KernelModeDLL || + module.type == KernelModeDriver || + module.type == KeyboardLayout)) + { + string WdkBase, CrtPath, DdkPath; + WdkBase = getenv ( "BASEDIR" ); + CrtPath = WdkBase + "\\lib\\crt\\i386"; + DdkPath = WdkBase + "\\lib\\wnet\\i386"; + + fprintf ( OUT, "%s;", CrtPath.c_str() ); + fprintf ( OUT, "%s", DdkPath.c_str() ); + + if (libraries.size () > 0) + fprintf ( OUT, ";" ); + } + + // Add conventional libraries dirs + for (i = 0; i < libraries.size (); i++) + { + if ( i > 0 ) + fprintf ( OUT, ";" ); + + string libpath = libraries[i].c_str(); + libpath.replace (libpath.find("---"), 3, cfg.name); + libpath = libpath.substr (0, libpath.find_last_of ("\\") ); + fprintf ( OUT, "%s", libpath.c_str() ); + } + + fprintf ( OUT, "\"\r\n" ); + + fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() ); + fprintf ( OUT, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 ); + fprintf ( OUT, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" ); + fprintf ( OUT, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 0 : 0); // whole program optimization + + if ( debug ) + fprintf ( OUT, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module.name.c_str() ); + + if ( binaryType == Sys ) + { + if (module.GetEntryPoint() == "0") + fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /noentry /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" ); + else + fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20 /SECTION:INIT,D /IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096\"\r\n" ); + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 ); + fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 ); + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint() == "" ? "DriverEntry" : module.GetEntryPoint().c_str ()); + fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x10000" : baseaddr.c_str ()); + } + else if ( binaryType == Exe ) + { + if ( module.type == Kernel ) + { + fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /SECTION:INIT,D /ALIGN:0x80\"\r\n" ); + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 3 ); + fprintf ( OUT, "\t\t\t\tDriver=\"%d\"\r\n", 1 ); + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"KiSystemStartup\"\r\n" ); + fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ()); + } + else if ( module.type == NativeCUI ) + { + fprintf ( OUT, "\t\t\t\tAdditionalOptions=\" /ALIGN:0x20\"\r\n" ); + fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 1 ); + fprintf ( OUT, "\t\t\t\tGenerateManifest=\"FALSE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"NtProcessStartup\"\r\n" ); + fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr.c_str ()); + } + else if ( module.type == Win32CUI || module.type == Win32GUI || module.type == Win32SCR) + { + if ( use_msvcrt_lib ) + { + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + } + fprintf ( OUT, "\t\t\t\tSubSystem=\"%d\"\r\n", 2 ); + } + } + else if ( binaryType == Dll ) + { + if (module.GetEntryPoint() == "0") + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" ); + else + { + // get rid of DllMain@12 because MSVC needs to link to _DllMainCRTStartup@12 + // when using CRT + if (module.GetEntryPoint() == "DllMain@12") + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"\"\r\n" ); + else + fprintf ( OUT, "\t\t\t\tEntryPointSymbol=\"%s\"\r\n", module.GetEntryPoint().c_str ()); + } + fprintf ( OUT, "\t\t\t\tBaseAddress=\"%s\"\r\n", baseaddr == "" ? "0x40000" : baseaddr.c_str ()); + if ( use_msvcrt_lib ) + { + fprintf ( OUT, "\t\t\t\tIgnoreAllDefaultLibraries=\"TRUE\"\r\n" ); + } + } + fprintf ( OUT, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 ); + } + + fprintf ( OUT, "\t\t\t\r\n " ); + + fprintf ( OUT, "\t\t\t\r\n" ); + if (configuration.VSProjectVersion == "8.00") + { + fprintf ( OUT, "\t\t\t\r\n" ); + } + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); +} + + +void +MSVCBackend::_generate_makefile_configuration( FILE* OUT, const Module& module, const MSVCConfiguration& cfg ) +{ + string path_basedir = module.GetPathToBaseDir (); + string intenv = Environment::GetIntermediatePath (); + string outenv = Environment::GetOutputPath (); + + string outdir; + string intdir; + string vcdir; + + + if ( intenv == "obj-i386" ) + intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ + else + intdir = intenv; + + if ( outenv == "output-i386" ) + outdir = path_basedir + "output-i386"; + else + outdir = outenv; + + if ( configuration.UseVSVersionInPath ) + { + vcdir = DEF_SSEP + _get_vc_dir(); + } + + fprintf ( OUT, "\t\trelative_path.c_str (), cfg.name.c_str() ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), cfg.name.c_str() ); + } + else + { + fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str () ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str () ); + } + + fprintf ( OUT, "\t\t\tConfigurationType=\"0\"\r\n"); + fprintf ( OUT, "\t\t\t>\r\n" ); + + fprintf ( OUT, "\t\t\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); +} + + std::string MSVCBackend::_strip_gcc_deffile(std::string Filename, std::string sourcedir, std::string objdir) { @@ -969,6 +1089,9 @@ MSVCBackend::_get_solution_version ( void ) else if (configuration.VSProjectVersion == "9.00") version = "10.00"; + else if (configuration.VSProjectVersion == "10.00") + version = "11.00"; + return version; } @@ -992,6 +1115,9 @@ MSVCBackend::_get_studio_version ( void ) else if (configuration.VSProjectVersion == "9.00") version = "2008"; + else if (configuration.VSProjectVersion == "10.00") + version = "2010"; + return version; } @@ -1037,11 +1163,12 @@ void MSVCBackend::_generate_sln_footer ( FILE* OUT ) { fprintf ( OUT, "Global\r\n" ); - fprintf ( OUT, "\tGlobalSection(SolutionConfiguration) = preSolution\r\n" ); + fprintf ( OUT, "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n" ); for ( size_t i = 0; i < m_configurations.size(); i++ ) fprintf ( OUT, "\t\t%s = %s\r\n", m_configurations[i]->name.c_str(), m_configurations[i]->name.c_str() ); fprintf ( OUT, "\tEndGlobalSection\r\n" ); - fprintf ( OUT, "\tGlobalSection(ProjectConfiguration) = postSolution\r\n" ); + + fprintf ( OUT, "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n" ); for( std::map::const_iterator p = ProjectNode.modules.begin(); p != ProjectNode.modules.end(); ++ p ) { Module& module = *p->second; @@ -1049,18 +1176,18 @@ MSVCBackend::_generate_sln_footer ( FILE* OUT ) _generate_sln_configurations ( OUT, guid.c_str() ); } fprintf ( OUT, "\tEndGlobalSection\r\n" ); +/* fprintf ( OUT, "\tGlobalSection(ExtensibilityGlobals) = postSolution\r\n" ); fprintf ( OUT, "\tEndGlobalSection\r\n" ); fprintf ( OUT, "\tGlobalSection(ExtensibilityAddIns) = postSolution\r\n" ); fprintf ( OUT, "\tEndGlobalSection\r\n" ); - +*/ if (configuration.VSProjectVersion == "7.00") { fprintf ( OUT, "\tGlobalSection(ProjectDependencies) = postSolution\r\n" ); //FIXME: Add dependencies for VS 2002 fprintf ( OUT, "\tEndGlobalSection\r\n" ); } - - if (configuration.VSProjectVersion == "8.00") { + else { fprintf ( OUT, "\tGlobalSection(SolutionProperties) = preSolution\r\n" ); fprintf ( OUT, "\t\tHideSolutionNode = FALSE\r\n" ); fprintf ( OUT, "\tEndGlobalSection\r\n" ); diff --git a/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp new file mode 100644 index 00000000000..c8d9fc03eb1 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/vcxprojmaker.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2009 Ged Murphy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "msvc.h" + +using std::string; +using std::vector; +using std::set; + +typedef set StringSet; + +#ifdef OUT +#undef OUT +#endif//OUT + +void +MSVCBackend::_generate_vcxproj ( const Module& module ) +{ + size_t i; + + string vcproj_file = VcprojFileName(module); + string computername; + string username; + string intermediatedir = ""; + + if (getenv ( "USERNAME" ) != NULL) + username = getenv ( "USERNAME" ); + if (getenv ( "COMPUTERNAME" ) != NULL) + computername = getenv ( "COMPUTERNAME" ); + else if (getenv ( "HOSTNAME" ) != NULL) + computername = getenv ( "HOSTNAME" ); + + printf ( "Creating MSVC project: '%s'\n", vcproj_file.c_str() ); + FILE* OUT = fopen ( vcproj_file.c_str(), "wb" ); + + string path_basedir = module.GetPathToBaseDir (); + string intenv = Environment::GetIntermediatePath (); + string outenv = Environment::GetOutputPath (); + string outdir; + string intdir; + string vcdir; + + if ( intenv == "obj-i386" ) + intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ + else + intdir = intenv; + + if ( outenv == "output-i386" ) + outdir = path_basedir + "output-i386"; + else + outdir = outenv; + + if ( configuration.UseVSVersionInPath ) + { + vcdir = DEF_SSEP + _get_vc_dir(); + } + + + + bool include_idl = false; + + vector source_files, resource_files; + vector ifs_list; + ifs_list.push_back ( &module.project.non_if_data ); + ifs_list.push_back ( &module.non_if_data ); + + while ( ifs_list.size() ) + { + const IfableData& data = *ifs_list.back(); + ifs_list.pop_back(); + const vector& files = data.files; + for ( i = 0; i < files.size(); i++ ) + { + if (files[i]->file.directory != SourceDirectory) + continue; + + // We want the full path here for directory support later on + string path = Path::RelativeFromDirectory ( + files[i]->file.relative_path, + module.output->relative_path ); + string file = path + std::string("\\") + files[i]->file.name; + + if ( !stricmp ( Right(file,3).c_str(), ".rc" ) ) + resource_files.push_back ( file ); + else if ( !stricmp ( Right(file,2).c_str(), ".h" ) ) + header_files.push_back ( file ); + else + source_files.push_back ( file ); + } + const vector& incs = data.includes; + for ( i = 0; i < incs.size(); i++ ) + { + string path = Path::RelativeFromDirectory ( + incs[i]->directory->relative_path, + module.output->relative_path ); + if ( module.type != RpcServer && module.type != RpcClient ) + { + if ( path.find ("/include/reactos/idl") != string::npos) + { + include_idl = true; + continue; + } + } + // switch between general headers and ros headers + if ( !strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 ) || + !strncmp(incs[i]->directory->relative_path.c_str(), "include\\ddk", 11 ) || + !strncmp(incs[i]->directory->relative_path.c_str(), "include\\GL", 10 ) || + !strncmp(incs[i]->directory->relative_path.c_str(), "include\\psdk", 12 ) || + !strncmp(incs[i]->directory->relative_path.c_str(), "include\\reactos\\wine", 20 ) ) + { + if (strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 )) + // not crt include + includes_ros.push_back ( path ); + } + else + { + includes.push_back ( path ); + } + } + const vector& libs = data.libraries; + for ( i = 0; i < libs.size(); i++ ) + { + string libpath = outdir + "\\" + libs[i]->importedModule->output->relative_path + "\\" + _get_vc_dir() + "\\---\\" + libs[i]->name + ".lib"; + libraries.push_back ( libpath ); + } + const vector& defs = data.defines; + for ( i = 0; i < defs.size(); i++ ) + { + if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) + continue; + + if ( defs[i]->value[0] ) + common_defines.insert( defs[i]->name + "=" + defs[i]->value ); + else + common_defines.insert( defs[i]->name ); + } + for ( std::map::const_iterator p = data.properties.begin(); p != data.properties.end(); ++ p ) + { + Property& prop = *p->second; + if ( strstr ( module.baseaddress.c_str(), prop.name.c_str() ) ) + baseaddr = prop.value; + } + } + /* include intermediate path for reactos.rc */ + string version = intdir + "\\include"; + includes.push_back (version); + version += "\\reactos"; + includes.push_back (version); + + string include_string; + + fprintf ( OUT, "\r\n" ); +} diff --git a/reactos/tools/rbuild/rbuild.mak b/reactos/tools/rbuild/rbuild.mak index 1a393649964..c05e9e17ffc 100644 --- a/reactos/tools/rbuild/rbuild.mak +++ b/reactos/tools/rbuild/rbuild.mak @@ -229,6 +229,7 @@ RBUILD_BACKEND_MSVC_BASE_SOURCES = $(addprefix $(RBUILD_MSVC_BASE_), \ msvc.cpp \ msvcmaker.cpp \ vcprojmaker.cpp \ + vcxprojmaker.cpp \ ) RBUILD_BACKEND_SOURCES = \ @@ -530,6 +531,10 @@ $(RBUILD_MSVC_INT_)vcprojmaker.o: $(RBUILD_MSVC_BASE_)vcprojmaker.cpp $(RBUILD_H $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ +$(RBUILD_MSVC_INT_)vcxprojmaker.o: $(RBUILD_MSVC_BASE_)vcxprojmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) + $(ECHO_HOSTCC) + ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ + $(RBUILD_TEST_TARGET): $(RBUILD_TEST_OBJECTS) $(INFLIB_HOST_OBJECTS) $(RBUILD_HEADERS) | $(RBUILD_OUT) $(ECHO_HOSTLD) ${host_gpp} $(RBUILD_TEST_OBJECTS) $(INFLIB_HOST_OBJECTS) $(RBUILD_HOST_LFLAGS) -o $@ diff --git a/reactos/tools/rbuild/rbuild.sln b/reactos/tools/rbuild/rbuild.sln index 0f9164398e8..01a7baa7830 100644 --- a/reactos/tools/rbuild/rbuild.sln +++ b/reactos/tools/rbuild/rbuild.sln @@ -1,5 +1,5 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rbuild", "rbuild.vcproj", "{D9305AFB-499E-49F1-A865-99DD7E19E762}" EndProject Global diff --git a/reactos/tools/rbuild/rbuild.vcproj b/reactos/tools/rbuild/rbuild.vcproj index 1e800a44b9d..59f90ad1a8a 100644 --- a/reactos/tools/rbuild/rbuild.vcproj +++ b/reactos/tools/rbuild/rbuild.vcproj @@ -1,10 +1,11 @@ - @@ -166,6 +166,8 @@ GenerateDebugInformation="true" ProgramDatabaseFile=".\Debug/rbuild.pdb" SubSystem="1" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" TargetMachine="1" /> - @@ -335,6 +334,10 @@ /> + + Date: Tue, 1 Dec 2009 18:46:13 +0000 Subject: [PATCH 126/140] [ntdll] - Logic change of r37554 is correct, RtlTimeFieldsToTime doesn't normalize invalid input values - remove these codes - Related to bug #4917, part 1 svn path=/trunk/; revision=44344 --- reactos/lib/rtl/time.c | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/reactos/lib/rtl/time.c b/reactos/lib/rtl/time.c index 1ae111b0be9..1b0b6c5e3f7 100644 --- a/reactos/lib/rtl/time.c +++ b/reactos/lib/rtl/time.c @@ -61,14 +61,6 @@ static int DaysSinceEpoch(int Year) return Days; } -static __inline void NormalizeTimeFields(CSHORT *FieldToNormalize, - CSHORT *CarryField, - int Modulus) -{ - *FieldToNormalize = (CSHORT) (*FieldToNormalize - Modulus); - *CarryField = (CSHORT) (*CarryField + 1); -} - /* FUNCTIONS *****************************************************************/ /* @@ -199,39 +191,6 @@ RtlTimeFieldsToTime( return FALSE; } - /* Normalize the TIME_FIELDS structure here */ - while (IntTimeFields.Second >= SECSPERMIN) - { - NormalizeTimeFields(&IntTimeFields.Second, - &IntTimeFields.Minute, - SECSPERMIN); - } - while (IntTimeFields.Minute >= MINSPERHOUR) - { - NormalizeTimeFields(&IntTimeFields.Minute, - &IntTimeFields.Hour, - MINSPERHOUR); - } - while (IntTimeFields.Hour >= HOURSPERDAY) - { - NormalizeTimeFields(&IntTimeFields.Hour, - &IntTimeFields.Day, - HOURSPERDAY); - } - while (IntTimeFields.Day > - MonthLengths[IsLeapYear(IntTimeFields.Year)][IntTimeFields.Month - 1]) - { - NormalizeTimeFields(&IntTimeFields.Day, - &IntTimeFields.Month, - SECSPERMIN); - } - while (IntTimeFields.Month > MONSPERYEAR) - { - NormalizeTimeFields(&IntTimeFields.Month, - &IntTimeFields.Year, - MONSPERYEAR); - } - /* Compute the time */ Time->QuadPart = DaysSinceEpoch(IntTimeFields.Year); for (CurMonth = 1; CurMonth < IntTimeFields.Month; CurMonth++) From fb3101148fc1fe13477057f147e84acd274ca9ff Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Tue, 1 Dec 2009 18:53:01 +0000 Subject: [PATCH 127/140] [kernel] - Fail in DosDateTimeToFileTime if prior time conversion was unsuccessful - Should fix the NetStats installation, bug #4917, part 2 svn path=/trunk/; revision=44345 --- reactos/dll/win32/kernel32/misc/time.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/kernel32/misc/time.c b/reactos/dll/win32/kernel32/misc/time.c index 2eb8eb4d702..5912cfc823b 100644 --- a/reactos/dll/win32/kernel32/misc/time.c +++ b/reactos/dll/win32/kernel32/misc/time.c @@ -318,7 +318,10 @@ DosDateTimeToFileTime(WORD wFatDate, SystemTime.wMonth = pddate->Month; SystemTime.wYear = 1980 + pddate->Year; - SystemTimeToFileTime(&SystemTime,lpFileTime); + if (SystemTimeToFileTime(&SystemTime, lpFileTime) == FALSE) + { + return FALSE; + } return TRUE; } From e1176344d4634517039896cebafdaf18db9edc52 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 1 Dec 2009 18:56:05 +0000 Subject: [PATCH 128/140] Add the msvc10 makefile changes svn path=/trunk/; revision=44346 --- reactos/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/reactos/Makefile b/reactos/Makefile index a2a184725ae..6a159e360fc 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -529,6 +529,11 @@ msvc9: $(ROS_BUILDENGINE) $(ECHO_RBUILD) $(Q)$(ROS_BUILDENGINE) $(RBUILD_FLAGS) $(ROS_RBUILDFLAGS) -vs9.00 -voversionconfiguration msvc +.PHONY: msvc10 +msvc10: $(ROS_BUILDENGINE) + $(ECHO_RBUILD) + $(Q)$(ROS_BUILDENGINE) $(RBUILD_FLAGS) $(ROS_RBUILDFLAGS) -vs10.00 -voversionconfiguration msvc + .PHONY: msvc6_clean msvc6_clean: $(ROS_BUILDENGINE) $(ECHO_RBUILD) @@ -554,6 +559,11 @@ msvc9_clean: $(ROS_BUILDENGINE) $(ECHO_RBUILD) $(Q)$(ROS_BUILDENGINE) $(RBUILD_FLAGS) $(ROS_RBUILDFLAGS) -c -vs9.00 -voversionconfiguration msvc +.PHONY: msvc10_clean +msvc10_clean: $(ROS_BUILDENGINE) + $(ECHO_RBUILD) + $(Q)$(ROS_BUILDENGINE) $(RBUILD_FLAGS) $(ROS_RBUILDFLAGS) -c -vs10.00 -voversionconfiguration msvc + .PHONY: msvc_clean msvc_clean: $(ROS_BUILDENGINE) $(ECHO_RBUILD) From 979696d87dd3c84d8f4988ee4ae529e8b44cbb5a Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Tue, 1 Dec 2009 19:51:51 +0000 Subject: [PATCH 129/140] [inf] Fix fdc driver version entry (highlighted by bug #4917) svn path=/trunk/; revision=44347 --- reactos/media/inf/fdc.inf | Bin 6338 -> 6338 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/reactos/media/inf/fdc.inf b/reactos/media/inf/fdc.inf index 135138d43097704b32bfe7acaec4c193ee24bede..0da85d2785ad4848302a6a0956602d12dbacd468 100644 GIT binary patch delta 22 dcmX?Pc*t;r5EG{Xg9U>=gCT?IW@)D7VgN+^1wH@( delta 22 dcmX?Pc*t;r5EG{%gDHbPg8_rZW@)D7VgN+&1wH@( From 88e41959e14f2e8cb4fca2e1920ec3172bfbcdd5 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 1 Dec 2009 21:26:40 +0000 Subject: [PATCH 130/140] [ntoskrnl/se] - Add a hack which prints an annoying message and grants access when it should not be. Callers/bugs should be fixed and this commit reverted after that. See issue #4169 for more details. svn path=/trunk/; revision=44348 --- reactos/ntoskrnl/se/semgr.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index 85cbead194e..fdee0973027 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -608,10 +608,12 @@ SepAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor, } else { - DPRINT1("Denying access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p)\n", + DPRINT1("HACK: Should deny access for caller: granted 0x%lx, desired 0x%lx (generic mapping %p).\n", *GrantedAccess, DesiredAccess, GenericMapping); - *AccessStatus = STATUS_ACCESS_DENIED; - return FALSE; + //*AccessStatus = STATUS_ACCESS_DENIED; + //return FALSE; + *AccessStatus = STATUS_SUCCESS; + return TRUE; } } From 6bc24c2625bb0d2c486d36d6546c2ed983d14db5 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Tue, 1 Dec 2009 21:32:50 +0000 Subject: [PATCH 131/140] [ntoskrnl/cc] - Don't create zero sized cache segments. By Dmitry Gorbachev. See issue #4100 for more details. svn path=/trunk/; revision=44349 --- reactos/ntoskrnl/cc/fs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/cc/fs.c b/reactos/ntoskrnl/cc/fs.c index 30e07f0fb7d..8a943b763e9 100644 --- a/reactos/ntoskrnl/cc/fs.c +++ b/reactos/ntoskrnl/cc/fs.c @@ -166,7 +166,8 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject, { current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry); current_entry = current_entry->Flink; - if (current->FileOffset > FileSizes->AllocationSize.QuadPart) + if (current->FileOffset > FileSizes->AllocationSize.QuadPart || + (current->FileOffset == 0 && FileSizes->AllocationSize.QuadPart == 0)) { if (current->ReferenceCount == 0 || (current->ReferenceCount == 1 && current->Dirty)) { From f6dd1109f6e280bbbfbf5e9e1d03b603444d8225 Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Wed, 2 Dec 2009 08:22:35 +0000 Subject: [PATCH 132/140] Bug 4970: PATCH: Dutch translation for newdev by Maikel Wever Bug 4971: PATCH: Dutch translation for regsvr32 by Maikel Wever Bug 4972: PATCH: Dutch translation of Calc - UPDATE by Maikel Wever svn path=/trunk/; revision=44355 --- reactos/base/applications/calc/lang/nl-NL.rc | 2 +- reactos/base/system/regsvr32/lang/nl-NL.rc | 34 ++++++ reactos/base/system/regsvr32/rsrc.rc | 1 + reactos/dll/win32/newdev/lang/nl-NL.rc | 115 +++++++++++++++++++ reactos/dll/win32/newdev/rsrc.rc | 1 + 5 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 reactos/base/system/regsvr32/lang/nl-NL.rc create mode 100644 reactos/dll/win32/newdev/lang/nl-NL.rc diff --git a/reactos/base/applications/calc/lang/nl-NL.rc b/reactos/base/applications/calc/lang/nl-NL.rc index fd3e3442a67..510352f6ee2 100644 --- a/reactos/base/applications/calc/lang/nl-NL.rc +++ b/reactos/base/applications/calc/lang/nl-NL.rc @@ -703,7 +703,7 @@ END STRINGTABLE DISCARDABLE BEGIN IDS_WEIGHT_BAHT "Baht" - IDS_WEIGHT_CARATS "Carats" + IDS_WEIGHT_CARATS "Karaat" IDS_WEIGHT_CHUNG "Chung" IDS_WEIGHT_DON "Don" IDS_WEIGHT_GEUN "Geun" diff --git a/reactos/base/system/regsvr32/lang/nl-NL.rc b/reactos/base/system/regsvr32/lang/nl-NL.rc new file mode 100644 index 00000000000..133075d6f1b --- /dev/null +++ b/reactos/base/system/regsvr32/lang/nl-NL.rc @@ -0,0 +1,34 @@ + #include "resource.h" + /* + * Moved all hardcoded strings to En.rc. + * By Magnus Olsen 2005 magnus@itkonsult-olsen.com + * + * Dutch Translation by Cedric Vonck cedricvonck - at - skynet (dot) be + */ + + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL + STRINGTABLE DISCARDABLE + { + + IDS_UsageMessage, "%s\n\nSyntaxis: regsvr32 [/u] [/s] [/c] [/n] [/i[:cmdline]] DLL-naam\n\ + /u - Registratie van server opheffen\n\ + /s - Stille modus; geen berichten weergeven\n\ + /c - Geef berichten weer in de console\n\ + /i - DLLInstall aanroepen en optioneel doorgeven [cmdline]. In combinatie met /u wordt het DLL-bestand verwijderd.\n\ + /n - DLLRegisterServer niet aanroepen; deze optie moet in combinatie met /i worden gebruikt." + + IDS_NoDllSpecified, "DLL naam werd niet vermeld." + + IDS_InvalidFlag, "Niet herkende schakeloptie: %s" + + IDS_SwitchN_NoI, "Niet herkende schakeloptie: /n moet in combinatie met /i worden gebruikt." + + IDS_DllNotLoaded, "LoadLibrary('%s') failed.\nGetLastError returns 0x%08x." + + IDS_MissingEntry, "%s werd ingeladen, maar het beginpunt %s werd niet gevonden.\n\n\ + %s mag niet geëxporteerd worden, of een corrupte versie van %s is in het geheugen ingeladen. Overweeg het gebruik van PView om %s te detecteren en te verwijderen." + + IDS_FailureMessage, "%s in %s was niet succesvol.\nFout code: 0x%08x" + + IDS_SuccessMessage "%s in %s is geslaagd." + } diff --git a/reactos/base/system/regsvr32/rsrc.rc b/reactos/base/system/regsvr32/rsrc.rc index 088183d2c13..425523101c8 100644 --- a/reactos/base/system/regsvr32/rsrc.rc +++ b/reactos/base/system/regsvr32/rsrc.rc @@ -15,6 +15,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #include "lang/ja-JP.rc" #include "lang/lt-LT.rc" #include "lang/no-NO.rc" +#include "lang/nl-NL.rc" #include "lang/pl-PL.rc" #include "lang/pt-BR.rc" #include "lang/ru-RU.rc" diff --git a/reactos/dll/win32/newdev/lang/nl-NL.rc b/reactos/dll/win32/newdev/lang/nl-NL.rc new file mode 100644 index 00000000000..92f67d513c1 --- /dev/null +++ b/reactos/dll/win32/newdev/lang/nl-NL.rc @@ -0,0 +1,115 @@ +/* +* COPYRIGHT: See COPYING in the top level directory +* PROJECT: ReactOS Error Reporting Assistant +* FILE: dll/win32/newdev/nl-NL.rc +* AUTHOR: Maurus Cuelenaere +*/ + + LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL + + IDD_WELCOMEPAGE DIALOG DISCARDABLE 0, 0, 317, 193 + STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU + CAPTION "Installatie apparaat" + FONT 8, "MS Shell Dlg" + BEGIN + LTEXT "Welkom",IDC_WELCOMETITLE,120,8,195,24 + LTEXT "Deze wizard installeert een nieuwe driver voor:", + IDC_STATIC,120,21,195,16 + LTEXT "Klik op Volgende om verder te gaan.",IDC_STATIC,120,169,195,17 + LTEXT "ONBEKEND APPARAAT",IDC_DEVICE,134,36,164,11 + LTEXT "WAARSCHUWING! EEN ONBEKEND APPARAAT INSTALLEREN KAN UW COMPUTER LATEN VASTLOPEN OF ONOPSTARTBAAR MAKEN!",IDC_STATIC,120,59,195,16 + CONTROL "Installeer de driver automatisch",IDC_RADIO_AUTO,"Button", + BS_AUTORADIOBUTTON,120,112,178,13 + CONTROL "Installeer de driver van een bepaalde locatie",IDC_RADIO_MANUAL, + "Button",BS_AUTORADIOBUTTON,120,133,164,14 + END + + IDD_NODRIVER DIALOG DISCARDABLE 0, 0, 317, 193 + STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU + CAPTION "Installatie apparaat" + FONT 8, "MS Shell Dlg" + BEGIN + LTEXT "Installatie mislukt.",IDC_FINISHTITLE,120,8,195,24 + LTEXT "Het apparaat kon niet geďnstalleerd worden omdat de driver niet gevonden kon worden.", + IDC_STATIC,120,40,195,19 + LTEXT "Klik op Vorige indien u het pad weet naar de driver.", + IDC_STATIC,120,98,181,24 + CONTROL "Toon dit dialoogvenster niet meer",IDC_DONOTSHOWDLG,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,120,170,180,11 + END + + IDD_INSTALLFAILED DIALOG DISCARDABLE 0, 0, 317, 193 + STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU + CAPTION "Installatie apparaat" + FONT 8, "MS Shell Dlg" + BEGIN + LTEXT "Installatie mislukt.",IDC_FINISHTITLE,120,8,195,24 + LTEXT "Het apparaat kon niet geďnstalleerd worden omdat er een onverwachte fout optrad.", + IDC_STATIC,120,40,195,19 + LTEXT "ONBEKEND APPARAAT",IDC_DEVICE,134,55,164,11 + END + + IDD_CHSOURCE DIALOG DISCARDABLE 0, 0, 317, 143 + STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU + CAPTION "Installatie apparaat" + FONT 8, "MS Shell Dlg" + BEGIN + CONTROL "Zoek in deze locaties",IDC_RADIO_SEARCHHERE,"Button", + BS_AUTORADIOBUTTON,27,11,239,13 + CONTROL "Kies de driver handmatig",IDC_RADIO_CHOOSE,"Button", + BS_AUTORADIOBUTTON,27,98,171,12 + CONTROL "Zoek in verwijderbare media",IDC_CHECK_MEDIA,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,47,33,163,9 + CONTROL "Sluit dit pad in",IDC_CHECK_PATH,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,47,54,162,10 + PUSHBUTTON "Bladeren",IDC_BROWSE,248,69,50,14 + COMBOBOX IDC_COMBO_PATH,61,71,176,12,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP | CBS_AUTOHSCROLL + END + + IDD_SEARCHDRV DIALOG DISCARDABLE 0, 0, 317, 143 + STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU + CAPTION "Installatie apparaat" + FONT 8, "MS Shell Dlg" + BEGIN + LTEXT "ONBEKEND APPARAAT",IDC_DEVICE,51,20,169,16 + END + + IDD_INSTALLDRV DIALOG DISCARDABLE 0, 0, 317, 143 + STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU + CAPTION "Installatie apparaat" + FONT 8, "MS Shell Dlg" + BEGIN + LTEXT "ONBEKEND APPARAAT",IDC_DEVICE,51,20,169,16 + END + + IDD_NEEDREBOOT DIALOG DISCARDABLE 0, 0, 317, 193 + STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU + CAPTION "Installatie apparaat" + FONT 8, "MS Shell Dlg" + BEGIN + LTEXT "Installatie voltooid",IDC_FINISHTITLE,120,8,195,11 + LTEXT "U moet uw computer herstarten om de installatie te voltooien van:", + IDC_STATIC,120,32,195,19 + LTEXT "Klik op Voltooien om de wizard te sluiten.",IDC_STATIC,120,174, + 179,11 + LTEXT "ONBEKEND APPARAAT",IDC_DEVICE,148,53,147,12 + END + + IDD_FINISHPAGE DIALOG DISCARDABLE 0, 0, 317, 193 + STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU + CAPTION "Installatie apparaat" + FONT 8, "MS Shell Dlg" + BEGIN + LTEXT "Installatie voltooid",IDC_FINISHTITLE,120,8,195,11 + LTEXT "De wizard is voltooid met het installeren van de driver voor:", + IDC_STATIC,120,32,195,19 + LTEXT "Klik op Voltooien om de wizard te sluiten.",IDC_STATIC,120,174, + 179,11 + LTEXT "ONBEKEND APPARAAT",IDC_DEVICE,148,53,147,12 + END diff --git a/reactos/dll/win32/newdev/rsrc.rc b/reactos/dll/win32/newdev/rsrc.rc index 738f99fa7d3..8e7d4e205f6 100644 --- a/reactos/dll/win32/newdev/rsrc.rc +++ b/reactos/dll/win32/newdev/rsrc.rc @@ -18,6 +18,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #include "lang/it-IT.rc" #include "lang/ja-JP.rc" #include "lang/no-NO.rc" +#include "lang/nl-NL.rc" #include "lang/pl-PL.rc" #include "lang/ro-RO.rc" #include "lang/ru-RU.rc" From c259bdb773dd8a6950c8b62b06924d1da439d9d9 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Wed, 2 Dec 2009 09:16:10 +0000 Subject: [PATCH 133/140] Handle the upcoming name change from mingw32-make.exe to make.exe in the next version of RosBE. svn path=/trunk/; revision=44358 --- reactos/rosbuild.bat | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/reactos/rosbuild.bat b/reactos/rosbuild.bat index e985273e907..21f814b33a3 100644 --- a/reactos/rosbuild.bat +++ b/reactos/rosbuild.bat @@ -1,5 +1,5 @@ :: -:: Call from Makefile command line within Visual Studio with the following parameters: +:: This script is called from the Makefile command line within Visual Studio using the following parameters: :: :: %1 - $(build) :: %2 - $(target) @@ -41,22 +41,29 @@ set "_ROSBE_FULL_PATH_=%_ROSBE_PATH_DIR%%_ROSBE_PATH_%" ::echo RosBE insall path = %_ROSBE_FULL_PATH_% :: Set the path which contains our build tools -set _ROSBE_BIN_PATH=%_ROSBE_FULL_PATH_%\i386\bin - -:: Set the make.exe path -set _MAKE_COMMAND=%_ROSBE_BIN_PATH%\mingw32-make.exe - -:: This file is located in the source root -set _ROS_SOURCE_ROOT=%~dp0 +set _ROSBE_BIN_PATH=%_ROSBE_FULL_PATH_%i386\bin :: Add the path to the search path path=%path%;%_ROSBE_BIN_PATH% +:: Set the make path +set _MAKE_COMMAND="" +if exist "%_ROSBE_BIN_PATH%\mingw32-make.exe" ( + set _MAKE_COMMAND=mingw32-make.exe +) +if exist "%_ROSBE_BIN_PATH%\make.exe" ( + set _MAKE_COMMAND=make.exe +) +if %_MAKE_COMMAND% == "" ( + goto err_no_make +) + +:: This file is located in the source root +set _ROS_SOURCE_ROOT=%~dp0 + :: Change the current dir to the source root cd %_ROS_SOURCE_ROOT% - - :: Run the requested build task if "%1" == "build" ( goto :build @@ -89,6 +96,10 @@ call "%_MAKE_COMMAND%" -j 1 %2% goto :exit +:err_no_make +echo. +echo Cannot find a make executable +goto :err_no_rosbe :err_no_rosbe echo. @@ -104,5 +115,3 @@ exit 2 :exit echo. -echo done -echo. \ No newline at end of file From e2e8b52413e940619675278fe98b9a93ed0eb221 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Wed, 2 Dec 2009 09:43:35 +0000 Subject: [PATCH 134/140] =?UTF-8?q?SXS=20Support=20Part=201=20of=202.=20Al?= =?UTF-8?q?l=20import=20work=20done=20by=20Samuel=20Serapi=C3=B3n=20with?= =?UTF-8?q?=20some=20small=20changes=20my=20me.=20[lib/rtl]=20-=20Import?= =?UTF-8?q?=20Rtlxx=20and=20related=20functions=20for=20Activation=20Conte?= =?UTF-8?q?xt=20Support=20from=20WINE.=20-=20Implement=20RtlAllocateActiva?= =?UTF-8?q?tionContextStack.=20-=20Modify=20get=5Fmanifest=5Fin=5Fmanifest?= =?UTF-8?q?=5Ffile=20function=20to=20use=20FileStandardInformation=20vice?= =?UTF-8?q?=20FileEndOfFileInformation=20(currently=20unsupported)=20in=20?= =?UTF-8?q?call=20to=20NtQueryInformationFile.=20-=20Add=20structs=20RTL?= =?UTF-8?q?=5FACTIVATION=5FCONTEXT=5FSTACK=5FFRAME=20and=20ACTIVATION=5FCO?= =?UTF-8?q?NTEXT=5FSTACK=20from=20WINE.=20-=20Add=20ActivationContextStack?= =?UTF-8?q?Pointer=20to=20TEB.=20-=20Define=20QUERY=5FACTCTX=5FFLAG=5FNO?= =?UTF-8?q?=5FADDREF.Will=20become=20active=20with=20changes=20to=20ntdll?= =?UTF-8?q?=20loader=20in=20Part=202.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=44359 --- reactos/include/ndk/rtlfuncs.h | 9 +- reactos/include/psdk/winbase.h | 1 + reactos/include/psdk/winternl.h | 18 +- reactos/lib/rtl/actctx.c | 2819 ++++++++++++++++++++++++++++--- 4 files changed, 2644 insertions(+), 203 deletions(-) diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index aff48db4671..5db3fc34daf 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -2914,17 +2914,22 @@ NTSYSAPI VOID NTAPI RtlReleaseActivationContext( - IN PVOID *Context + IN HANDLE handle ); NTSYSAPI NTSTATUS NTAPI RtlDeactivateActivationContext( - DWORD dwFlags, + ULONG dwFlags, ULONG_PTR ulCookie ); +NTSYSAPI +VOID +NTAPI +RtlFreeThreadActivationContextStack(void); + NTSYSAPI NTSTATUS NTAPI diff --git a/reactos/include/psdk/winbase.h b/reactos/include/psdk/winbase.h index c186e04b37f..0fe9544161f 100644 --- a/reactos/include/psdk/winbase.h +++ b/reactos/include/psdk/winbase.h @@ -531,6 +531,7 @@ extern "C" { #define QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX 0x00000004 #define QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE 0x00000008 #define QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS 0x00000010 +#define QUERY_ACTCTX_FLAG_NO_ADDREF 0x80000000 #if (_WIN32_WINNT >= 0x0600) #define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 #endif diff --git a/reactos/include/psdk/winternl.h b/reactos/include/psdk/winternl.h index 8a447200856..82a13b05bf4 100644 --- a/reactos/include/psdk/winternl.h +++ b/reactos/include/psdk/winternl.h @@ -191,6 +191,21 @@ typedef struct _GDI_TEB_BATCH ULONG Buffer[0x136]; } GDI_TEB_BATCH; +typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME +{ + struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME *Previous; + struct _ACTIVATION_CONTEXT *ActivationContext; + ULONG Flags; +} RTL_ACTIVATION_CONTEXT_STACK_FRAME, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME; + +typedef struct _ACTIVATION_CONTEXT_STACK +{ + ULONG Flags; + ULONG NextCookieSequenceNumber; + RTL_ACTIVATION_CONTEXT_STACK_FRAME *ActiveFrame; + LIST_ENTRY FrameListCache; +} ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK; + /*********************************************************************** * PEB data structure */ @@ -279,7 +294,8 @@ typedef struct _TEB PVOID SystemReserved1[54]; /* 0cc used for kernel32 private data in Wine */ PVOID Spare1; /* 1a4 */ LONG ExceptionCode; /* 1a8 */ - BYTE SpareBytes1[40]; /* 1ac */ + PACTIVATION_CONTEXT_STACK ActivationContextStackPointer; /* 1a8/02c8 */ + BYTE SpareBytes1[36]; /* 1ac */ PVOID SystemReserved2[10]; /* 1d4 used for ntdll private data in Wine */ GDI_TEB_BATCH GdiTebBatch; /* 1fc */ ULONG gdiRgn; /* 6dc */ diff --git a/reactos/lib/rtl/actctx.c b/reactos/lib/rtl/actctx.c index c4d484b1f1b..4508876b4fe 100644 --- a/reactos/lib/rtl/actctx.c +++ b/reactos/lib/rtl/actctx.c @@ -3,33 +3,1549 @@ * PROJECT: ReactOS Runtime Library * PURPOSE: Activation Context Support * FILE: lib/rtl/actctx.c - * PROGRAMERS: Stefan Ginsberg (stefan__100__@hotmail.com) + * PROGRAMERS: + * Jon Griffiths + * Eric Pouech + * Jacek Caban for CodeWeavers + * Alexandre Julliard + * Stefan Ginsberg (stefan__100__@hotmail.com) + * Samuel Serapión */ -/* INCLUDES *****************************************************************/ +/* Based on Wine 1.1.26 */ +/* INCLUDES *****************************************************************/ #include #define NDEBUG #include +#include + #define QUERY_ACTCTX_FLAG_ACTIVE (0x00000001) #define ACTCTX_FLAGS_ALL (\ - ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\ - ACTCTX_FLAG_LANGID_VALID |\ - ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID |\ - ACTCTX_FLAG_RESOURCE_NAME_VALID |\ - ACTCTX_FLAG_SET_PROCESS_DEFAULT |\ - ACTCTX_FLAG_APPLICATION_NAME_VALID |\ - ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF |\ - ACTCTX_FLAG_HMODULE_VALID ) + ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\ + ACTCTX_FLAG_LANGID_VALID |\ + ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID |\ + ACTCTX_FLAG_RESOURCE_NAME_VALID |\ + ACTCTX_FLAG_SET_PROCESS_DEFAULT |\ + ACTCTX_FLAG_APPLICATION_NAME_VALID |\ + ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF |\ + ACTCTX_FLAG_HMODULE_VALID ) + +#define ACTCTX_MAGIC 0xC07E3E11 #define ACTCTX_FAKE_HANDLE ((HANDLE) 0xf00baa) #define ACTCTX_FAKE_COOKIE ((ULONG_PTR) 0xf00bad) -/* INTERNAL FUNCTIONS *******************************************************/ + +typedef struct +{ + const WCHAR *ptr; + unsigned int len; +} xmlstr_t; + +typedef struct +{ + const WCHAR *ptr; + const WCHAR *end; +} xmlbuf_t; + +struct file_info +{ + ULONG type; + WCHAR *info; +}; + +struct assembly_version +{ + USHORT major; + USHORT minor; + USHORT build; + USHORT revision; +}; + +struct assembly_identity +{ + WCHAR *name; + WCHAR *arch; + WCHAR *public_key; + WCHAR *language; + WCHAR *type; + struct assembly_version version; + BOOL optional; +}; + +struct entity +{ + DWORD kind; + union + { + struct + { + WCHAR *tlbid; + WCHAR *version; + WCHAR *helpdir; + } typelib; + struct + { + WCHAR *clsid; + } comclass; + struct { + WCHAR *iid; + WCHAR *name; + } proxy; + struct + { + WCHAR *name; + } class; + struct + { + WCHAR *name; + WCHAR *clsid; + } clrclass; + struct + { + WCHAR *name; + WCHAR *clsid; + } clrsurrogate; + } u; +}; + +struct entity_array +{ + struct entity *base; + unsigned int num; + unsigned int allocated; +}; + +struct dll_redirect +{ + WCHAR *name; + WCHAR *hash; + struct entity_array entities; +}; + +enum assembly_type +{ + APPLICATION_MANIFEST, + ASSEMBLY_MANIFEST, + ASSEMBLY_SHARED_MANIFEST, +}; + +struct assembly +{ + enum assembly_type type; + struct assembly_identity id; + struct file_info manifest; + WCHAR *directory; + BOOL no_inherit; + struct dll_redirect *dlls; + unsigned int num_dlls; + unsigned int allocated_dlls; + struct entity_array entities; +}; + +typedef struct _ACTIVATION_CONTEXT +{ + ULONG magic; + long ref_count; + struct file_info config; + struct file_info appdir; + struct assembly *assemblies; + unsigned int num_assemblies; + unsigned int allocated_assemblies; +} ACTIVATION_CONTEXT; + +struct actctx_loader +{ + ACTIVATION_CONTEXT *actctx; + struct assembly_identity *dependencies; + unsigned int num_dependencies; + unsigned int allocated_dependencies; +}; + +static const WCHAR assemblyW[] = {'a','s','s','e','m','b','l','y',0}; +static const WCHAR assemblyIdentityW[] = {'a','s','s','e','m','b','l','y','I','d','e','n','t','i','t','y',0}; +static const WCHAR bindingRedirectW[] = {'b','i','n','d','i','n','g','R','e','d','i','r','e','c','t',0}; +static const WCHAR clrClassW[] = {'c','l','r','C','l','a','s','s',0}; +static const WCHAR clrSurrogateW[] = {'c','l','r','S','u','r','r','o','g','a','t','e',0}; +static const WCHAR comClassW[] = {'c','o','m','C','l','a','s','s',0}; +static const WCHAR comInterfaceExternalProxyStubW[] = {'c','o','m','I','n','t','e','r','f','a','c','e','E','x','t','e','r','n','a','l','P','r','o','x','y','S','t','u','b',0}; +static const WCHAR comInterfaceProxyStubW[] = {'c','o','m','I','n','t','e','r','f','a','c','e','P','r','o','x','y','S','t','u','b',0}; +static const WCHAR dependencyW[] = {'d','e','p','e','n','d','e','n','c','y',0}; +static const WCHAR dependentAssemblyW[] = {'d','e','p','e','n','d','e','n','t','A','s','s','e','m','b','l','y',0}; +static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0}; +static const WCHAR fileW[] = {'f','i','l','e',0}; +static const WCHAR asmv2hashW[] = {'a','s','m','v','2',':','h','a','s','h',0}; +static const WCHAR noInheritW[] = {'n','o','I','n','h','e','r','i','t',0}; +static const WCHAR noInheritableW[] = {'n','o','I','n','h','e','r','i','t','a','b','l','e',0}; +static const WCHAR typelibW[] = {'t','y','p','e','l','i','b',0}; +static const WCHAR windowClassW[] = {'w','i','n','d','o','w','C','l','a','s','s',0}; + +static const WCHAR clsidW[] = {'c','l','s','i','d',0}; +static const WCHAR hashW[] = {'h','a','s','h',0}; +static const WCHAR hashalgW[] = {'h','a','s','h','a','l','g',0}; +static const WCHAR helpdirW[] = {'h','e','l','p','d','i','r',0}; +static const WCHAR iidW[] = {'i','i','d',0}; +static const WCHAR languageW[] = {'l','a','n','g','u','a','g','e',0}; +static const WCHAR manifestVersionW[] = {'m','a','n','i','f','e','s','t','V','e','r','s','i','o','n',0}; +static const WCHAR nameW[] = {'n','a','m','e',0}; +static const WCHAR newVersionW[] = {'n','e','w','V','e','r','s','i','o','n',0}; +static const WCHAR oldVersionW[] = {'o','l','d','V','e','r','s','i','o','n',0}; +static const WCHAR optionalW[] = {'o','p','t','i','o','n','a','l',0}; +static const WCHAR processorArchitectureW[] = {'p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e',0}; +static const WCHAR publicKeyTokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0}; +static const WCHAR tlbidW[] = {'t','l','b','i','d',0}; +static const WCHAR typeW[] = {'t','y','p','e',0}; +static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0}; +static const WCHAR xmlnsW[] = {'x','m','l','n','s',0}; + +static const WCHAR xmlW[] = {'?','x','m','l',0}; +static const WCHAR manifestv1W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','1',0}; +static const WCHAR manifestv3W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','3',0}; + +static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0}; +static const WCHAR version_formatW[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; + +static ACTIVATION_CONTEXT system_actctx = { ACTCTX_MAGIC, 1 }; +static ACTIVATION_CONTEXT *process_actctx = &system_actctx; + +static WCHAR *strdupW(const WCHAR* str) +{ + WCHAR* ptr; + + if (!(ptr = RtlAllocateHeap(RtlGetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR)))) + return NULL; + return strcpyW(ptr, str); +} + +static WCHAR *xmlstrdupW(const xmlstr_t* str) +{ + WCHAR *strW; + + if ((strW = RtlAllocateHeap(RtlGetProcessHeap(), 0, (str->len + 1) * sizeof(WCHAR)))) + { + memcpy( strW, str->ptr, str->len * sizeof(WCHAR) ); + strW[str->len] = 0; + } + return strW; +} + +static inline BOOL xmlstr_cmp(const xmlstr_t* xmlstr, const WCHAR *str) +{ + return !strncmpW(xmlstr->ptr, str, xmlstr->len) && !str[xmlstr->len]; +} + +static inline BOOL xmlstr_cmpi(const xmlstr_t* xmlstr, const WCHAR *str) +{ + return !strncmpiW(xmlstr->ptr, str, xmlstr->len) && !str[xmlstr->len]; +} + +static inline BOOL xmlstr_cmp_end(const xmlstr_t* xmlstr, const WCHAR *str) +{ + return (xmlstr->len && xmlstr->ptr[0] == '/' && + !strncmpW(xmlstr->ptr + 1, str, xmlstr->len - 1) && !str[xmlstr->len - 1]); +} + +static inline BOOL isxmlspace( WCHAR ch ) +{ + return (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t'); +} + +static struct assembly *add_assembly(ACTIVATION_CONTEXT *actctx, enum assembly_type at) +{ + struct assembly *assembly; + + if (actctx->num_assemblies == actctx->allocated_assemblies) + { + void *ptr; + unsigned int new_count; + if (actctx->assemblies) + { + new_count = actctx->allocated_assemblies * 2; + ptr = RtlReAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, + actctx->assemblies, new_count * sizeof(*assembly) ); + } + else + { + new_count = 4; + ptr = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*assembly) ); + } + if (!ptr) return NULL; + actctx->assemblies = ptr; + actctx->allocated_assemblies = new_count; + } + + assembly = &actctx->assemblies[actctx->num_assemblies++]; + assembly->type = at; + return assembly; +} + +static struct dll_redirect* add_dll_redirect(struct assembly* assembly) +{ + if (assembly->num_dlls == assembly->allocated_dlls) + { + void *ptr; + unsigned int new_count; + if (assembly->dlls) + { + new_count = assembly->allocated_dlls * 2; + ptr = RtlReAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, + assembly->dlls, new_count * sizeof(*assembly->dlls) ); + } + else + { + new_count = 4; + ptr = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*assembly->dlls) ); + } + if (!ptr) return NULL; + assembly->dlls = ptr; + assembly->allocated_dlls = new_count; + } + return &assembly->dlls[assembly->num_dlls++]; +} + +static void free_assembly_identity(struct assembly_identity *ai) +{ + RtlFreeHeap( RtlGetProcessHeap(), 0, ai->name ); + RtlFreeHeap( RtlGetProcessHeap(), 0, ai->arch ); + RtlFreeHeap( RtlGetProcessHeap(), 0, ai->public_key ); + RtlFreeHeap( RtlGetProcessHeap(), 0, ai->language ); + RtlFreeHeap( RtlGetProcessHeap(), 0, ai->type ); +} + +static struct entity* add_entity(struct entity_array *array, DWORD kind) +{ + struct entity* entity; + + if (array->num == array->allocated) + { + void *ptr; + unsigned int new_count; + if (array->base) + { + new_count = array->allocated * 2; + ptr = RtlReAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, + array->base, new_count * sizeof(*array->base) ); + } + else + { + new_count = 4; + ptr = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*array->base) ); + } + if (!ptr) return NULL; + array->base = ptr; + array->allocated = new_count; + } + entity = &array->base[array->num++]; + entity->kind = kind; + return entity; +} + +static void free_entity_array(struct entity_array *array) +{ + unsigned int i; + for (i = 0; i < array->num; i++) + { + struct entity *entity = &array->base[i]; + switch (entity->kind) + { + case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION: + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.comclass.clsid); + break; + case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION: + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.proxy.iid); + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.proxy.name); + break; + case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION: + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.typelib.tlbid); + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.typelib.version); + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.typelib.helpdir); + break; + case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION: + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.class.name); + break; + case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION: + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.clrclass.name); + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.clrclass.clsid); + break; + case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES: + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.clrsurrogate.name); + RtlFreeHeap(RtlGetProcessHeap(), 0, entity->u.clrsurrogate.clsid); + break; + default: + DPRINT1("Unknown entity kind %d\n", entity->kind); + } + } + RtlFreeHeap( RtlGetProcessHeap(), 0, array->base ); +} + +static BOOL is_matching_string( const WCHAR *str1, const WCHAR *str2 ) +{ + if (!str1) return !str2; + return str2 && !strcmpiW( str1, str2 ); +} + +static BOOL is_matching_identity( const struct assembly_identity *id1, + const struct assembly_identity *id2 ) +{ + if (!is_matching_string( id1->name, id2->name )) return FALSE; + if (!is_matching_string( id1->arch, id2->arch )) return FALSE; + if (!is_matching_string( id1->public_key, id2->public_key )) return FALSE; + + if (id1->language && id2->language && strcmpiW( id1->language, id2->language )) + { + static const WCHAR wildcardW[] = {'*',0}; + if (strcmpW( wildcardW, id1->language ) && strcmpW( wildcardW, id2->language )) + return FALSE; + } + if (id1->version.major != id2->version.major) return FALSE; + if (id1->version.minor != id2->version.minor) return FALSE; + if (id1->version.build > id2->version.build) return FALSE; + if (id1->version.build == id2->version.build && + id1->version.revision > id2->version.revision) return FALSE; + return TRUE; +} + +static BOOL add_dependent_assembly_id(struct actctx_loader* acl, + struct assembly_identity* ai) +{ + unsigned int i; + + /* check if we already have that assembly */ + + for (i = 0; i < acl->actctx->num_assemblies; i++) + if (is_matching_identity( ai, &acl->actctx->assemblies[i].id )) + { + DPRINT( "reusing existing assembly for %s arch %s version %u.%u.%u.%u\n", + ai->name, ai->arch, ai->version.major, ai->version.minor, + ai->version.build, ai->version.revision ); + return TRUE; + } + + for (i = 0; i < acl->num_dependencies; i++) + if (is_matching_identity( ai, &acl->dependencies[i] )) + { + DPRINT( "reusing existing dependency for %s arch %s version %u.%u.%u.%u\n", + ai->name, ai->arch, ai->version.major, ai->version.minor, + ai->version.build, ai->version.revision ); + return TRUE; + } + + if (acl->num_dependencies == acl->allocated_dependencies) + { + void *ptr; + unsigned int new_count; + if (acl->dependencies) + { + new_count = acl->allocated_dependencies * 2; + ptr = RtlReAllocateHeap(RtlGetProcessHeap(), 0, acl->dependencies, + new_count * sizeof(acl->dependencies[0])); + } + else + { + new_count = 4; + ptr = RtlAllocateHeap(RtlGetProcessHeap(), 0, new_count * sizeof(acl->dependencies[0])); + } + if (!ptr) return FALSE; + acl->dependencies = ptr; + acl->allocated_dependencies = new_count; + } + acl->dependencies[acl->num_dependencies++] = *ai; + + return TRUE; +} + +static void free_depend_manifests(struct actctx_loader* acl) +{ + unsigned int i; + for (i = 0; i < acl->num_dependencies; i++) + free_assembly_identity(&acl->dependencies[i]); + RtlFreeHeap(RtlGetProcessHeap(), 0, acl->dependencies); +} + +static WCHAR *build_assembly_dir(struct assembly_identity* ai) +{ + static const WCHAR undW[] = {'_',0}; + static const WCHAR noneW[] = {'n','o','n','e',0}; + static const WCHAR mskeyW[] = {'d','e','a','d','b','e','e','f',0}; + + const WCHAR *arch = ai->arch ? ai->arch : noneW; + const WCHAR *key = ai->public_key ? ai->public_key : noneW; + const WCHAR *lang = ai->language ? ai->language : noneW; + const WCHAR *name = ai->name ? ai->name : noneW; + SIZE_T size = (strlenW(arch) + 1 + strlenW(name) + 1 + strlenW(key) + 24 + 1 + + strlenW(lang) + 1) * sizeof(WCHAR) + sizeof(mskeyW); + WCHAR *ret; + + if (!(ret = RtlAllocateHeap( RtlGetProcessHeap(), 0, size ))) return NULL; + + strcpyW( ret, arch ); + strcatW( ret, undW ); + strcatW( ret, name ); + strcatW( ret, undW ); + strcatW( ret, key ); + strcatW( ret, undW ); + sprintfW( ret + strlenW(ret), version_formatW, + ai->version.major, ai->version.minor, ai->version.build, ai->version.revision ); + strcatW( ret, undW ); + strcatW( ret, lang ); + strcatW( ret, undW ); + strcatW( ret, mskeyW ); + return ret; +} + +static inline void append_string( WCHAR *buffer, const WCHAR *prefix, const WCHAR *str ) +{ + WCHAR *p = buffer; + + if (!str) return; + strcatW( buffer, prefix ); + p += strlenW(p); + *p++ = '"'; + strcpyW( p, str ); + p += strlenW(p); + *p++ = '"'; + *p = 0; +} + +static WCHAR *build_assembly_id( const struct assembly_identity *ai ) +{ + static const WCHAR archW[] = + {',','p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e','=',0}; + static const WCHAR public_keyW[] = + {',','p','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0}; + static const WCHAR typeW[] = + {',','t','y','p','e','=',0}; + static const WCHAR versionW[] = + {',','v','e','r','s','i','o','n','=',0}; + + WCHAR version[64], *ret; + SIZE_T size = 0; + + sprintfW( version, version_formatW, + ai->version.major, ai->version.minor, ai->version.build, ai->version.revision ); + if (ai->name) size += strlenW(ai->name) * sizeof(WCHAR); + if (ai->arch) size += strlenW(archW) + strlenW(ai->arch) + 2; + if (ai->public_key) size += strlenW(public_keyW) + strlenW(ai->public_key) + 2; + if (ai->type) size += strlenW(typeW) + strlenW(ai->type) + 2; + size += strlenW(versionW) + strlenW(version) + 2; + + if (!(ret = RtlAllocateHeap( RtlGetProcessHeap(), 0, (size + 1) * sizeof(WCHAR) ))) + return NULL; + + if (ai->name) strcpyW( ret, ai->name ); + else *ret = 0; + append_string( ret, archW, ai->arch ); + append_string( ret, public_keyW, ai->public_key ); + append_string( ret, typeW, ai->type ); + append_string( ret, versionW, version ); + return ret; +} + +static ACTIVATION_CONTEXT *check_actctx( HANDLE h ) +{ + ACTIVATION_CONTEXT *ret = NULL, *actctx = h; + + if (!h || h == INVALID_HANDLE_VALUE) return NULL; + //__TRY + { + if (actctx && actctx->magic == ACTCTX_MAGIC) ret = actctx; + } + //__EXCEPT_PAGE_FAULT + { + } + //__ENDTRY + return ret; +} + +static inline void actctx_addref( ACTIVATION_CONTEXT *actctx ) +{ + _InterlockedExchangeAdd( &actctx->ref_count, 1 ); +} + +static void actctx_release( ACTIVATION_CONTEXT *actctx ) +{ + if (_InterlockedExchangeAdd( &actctx->ref_count, -1 ) == 1) + { + unsigned int i, j; + + for (i = 0; i < actctx->num_assemblies; i++) + { + struct assembly *assembly = &actctx->assemblies[i]; + for (j = 0; j < assembly->num_dlls; j++) + { + struct dll_redirect *dll = &assembly->dlls[j]; + free_entity_array( &dll->entities ); + RtlFreeHeap( RtlGetProcessHeap(), 0, dll->name ); + RtlFreeHeap( RtlGetProcessHeap(), 0, dll->hash ); + } + RtlFreeHeap( RtlGetProcessHeap(), 0, assembly->dlls ); + RtlFreeHeap( RtlGetProcessHeap(), 0, assembly->manifest.info ); + RtlFreeHeap( RtlGetProcessHeap(), 0, assembly->directory ); + free_entity_array( &assembly->entities ); + free_assembly_identity(&assembly->id); + } + RtlFreeHeap( RtlGetProcessHeap(), 0, actctx->config.info ); + RtlFreeHeap( RtlGetProcessHeap(), 0, actctx->appdir.info ); + RtlFreeHeap( RtlGetProcessHeap(), 0, actctx->assemblies ); + actctx->magic = 0; + RtlFreeHeap( RtlGetProcessHeap(), 0, actctx ); + } +} + +static BOOL next_xml_attr(xmlbuf_t* xmlbuf, xmlstr_t* name, xmlstr_t* value, + BOOL* error, BOOL* end) +{ + const WCHAR* ptr; + + *error = TRUE; + + while (xmlbuf->ptr < xmlbuf->end && isxmlspace(*xmlbuf->ptr)) + xmlbuf->ptr++; + + if (xmlbuf->ptr == xmlbuf->end) return FALSE; + + if (*xmlbuf->ptr == '/') + { + xmlbuf->ptr++; + if (xmlbuf->ptr == xmlbuf->end || *xmlbuf->ptr != '>') + return FALSE; + + xmlbuf->ptr++; + *end = TRUE; + *error = FALSE; + return FALSE; + } + + if (*xmlbuf->ptr == '>') + { + xmlbuf->ptr++; + *error = FALSE; + return FALSE; + } + + ptr = xmlbuf->ptr; + while (ptr < xmlbuf->end && *ptr != '=' && *ptr != '>' && !isxmlspace(*ptr)) ptr++; + + if (ptr == xmlbuf->end || *ptr != '=') return FALSE; + + name->ptr = xmlbuf->ptr; + name->len = ptr-xmlbuf->ptr; + xmlbuf->ptr = ptr; + + ptr++; + if (ptr == xmlbuf->end || (*ptr != '"' && *ptr != '\'')) return FALSE; + + value->ptr = ++ptr; + if (ptr == xmlbuf->end) return FALSE; + + ptr = memchrW(ptr, ptr[-1], xmlbuf->end - ptr); + if (!ptr) + { + xmlbuf->ptr = xmlbuf->end; + return FALSE; + } + + value->len = ptr - value->ptr; + xmlbuf->ptr = ptr + 1; + + if (xmlbuf->ptr == xmlbuf->end) return FALSE; + + *error = FALSE; + return TRUE; +} + +static BOOL next_xml_elem(xmlbuf_t* xmlbuf, xmlstr_t* elem) +{ + const WCHAR* ptr; + + for (;;) + { + ptr = memchrW(xmlbuf->ptr, '<', xmlbuf->end - xmlbuf->ptr); + if (!ptr) + { + xmlbuf->ptr = xmlbuf->end; + return FALSE; + } + ptr++; + if (ptr + 3 < xmlbuf->end && ptr[0] == '!' && ptr[1] == '-' && ptr[2] == '-') /* skip comment */ + { + for (ptr += 3; ptr + 3 <= xmlbuf->end; ptr++) + if (ptr[0] == '-' && ptr[1] == '-' && ptr[2] == '>') break; + + if (ptr + 3 > xmlbuf->end) + { + xmlbuf->ptr = xmlbuf->end; + return FALSE; + } + xmlbuf->ptr = ptr + 3; + } + else break; + } + + xmlbuf->ptr = ptr; + while (ptr < xmlbuf->end && !isxmlspace(*ptr) && *ptr != '>' && (*ptr != '/' || ptr == xmlbuf->ptr)) + ptr++; + + elem->ptr = xmlbuf->ptr; + elem->len = ptr - xmlbuf->ptr; + xmlbuf->ptr = ptr; + return xmlbuf->ptr != xmlbuf->end; +} + +static BOOL parse_xml_header(xmlbuf_t* xmlbuf) +{ + /* FIXME: parse attributes */ + const WCHAR *ptr; + + for (ptr = xmlbuf->ptr; ptr < xmlbuf->end - 1; ptr++) + { + if (ptr[0] == '?' && ptr[1] == '>') + { + xmlbuf->ptr = ptr + 2; + return TRUE; + } + } + return FALSE; +} + +static BOOL parse_text_content(xmlbuf_t* xmlbuf, xmlstr_t* content) +{ + const WCHAR *ptr = memchrW(xmlbuf->ptr, '<', xmlbuf->end - xmlbuf->ptr); + + if (!ptr) return FALSE; + + content->ptr = xmlbuf->ptr; + content->len = ptr - xmlbuf->ptr; + xmlbuf->ptr = ptr; + + return TRUE; +} + +static BOOL parse_version(const xmlstr_t *str, struct assembly_version *version) +{ + unsigned int ver[4]; + unsigned int pos; + const WCHAR *curr; + + /* major.minor.build.revision */ + ver[0] = ver[1] = ver[2] = ver[3] = pos = 0; + for (curr = str->ptr; curr < str->ptr + str->len; curr++) + { + if (*curr >= '0' && *curr <= '9') + { + ver[pos] = ver[pos] * 10 + *curr - '0'; + if (ver[pos] >= 0x10000) goto error; + } + else if (*curr == '.') + { + if (++pos >= 4) goto error; + } + else goto error; + } + version->major = ver[0]; + version->minor = ver[1]; + version->build = ver[2]; + version->revision = ver[3]; + return TRUE; + +error: + DPRINT1( "Wrong version definition in manifest file (%s)\n", str->ptr ); + return FALSE; +} + +static BOOL parse_expect_elem(xmlbuf_t* xmlbuf, const WCHAR* name) +{ + xmlstr_t elem; + if (!next_xml_elem(xmlbuf, &elem)) return FALSE; + if (xmlstr_cmp(&elem, name)) return TRUE; + DPRINT1( "unexpected element %s\n", elem.ptr ); + return FALSE; +} + +static BOOL parse_expect_no_attr(xmlbuf_t* xmlbuf, BOOL* end) +{ + xmlstr_t attr_name, attr_value; + BOOL error; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, end)) + { + DPRINT1( "unexpected attr %s=%s\n", attr_name.ptr, + attr_value.ptr); + } + return !error; +} + +static BOOL parse_end_element(xmlbuf_t *xmlbuf) +{ + BOOL end = FALSE; + return parse_expect_no_attr(xmlbuf, &end) && !end; +} + +static BOOL parse_expect_end_elem(xmlbuf_t *xmlbuf, const WCHAR *name) +{ + xmlstr_t elem; + if (!next_xml_elem(xmlbuf, &elem)) return FALSE; + if (!xmlstr_cmp_end(&elem, name)) + { + DPRINT1( "unexpected element %s\n", elem.ptr ); + return FALSE; + } + return parse_end_element(xmlbuf); +} + +static BOOL parse_unknown_elem(xmlbuf_t *xmlbuf, const xmlstr_t *unknown_elem) +{ + xmlstr_t attr_name, attr_value, elem; + BOOL end = FALSE, error, ret = TRUE; + + while(next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)); + if(error || end) return end; + + while(ret && (ret = next_xml_elem(xmlbuf, &elem))) + { + if(*elem.ptr == '/' && elem.len - 1 == unknown_elem->len && + !strncmpW(elem.ptr+1, unknown_elem->ptr, unknown_elem->len)) + break; + else + ret = parse_unknown_elem(xmlbuf, &elem); + } + + return ret && parse_end_element(xmlbuf); +} + +static BOOL parse_assembly_identity_elem(xmlbuf_t* xmlbuf, ACTIVATION_CONTEXT* actctx, + struct assembly_identity* ai) +{ + xmlstr_t attr_name, attr_value; + BOOL end = FALSE, error; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, nameW)) + { + if (!(ai->name = xmlstrdupW(&attr_value))) return FALSE; + } + else if (xmlstr_cmp(&attr_name, typeW)) + { + if (!(ai->type = xmlstrdupW(&attr_value))) return FALSE; + } + else if (xmlstr_cmp(&attr_name, versionW)) + { + if (!parse_version(&attr_value, &ai->version)) return FALSE; + } + else if (xmlstr_cmp(&attr_name, processorArchitectureW)) + { + if (!(ai->arch = xmlstrdupW(&attr_value))) return FALSE; + } + else if (xmlstr_cmp(&attr_name, publicKeyTokenW)) + { + if (!(ai->public_key = xmlstrdupW(&attr_value))) return FALSE; + } + else if (xmlstr_cmp(&attr_name, languageW)) + { + DPRINT1("Unsupported yet language attribute (%s)\n", + attr_value.ptr); + if (!(ai->language = xmlstrdupW(&attr_value))) return FALSE; + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, + attr_value.ptr); + } + } + + if (error || end) return end; + return parse_expect_end_elem(xmlbuf, assemblyIdentityW); +} + +static BOOL parse_com_class_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll) +{ + xmlstr_t elem, attr_name, attr_value; + BOOL ret, end = FALSE, error; + struct entity* entity; + + if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION))) + return FALSE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, clsidW)) + { + if (!(entity->u.comclass.clsid = xmlstrdupW(&attr_value))) return FALSE; + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + if (error || end) return end; + + while ((ret = next_xml_elem(xmlbuf, &elem))) + { + if (xmlstr_cmp_end(&elem, comClassW)) + { + ret = parse_end_element(xmlbuf); + break; + } + else + { + DPRINT1("unknown elem %s\n", elem.ptr); + ret = parse_unknown_elem(xmlbuf, &elem); + } + } + return ret; +} + +static BOOL parse_cominterface_proxy_stub_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll) +{ + xmlstr_t attr_name, attr_value; + BOOL end = FALSE, error; + struct entity* entity; + + if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION))) + return FALSE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, iidW)) + { + if (!(entity->u.proxy.iid = xmlstrdupW(&attr_value))) return FALSE; + } + if (xmlstr_cmp(&attr_name, nameW)) + { + if (!(entity->u.proxy.name = xmlstrdupW(&attr_value))) return FALSE; + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + if (error || end) return end; + return parse_expect_end_elem(xmlbuf, comInterfaceProxyStubW); +} + +static BOOL parse_typelib_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll) +{ + xmlstr_t attr_name, attr_value; + BOOL end = FALSE, error; + struct entity* entity; + + if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION))) + return FALSE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, tlbidW)) + { + if (!(entity->u.typelib.tlbid = xmlstrdupW(&attr_value))) return FALSE; + } + if (xmlstr_cmp(&attr_name, versionW)) + { + if (!(entity->u.typelib.version = xmlstrdupW(&attr_value))) return FALSE; + } + if (xmlstr_cmp(&attr_name, helpdirW)) + { + if (!(entity->u.typelib.helpdir = xmlstrdupW(&attr_value))) return FALSE; + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr , attr_value.ptr); + } + } + + if (error || end) return end; + return parse_expect_end_elem(xmlbuf, typelibW); +} + +static BOOL parse_window_class_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll) +{ + xmlstr_t elem, content; + BOOL end = FALSE, ret = TRUE; + struct entity* entity; + + if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION))) + return FALSE; + + if (!parse_expect_no_attr(xmlbuf, &end)) return FALSE; + if (end) return FALSE; + + if (!parse_text_content(xmlbuf, &content)) return FALSE; + + if (!(entity->u.class.name = xmlstrdupW(&content))) return FALSE; + + while (ret && (ret = next_xml_elem(xmlbuf, &elem))) + { + if (xmlstr_cmp_end(&elem, windowClassW)) + { + ret = parse_end_element(xmlbuf); + break; + } + else + { + DPRINT1("unknown elem %s\n", elem.ptr); + ret = parse_unknown_elem(xmlbuf, &elem); + } + } + + return ret; +} + +static BOOL parse_binding_redirect_elem(xmlbuf_t* xmlbuf) +{ + xmlstr_t attr_name, attr_value; + BOOL end = FALSE, error; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, oldVersionW)) + { + DPRINT1("Not stored yet oldVersion=%s\n", attr_value.ptr); + } + else if (xmlstr_cmp(&attr_name, newVersionW)) + { + DPRINT1("Not stored yet newVersion=%s\n", attr_value.ptr); + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + if (error || end) return end; + return parse_expect_end_elem(xmlbuf, bindingRedirectW); +} + +static BOOL parse_description_elem(xmlbuf_t* xmlbuf) +{ + xmlstr_t elem, content; + BOOL end = FALSE, ret = TRUE; + + if (!parse_expect_no_attr(xmlbuf, &end) || end || + !parse_text_content(xmlbuf, &content)) + return FALSE; + + DPRINT("Got description %s\n", content.ptr); + + while (ret && (ret = next_xml_elem(xmlbuf, &elem))) + { + if (xmlstr_cmp_end(&elem, descriptionW)) + { + ret = parse_end_element(xmlbuf); + break; + } + else + { + DPRINT1("unknown elem %s\n", elem.ptr); + ret = parse_unknown_elem(xmlbuf, &elem); + } + } + + return ret; +} + +static BOOL parse_com_interface_external_proxy_stub_elem(xmlbuf_t* xmlbuf, + struct assembly* assembly) +{ + xmlstr_t attr_name, attr_value; + BOOL end = FALSE, error; + struct entity* entity; + + entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION); + if (!entity) return FALSE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, iidW)) + { + if (!(entity->u.proxy.iid = xmlstrdupW(&attr_value))) return FALSE; + } + if (xmlstr_cmp(&attr_name, nameW)) + { + if (!(entity->u.proxy.name = xmlstrdupW(&attr_value))) return FALSE; + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + if (error || end) return end; + return parse_expect_end_elem(xmlbuf, comInterfaceExternalProxyStubW); +} + +static BOOL parse_clr_class_elem(xmlbuf_t* xmlbuf, struct assembly* assembly) +{ + xmlstr_t attr_name, attr_value; + BOOL end = FALSE, error; + struct entity* entity; + + entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION); + if (!entity) return FALSE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, nameW)) + { + if (!(entity->u.clrclass.name = xmlstrdupW(&attr_value))) return FALSE; + } + else if (xmlstr_cmp(&attr_name, clsidW)) + { + if (!(entity->u.clrclass.clsid = xmlstrdupW(&attr_value))) return FALSE; + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + if (error || end) return end; + return parse_expect_end_elem(xmlbuf, clrClassW); +} + +static BOOL parse_clr_surrogate_elem(xmlbuf_t* xmlbuf, struct assembly* assembly) +{ + xmlstr_t attr_name, attr_value; + BOOL end = FALSE, error; + struct entity* entity; + + entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES); + if (!entity) return FALSE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, nameW)) + { + if (!(entity->u.clrsurrogate.name = xmlstrdupW(&attr_value))) return FALSE; + } + else if (xmlstr_cmp(&attr_name, clsidW)) + { + if (!(entity->u.clrsurrogate.clsid = xmlstrdupW(&attr_value))) return FALSE; + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + if (error || end) return end; + return parse_expect_end_elem(xmlbuf, clrSurrogateW); +} + +static BOOL parse_dependent_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl, BOOL optional) +{ + struct assembly_identity ai; + xmlstr_t elem; + BOOL end = FALSE, ret = TRUE; + + if (!parse_expect_no_attr(xmlbuf, &end) || end) return end; + + memset(&ai, 0, sizeof(ai)); + ai.optional = optional; + + if (!parse_expect_elem(xmlbuf, assemblyIdentityW) || + !parse_assembly_identity_elem(xmlbuf, acl->actctx, &ai)) + return FALSE; + + /* store the newly found identity for later loading */ + if (!add_dependent_assembly_id(acl, &ai)) return FALSE; + + while (ret && (ret = next_xml_elem(xmlbuf, &elem))) + { + if (xmlstr_cmp_end(&elem, dependentAssemblyW)) + { + ret = parse_end_element(xmlbuf); + break; + } + else if (xmlstr_cmp(&elem, bindingRedirectW)) + { + ret = parse_binding_redirect_elem(xmlbuf); + } + else + { + DPRINT1("unknown elem %s\n", elem.ptr); + ret = parse_unknown_elem(xmlbuf, &elem); + } + } + + return ret; +} + +static BOOL parse_dependency_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl) +{ + xmlstr_t attr_name, attr_value, elem; + BOOL end = FALSE, ret = TRUE, error, optional = FALSE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, optionalW)) + { + static const WCHAR yesW[] = {'y','e','s',0}; + optional = xmlstr_cmpi( &attr_value, yesW ); + DPRINT1("optional=%s\n", attr_value.ptr); + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + while (ret && (ret = next_xml_elem(xmlbuf, &elem))) + { + if (xmlstr_cmp_end(&elem, dependencyW)) + { + ret = parse_end_element(xmlbuf); + break; + } + else if (xmlstr_cmp(&elem, dependentAssemblyW)) + { + ret = parse_dependent_assembly_elem(xmlbuf, acl, optional); + } + else + { + DPRINT1("unknown element %s\n", elem.ptr); + ret = parse_unknown_elem(xmlbuf, &elem); + } + } + + return ret; +} + +static BOOL parse_noinherit_elem(xmlbuf_t* xmlbuf) +{ + BOOL end = FALSE; + + if (!parse_expect_no_attr(xmlbuf, &end)) return FALSE; + return end || parse_expect_end_elem(xmlbuf, noInheritW); +} + +static BOOL parse_noinheritable_elem(xmlbuf_t* xmlbuf) +{ + BOOL end = FALSE; + + if (!parse_expect_no_attr(xmlbuf, &end)) return FALSE; + return end || parse_expect_end_elem(xmlbuf, noInheritableW); +} + +static BOOL parse_file_elem(xmlbuf_t* xmlbuf, struct assembly* assembly) +{ + xmlstr_t attr_name, attr_value, elem; + BOOL end = FALSE, error, ret = TRUE; + struct dll_redirect* dll; + + if (!(dll = add_dll_redirect(assembly))) return FALSE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, nameW)) + { + if (!(dll->name = xmlstrdupW(&attr_value))) return FALSE; + DPRINT("name=%s\n", attr_value.ptr); + } + else if (xmlstr_cmp(&attr_name, hashW)) + { + if (!(dll->hash = xmlstrdupW(&attr_value))) return FALSE; + } + else if (xmlstr_cmp(&attr_name, hashalgW)) + { + static const WCHAR sha1W[] = {'S','H','A','1',0}; + if (!xmlstr_cmpi(&attr_value, sha1W)) + DPRINT1("hashalg should be SHA1, got %s\n", attr_value.ptr); + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + if (error || !dll->name) return FALSE; + if (end) return TRUE; + + while (ret && (ret = next_xml_elem(xmlbuf, &elem))) + { + if (xmlstr_cmp_end(&elem, fileW)) + { + ret = parse_end_element(xmlbuf); + break; + } + else if (xmlstr_cmp(&elem, comClassW)) + { + ret = parse_com_class_elem(xmlbuf, dll); + } + else if (xmlstr_cmp(&elem, comInterfaceProxyStubW)) + { + ret = parse_cominterface_proxy_stub_elem(xmlbuf, dll); + } + else if (xmlstr_cmp(&elem, asmv2hashW)) + { + DPRINT1("asmv2hash (undocumented) not supported\n"); + ret = parse_unknown_elem(xmlbuf, &elem); + } + else if (xmlstr_cmp(&elem, typelibW)) + { + ret = parse_typelib_elem(xmlbuf, dll); + } + else if (xmlstr_cmp(&elem, windowClassW)) + { + ret = parse_window_class_elem(xmlbuf, dll); + } + else + { + DPRINT1("unknown elem %s\n", elem.ptr); + ret = parse_unknown_elem( xmlbuf, &elem ); + } + } + + return ret; +} + +static BOOL parse_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl, + struct assembly* assembly, + struct assembly_identity* expected_ai) +{ + xmlstr_t attr_name, attr_value, elem; + BOOL end = FALSE, error, version = FALSE, xmlns = FALSE, ret = TRUE; + + while (next_xml_attr(xmlbuf, &attr_name, &attr_value, &error, &end)) + { + if (xmlstr_cmp(&attr_name, manifestVersionW)) + { + static const WCHAR v10W[] = {'1','.','0',0}; + if (!xmlstr_cmp(&attr_value, v10W)) + { + DPRINT1("wrong version %s\n", attr_value.ptr); + return FALSE; + } + version = TRUE; + } + else if (xmlstr_cmp(&attr_name, xmlnsW)) + { + if (!xmlstr_cmp(&attr_value, manifestv1W) && !xmlstr_cmp(&attr_value, manifestv3W)) + { + DPRINT1("wrong namespace %s\n", attr_value.ptr); + return FALSE; + } + xmlns = TRUE; + } + else + { + DPRINT1("unknown attr %s=%s\n", attr_name.ptr, attr_value.ptr); + } + } + + if (error || end || !xmlns || !version) return FALSE; + if (!next_xml_elem(xmlbuf, &elem)) return FALSE; + + if (assembly->type == APPLICATION_MANIFEST && xmlstr_cmp(&elem, noInheritW)) + { + if (!parse_noinherit_elem(xmlbuf) || !next_xml_elem(xmlbuf, &elem)) + return FALSE; + assembly->no_inherit = TRUE; + } + + if (xmlstr_cmp(&elem, noInheritableW)) + { + if (!parse_noinheritable_elem(xmlbuf) || !next_xml_elem(xmlbuf, &elem)) + return FALSE; + } + else if ((assembly->type == ASSEMBLY_MANIFEST || assembly->type == ASSEMBLY_SHARED_MANIFEST) && + assembly->no_inherit) + return FALSE; + + while (ret) + { + if (xmlstr_cmp_end(&elem, assemblyW)) + { + ret = parse_end_element(xmlbuf); + break; + } + else if (xmlstr_cmp(&elem, descriptionW)) + { + ret = parse_description_elem(xmlbuf); + } + else if (xmlstr_cmp(&elem, comInterfaceExternalProxyStubW)) + { + ret = parse_com_interface_external_proxy_stub_elem(xmlbuf, assembly); + } + else if (xmlstr_cmp(&elem, dependencyW)) + { + ret = parse_dependency_elem(xmlbuf, acl); + } + else if (xmlstr_cmp(&elem, fileW)) + { + ret = parse_file_elem(xmlbuf, assembly); + } + else if (xmlstr_cmp(&elem, clrClassW)) + { + ret = parse_clr_class_elem(xmlbuf, assembly); + } + else if (xmlstr_cmp(&elem, clrSurrogateW)) + { + ret = parse_clr_surrogate_elem(xmlbuf, assembly); + } + else if (xmlstr_cmp(&elem, assemblyIdentityW)) + { + if (!parse_assembly_identity_elem(xmlbuf, acl->actctx, &assembly->id)) return FALSE; + + if (expected_ai) + { + /* FIXME: more tests */ + if (assembly->type == ASSEMBLY_MANIFEST && + memcmp(&assembly->id.version, &expected_ai->version, sizeof(assembly->id.version))) + { + DPRINT1("wrong version for assembly manifest: %u.%u.%u.%u / %u.%u.%u.%u\n", + expected_ai->version.major, expected_ai->version.minor, + expected_ai->version.build, expected_ai->version.revision, + assembly->id.version.major, assembly->id.version.minor, + assembly->id.version.build, assembly->id.version.revision); + ret = FALSE; + } + else if (assembly->type == ASSEMBLY_SHARED_MANIFEST && + (assembly->id.version.major != expected_ai->version.major || + assembly->id.version.minor != expected_ai->version.minor || + assembly->id.version.build < expected_ai->version.build || + (assembly->id.version.build == expected_ai->version.build && + assembly->id.version.revision < expected_ai->version.revision))) + { + DPRINT1("wrong version for shared assembly manifest\n"); + ret = FALSE; + } + } + } + else + { + DPRINT1("unknown element %s\n", elem.ptr); + ret = parse_unknown_elem(xmlbuf, &elem); + } + if (ret) ret = next_xml_elem(xmlbuf, &elem); + } + + return ret; +} + +static NTSTATUS parse_manifest_buffer( struct actctx_loader* acl, struct assembly *assembly, + struct assembly_identity* ai, xmlbuf_t *xmlbuf ) +{ + xmlstr_t elem; + + if (!next_xml_elem(xmlbuf, &elem)) return STATUS_SXS_CANT_GEN_ACTCTX; + + if (xmlstr_cmp(&elem, xmlW) && + (!parse_xml_header(xmlbuf) || !next_xml_elem(xmlbuf, &elem))) + return STATUS_SXS_CANT_GEN_ACTCTX; + + if (!xmlstr_cmp(&elem, assemblyW)) + { + DPRINT1("root element is %s, not \n", elem.ptr); + return STATUS_SXS_CANT_GEN_ACTCTX; + } + + if (!parse_assembly_elem(xmlbuf, acl, assembly, ai)) + { + DPRINT1("failed to parse manifest %s\n", assembly->manifest.info ); + return STATUS_SXS_CANT_GEN_ACTCTX; + } + + if (next_xml_elem(xmlbuf, &elem)) + { + DPRINT1("unexpected element %s\n", elem.ptr); + return STATUS_SXS_CANT_GEN_ACTCTX; + } + + if (xmlbuf->ptr != xmlbuf->end) + { + DPRINT1("parse error\n"); + return STATUS_SXS_CANT_GEN_ACTCTX; + } + return STATUS_SUCCESS; +} + +static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_identity* ai, + LPCWSTR filename, LPCWSTR directory, BOOL shared, + const void *buffer, SIZE_T size ) +{ + xmlbuf_t xmlbuf; + NTSTATUS status; + struct assembly *assembly; + int unicode_tests; + + DPRINT( "parsing manifest loaded from %s base dir %s\n", filename, directory ); + + if (!(assembly = add_assembly(acl->actctx, shared ? ASSEMBLY_SHARED_MANIFEST : ASSEMBLY_MANIFEST))) + return STATUS_SXS_CANT_GEN_ACTCTX; + + if (directory && !(assembly->directory = strdupW(directory))) + return STATUS_NO_MEMORY; + + if (filename) assembly->manifest.info = strdupW( filename + 4 /* skip \??\ prefix */ ); + assembly->manifest.type = assembly->manifest.info ? ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE + : ACTIVATION_CONTEXT_PATH_TYPE_NONE; + + unicode_tests = IS_TEXT_UNICODE_SIGNATURE | IS_TEXT_UNICODE_REVERSE_SIGNATURE; + if (RtlIsTextUnicode( (PVOID) buffer, size, &unicode_tests )) + { + xmlbuf.ptr = buffer; + xmlbuf.end = xmlbuf.ptr + size / sizeof(WCHAR); + status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf ); + } + else if (unicode_tests & IS_TEXT_UNICODE_REVERSE_SIGNATURE) + { + const WCHAR *buf = buffer; + WCHAR *new_buff; + unsigned int i; + + if (!(new_buff = RtlAllocateHeap( RtlGetProcessHeap(), 0, size ))) + return STATUS_NO_MEMORY; + for (i = 0; i < size / sizeof(WCHAR); i++) + new_buff[i] = RtlUshortByteSwap( buf[i] ); + xmlbuf.ptr = new_buff; + xmlbuf.end = xmlbuf.ptr + size / sizeof(WCHAR); + status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf ); + RtlFreeHeap( RtlGetProcessHeap(), 0, new_buff ); + } + else + { + /* let's assume utf-8 for now */ + int len; + + _SEH2_TRY + { + len = mbstowcs( NULL, buffer, size); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + DPRINT1("Exception accessing buffer\n"); + return STATUS_SXS_CANT_GEN_ACTCTX; + } + _SEH2_END; + + DPRINT("len = %x\n", len); + WCHAR *new_buff; + + if (len == -1) + { + DPRINT1( "utf-8 conversion failed\n" ); + return STATUS_SXS_CANT_GEN_ACTCTX; + } + if (!(new_buff = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(WCHAR) ))) + return STATUS_NO_MEMORY; + + mbstowcs( new_buff, buffer, len); + xmlbuf.ptr = new_buff; + DPRINT("Buffer %S\n", new_buff); + xmlbuf.end = xmlbuf.ptr + len; + status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf ); + + RtlFreeHeap( RtlGetProcessHeap(), 0, new_buff ); + } + return status; +} static NTSTATUS open_nt_file( HANDLE *handle, UNICODE_STRING *name ) { @@ -45,14 +1561,1103 @@ static NTSTATUS open_nt_file( HANDLE *handle, UNICODE_STRING *name ) return NtOpenFile( handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT ); } +static NTSTATUS get_module_filename( HMODULE module, UNICODE_STRING *str, unsigned int extra_len ) +{ + NTSTATUS status; + ULONG magic; + LDR_DATA_TABLE_ENTRY *pldr; + + LdrLockLoaderLock(0, NULL, &magic); + status = LdrFindEntryForAddress( module, &pldr ); + if (status == STATUS_SUCCESS) + { + if ((str->Buffer = RtlAllocateHeap( RtlGetProcessHeap(), 0, + pldr->FullDllName.Length + extra_len + sizeof(WCHAR) ))) + { + memcpy( str->Buffer, pldr->FullDllName.Buffer, pldr->FullDllName.Length + sizeof(WCHAR) ); + str->Length = pldr->FullDllName.Length; + str->MaximumLength = pldr->FullDllName.Length + extra_len + sizeof(WCHAR); + } + else status = STATUS_NO_MEMORY; + } + LdrUnlockLoaderLock(0, magic); + return status; +} + +static NTSTATUS get_manifest_in_module( struct actctx_loader* acl, struct assembly_identity* ai, + LPCWSTR filename, LPCWSTR directory, BOOL shared, + HANDLE hModule, LPCWSTR resname, ULONG lang ) +{ + NTSTATUS status; + UNICODE_STRING nameW; + LDR_RESOURCE_INFO info; + IMAGE_RESOURCE_DATA_ENTRY* entry = NULL; + void *ptr; + +#if 0 + if (TRACE_ON(actctx)) + { + if (!filename && !get_module_filename( hModule, &nameW, 0 )) + { + DPRINT( "looking for res %s in module %p %s\n", debugstr_w(resname), + hModule, debugstr_w(nameW.Buffer) ); + RtlFreeUnicodeString( &nameW ); + } + else DPRINT( "looking for res %s in module %p %s\n", debugstr_w(resname), + hModule, debugstr_w(filename) ); + } +#endif + + if (!resname) return STATUS_INVALID_PARAMETER; + + info.Type = (ULONG_PTR)RT_MANIFEST; + info.Language = lang; + if (!((ULONG_PTR)resname >> 16)) + { + info.Name = (ULONG_PTR)resname; + status = LdrFindResource_U(hModule, &info, 3, &entry); + } + else if (resname[0] == '#') + { + ULONG value; + RtlInitUnicodeString(&nameW, resname + 1); + if (RtlUnicodeStringToInteger(&nameW, 10, &value) != STATUS_SUCCESS || HIWORD(value)) + return STATUS_INVALID_PARAMETER; + info.Name = value; + status = LdrFindResource_U(hModule, &info, 3, &entry); + } + else + { + RtlCreateUnicodeString(&nameW, resname); + RtlUpcaseUnicodeString(&nameW, &nameW, FALSE); + info.Name = (ULONG_PTR)nameW.Buffer; + status = LdrFindResource_U(hModule, &info, 3, &entry); + RtlFreeUnicodeString(&nameW); + } + if (status == STATUS_SUCCESS) status = LdrAccessResource(hModule, entry, &ptr, NULL); + + if (status == STATUS_SUCCESS) + status = parse_manifest(acl, ai, filename, directory, shared, ptr, entry->Size); + + return status; +} + +static NTSTATUS get_manifest_in_pe_file( struct actctx_loader* acl, struct assembly_identity* ai, + LPCWSTR filename, LPCWSTR directory, BOOL shared, + HANDLE file, LPCWSTR resname, ULONG lang ) +{ + HANDLE mapping; + OBJECT_ATTRIBUTES attr; + LARGE_INTEGER size; + LARGE_INTEGER offset; + NTSTATUS status; + SIZE_T count; + void *base; + + DPRINT( "looking for res %s in %s\n", resname, filename ); + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + size.QuadPart = 0; + status = NtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, + &attr, &size, PAGE_READONLY, SEC_COMMIT, file ); + if (status != STATUS_SUCCESS) return status; + + offset.QuadPart = 0; + count = 0; + base = NULL; + status = NtMapViewOfSection( mapping, NtCurrentProcess(), &base, 0, 0, &offset, + &count, ViewShare, 0, PAGE_READONLY ); + NtClose( mapping ); + if (status != STATUS_SUCCESS) return status; + + if (RtlImageNtHeader(base)) /* we got a PE file */ + { + HANDLE module = (HMODULE)((ULONG_PTR)base | 1); /* make it a LOAD_LIBRARY_AS_DATAFILE handle */ + status = get_manifest_in_module( acl, ai, filename, directory, shared, module, resname, lang ); + } + else status = STATUS_INVALID_IMAGE_FORMAT; + + NtUnmapViewOfSection( NtCurrentProcess(), base ); + return status; +} + +static NTSTATUS get_manifest_in_manifest_file( struct actctx_loader* acl, struct assembly_identity* ai, + LPCWSTR filename, LPCWSTR directory, BOOL shared, HANDLE file ) +{ + FILE_STANDARD_INFORMATION info; + IO_STATUS_BLOCK io; + HANDLE mapping; + OBJECT_ATTRIBUTES attr; + LARGE_INTEGER size; + LARGE_INTEGER offset; + NTSTATUS status; + SIZE_T count; + void *base; + + DPRINT( "loading manifest file %S\n", filename ); + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.ObjectName = NULL; + attr.Attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + size.QuadPart = 0; + status = NtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ, + &attr, &size, PAGE_READONLY, SEC_COMMIT, file ); + + if (status != STATUS_SUCCESS) return status; + + offset.QuadPart = 0; + count = 0; + base = NULL; + status = NtMapViewOfSection( mapping, NtCurrentProcess(), &base, 0, 0, &offset, + &count, ViewShare, 0, PAGE_READONLY ); + + if (status != STATUS_SUCCESS) return status; + + /* Fixme: WINE uses FileEndOfFileInformation with NtQueryInformationFile. */ + status = NtQueryInformationFile( file, &io, &info, sizeof(info), FileStandardInformation); + + if (status == STATUS_SUCCESS) + status = parse_manifest(acl, ai, filename, directory, shared, base, info.EndOfFile.QuadPart); + + NtUnmapViewOfSection( NtCurrentProcess(), base ); + NtClose( mapping ); + return status; +} + +/* try to load the .manifest file associated to the file */ +static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl, struct assembly_identity* ai, + LPCWSTR filename, LPCWSTR directory, HMODULE module, LPCWSTR resname ) +{ + static const WCHAR fmtW[] = { '.','%','l','u',0 }; + WCHAR *buffer; + NTSTATUS status; + UNICODE_STRING nameW; + HANDLE file; + ULONG_PTR resid = (ULONG_PTR)CREATEPROCESS_MANIFEST_RESOURCE_ID; + + if (!((ULONG_PTR)resname >> 16)) resid = (ULONG_PTR)resname & 0xffff; + + DPRINT( "looking for manifest associated with %s id %lu\n", filename, resid ); + + if (module) /* use the module filename */ + { + UNICODE_STRING name; + + if (!(status = get_module_filename( module, &name, sizeof(dotManifestW) + 10*sizeof(WCHAR) ))) + { + if (resid != 1) sprintfW( name.Buffer + strlenW(name.Buffer), fmtW, resid ); + strcatW( name.Buffer, dotManifestW ); + if (!RtlDosPathNameToNtPathName_U( name.Buffer, &nameW, NULL, NULL )) + status = STATUS_RESOURCE_DATA_NOT_FOUND; + RtlFreeUnicodeString( &name ); + } + if (status) return status; + } + else + { + if (!(buffer = RtlAllocateHeap( RtlGetProcessHeap(), 0, + (strlenW(filename) + 10) * sizeof(WCHAR) + sizeof(dotManifestW) ))) + return STATUS_NO_MEMORY; + strcpyW( buffer, filename ); + if (resid != 1) sprintfW( buffer + strlenW(buffer), fmtW, resid ); + strcatW( buffer, dotManifestW ); + RtlInitUnicodeString( &nameW, buffer ); + } + + if (!open_nt_file( &file, &nameW )) + { + status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, directory, FALSE, file ); + NtClose( file ); + } + else status = STATUS_RESOURCE_DATA_NOT_FOUND; + RtlFreeUnicodeString( &nameW ); + return status; +} + +static WCHAR *lookup_manifest_file( HANDLE dir, struct assembly_identity *ai ) +{ + static const WCHAR lookup_fmtW[] = + {'%','s','_','%','s','_','%','s','_','%','u','.','%','u','.','*','.','*','_', + '*', /* FIXME */ + '.','m','a','n','i','f','e','s','t',0}; + + WCHAR *lookup, *ret = NULL; + UNICODE_STRING lookup_us; + IO_STATUS_BLOCK io; + unsigned int data_pos = 0, data_len; + char buffer[8192]; + + if (!(lookup = RtlAllocateHeap( RtlGetProcessHeap(), 0, + (strlenW(ai->arch) + strlenW(ai->name) + + strlenW(ai->public_key) + 20) * sizeof(WCHAR) + + sizeof(lookup_fmtW) ))) + return NULL; + + sprintfW( lookup, lookup_fmtW, ai->arch, ai->name, ai->public_key, ai->version.major, ai->version.minor); + RtlInitUnicodeString( &lookup_us, lookup ); + + NtQueryDirectoryFile( dir, 0, NULL, NULL, &io, buffer, sizeof(buffer), + FileBothDirectoryInformation, FALSE, &lookup_us, TRUE ); + if (io.Status == STATUS_SUCCESS) + { + FILE_BOTH_DIR_INFORMATION *dir_info; + WCHAR *tmp; + ULONG build, revision; + + data_len = io.Information; + + for (;;) + { + if (data_pos >= data_len) + { + NtQueryDirectoryFile( dir, 0, NULL, NULL, &io, buffer, sizeof(buffer), + FileBothDirectoryInformation, FALSE, &lookup_us, FALSE ); + if (io.Status != STATUS_SUCCESS) break; + data_len = io.Information; + data_pos = 0; + } + dir_info = (FILE_BOTH_DIR_INFORMATION*)(buffer + data_pos); + + if (dir_info->NextEntryOffset) data_pos += dir_info->NextEntryOffset; + else data_pos = data_len; + + tmp = (WCHAR *)dir_info->FileName + (strchrW(lookup, '*') - lookup); + build = atoiW(tmp); + if (build < ai->version.build) continue; + tmp = strchrW(tmp, '.') + 1; + revision = atoiW(tmp); + if (build == ai->version.build && revision < ai->version.revision) + continue; + ai->version.build = build; + ai->version.revision = revision; + + if ((ret = RtlAllocateHeap( RtlGetProcessHeap(), 0, dir_info->FileNameLength * sizeof(WCHAR) ))) + { + memcpy( ret, dir_info->FileName, dir_info->FileNameLength ); + ret[dir_info->FileNameLength/sizeof(WCHAR)] = 0; + } + break; + } + } + else DPRINT1("no matching file for %s\n", lookup); + RtlFreeHeap( RtlGetProcessHeap(), 0, lookup ); + return ret; +} + +static NTSTATUS lookup_winsxs(struct actctx_loader* acl, struct assembly_identity* ai) +{ + struct assembly_identity sxs_ai; + UNICODE_STRING path_us; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + WCHAR *path, *file = NULL; + HANDLE handle; + + static const WCHAR manifest_dirW[] = + {'\\','w','i','n','s','x','s','\\','m','a','n','i','f','e','s','t','s',0}; + + if (!ai->arch || !ai->name || !ai->public_key) return STATUS_NO_SUCH_FILE; + + if (!(path = RtlAllocateHeap( RtlGetProcessHeap(), 0, + ((strlenW(SharedUserData->NtSystemRoot) + 1) *sizeof(WCHAR)) + sizeof(manifest_dirW) ))) + return STATUS_NO_MEMORY; + + memcpy( path, SharedUserData->NtSystemRoot, strlenW(SharedUserData->NtSystemRoot) * sizeof(WCHAR) ); + memcpy( path + strlenW(SharedUserData->NtSystemRoot), manifest_dirW, sizeof(manifest_dirW) ); + + if (!RtlDosPathNameToNtPathName_U( path, &path_us, NULL, NULL )) + { + RtlFreeHeap( RtlGetProcessHeap(), 0, path ); + return STATUS_NO_SUCH_FILE; + } + RtlFreeHeap( RtlGetProcessHeap(), 0, path ); + + attr.Length = sizeof(attr); + attr.RootDirectory = 0; + attr.Attributes = OBJ_CASE_INSENSITIVE; + attr.ObjectName = &path_us; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + if (!NtOpenFile( &handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT )) + { + sxs_ai = *ai; + file = lookup_manifest_file( handle, &sxs_ai ); + NtClose( handle ); + } + if (!file) + { + RtlFreeUnicodeString( &path_us ); + return STATUS_NO_SUCH_FILE; + } + + /* append file name to directory path */ + if (!(path = RtlReAllocateHeap( RtlGetProcessHeap(), 0, path_us.Buffer, + path_us.Length + (strlenW(file) + 2) * sizeof(WCHAR) ))) + { + RtlFreeHeap( RtlGetProcessHeap(), 0, file ); + RtlFreeUnicodeString( &path_us ); + return STATUS_NO_MEMORY; + } + + path[path_us.Length/sizeof(WCHAR)] = '\\'; + strcpyW( path + path_us.Length/sizeof(WCHAR) + 1, file ); + RtlInitUnicodeString( &path_us, path ); + *strrchrW(file, '.') = 0; /* remove .manifest extension */ + + if (!open_nt_file( &handle, &path_us )) + { + io.Status = get_manifest_in_manifest_file(acl, &sxs_ai, path_us.Buffer, file, TRUE, handle); + NtClose( handle ); + } + else io.Status = STATUS_NO_SUCH_FILE; + + RtlFreeHeap( RtlGetProcessHeap(), 0, file ); + RtlFreeUnicodeString( &path_us ); + return io.Status; +} + +static NTSTATUS lookup_assembly(struct actctx_loader* acl, + struct assembly_identity* ai) +{ + static const WCHAR dotDllW[] = {'.','d','l','l',0}; + unsigned int i; + WCHAR *buffer, *p, *directory; + NTSTATUS status; + UNICODE_STRING nameW; + HANDLE file; + + DPRINT1( "looking for name=%S version=%u.%u.%u.%u arch=%S\n", + ai->name, ai->version.major, ai->version.minor, ai->version.build, ai->version.revision, ai->arch ); + + if ((status = lookup_winsxs(acl, ai)) != STATUS_NO_SUCH_FILE) return status; + + /* FIXME: add support for language specific lookup */ + + nameW.Buffer = NULL; + if (!(buffer = RtlAllocateHeap( RtlGetProcessHeap(), 0, + (strlenW(acl->actctx->appdir.info) + 2 * strlenW(ai->name) + 2) * sizeof(WCHAR) + sizeof(dotManifestW) ))) + return STATUS_NO_MEMORY; + + if (!(directory = build_assembly_dir( ai ))) + { + RtlFreeHeap( RtlGetProcessHeap(), 0, buffer ); + return STATUS_NO_MEMORY; + } + + /* lookup in appdir\name.dll + * appdir\name.manifest + * appdir\name\name.dll + * appdir\name\name.manifest + */ + strcpyW( buffer, acl->actctx->appdir.info ); + p = buffer + strlenW(buffer); + for (i = 0; i < 2; i++) + { + *p++ = '\\'; + strcpyW( p, ai->name ); + p += strlenW(p); + + strcpyW( p, dotDllW ); + if (RtlDosPathNameToNtPathName_U( buffer, &nameW, NULL, NULL )) + { + status = open_nt_file( &file, &nameW ); + if (!status) + { + status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, directory, FALSE, file, + (LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID, 0 ); + NtClose( file ); + break; + } + RtlFreeUnicodeString( &nameW ); + } + + strcpyW( p, dotManifestW ); + if (RtlDosPathNameToNtPathName_U( buffer, &nameW, NULL, NULL )) + { + status = open_nt_file( &file, &nameW ); + if (!status) + { + status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, directory, FALSE, file ); + NtClose( file ); + break; + } + RtlFreeUnicodeString( &nameW ); + } + status = STATUS_SXS_ASSEMBLY_NOT_FOUND; + } + RtlFreeUnicodeString( &nameW ); + RtlFreeHeap( RtlGetProcessHeap(), 0, directory ); + RtlFreeHeap( RtlGetProcessHeap(), 0, buffer ); + return status; +} + +static NTSTATUS parse_depend_manifests(struct actctx_loader* acl) +{ + NTSTATUS status = STATUS_SUCCESS; + unsigned int i; + + for (i = 0; i < acl->num_dependencies; i++) + { + if (lookup_assembly(acl, &acl->dependencies[i]) != STATUS_SUCCESS) + { + if (!acl->dependencies[i].optional) + { + DPRINT1( "Could not find dependent assembly %S\n", acl->dependencies[i].name ); + status = STATUS_SXS_CANT_GEN_ACTCTX; + break; + } + } + } + /* FIXME should now iterate through all refs */ + return status; +} + +/* find the appropriate activation context for RtlQueryInformationActivationContext */ +static NTSTATUS find_query_actctx( HANDLE *handle, DWORD flags, ULONG class ) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (flags & QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX) + { + if (NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame) + *handle = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame->ActivationContext; + } + else if (flags & (QUERY_ACTCTX_FLAG_ACTCTX_IS_ADDRESS|QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE)) + { + ULONG magic; + LDR_DATA_TABLE_ENTRY *pldr; + + LdrLockLoaderLock( 0, NULL, &magic ); + if (!LdrFindEntryForAddress( *handle, &pldr )) + { + if ((flags & QUERY_ACTCTX_FLAG_ACTCTX_IS_HMODULE) && *handle != pldr->DllBase) + status = STATUS_DLL_NOT_FOUND; + else + *handle = pldr->EntryPointActivationContext; + } + else status = STATUS_DLL_NOT_FOUND; + LdrUnlockLoaderLock( 0, magic ); + } + else if (!*handle && (class != ActivationContextBasicInformation)) + *handle = process_actctx; + + return status; +} + +static NTSTATUS fill_keyed_data(PACTCTX_SECTION_KEYED_DATA data, PVOID v1, PVOID v2, unsigned int i) +{ + data->ulDataFormatVersion = 1; + data->lpData = v1; + data->ulLength = 20; /* FIXME */ + data->lpSectionGlobalData = NULL; /* FIXME */ + data->ulSectionGlobalDataLength = 0; /* FIXME */ + data->lpSectionBase = v2; + data->ulSectionTotalLength = 0; /* FIXME */ + data->hActCtx = NULL; + if (data->cbSize >= offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG)) + data->ulAssemblyRosterIndex = i + 1; + + return STATUS_SUCCESS; +} + +static NTSTATUS find_dll_redirection(ACTIVATION_CONTEXT* actctx, const UNICODE_STRING *section_name, + PACTCTX_SECTION_KEYED_DATA data) +{ + unsigned int i, j, snlen = section_name->Length / sizeof(WCHAR); + + for (i = 0; i < actctx->num_assemblies; i++) + { + struct assembly *assembly = &actctx->assemblies[i]; + for (j = 0; j < assembly->num_dlls; j++) + { + struct dll_redirect *dll = &assembly->dlls[j]; + if (!strncmpiW(section_name->Buffer, dll->name, snlen) && !dll->name[snlen]) + return fill_keyed_data(data, dll, assembly, i); + } + } + return STATUS_SXS_KEY_NOT_FOUND; +} + +static NTSTATUS find_window_class(ACTIVATION_CONTEXT* actctx, const UNICODE_STRING *section_name, + PACTCTX_SECTION_KEYED_DATA data) +{ + unsigned int i, j, k, snlen = section_name->Length / sizeof(WCHAR); + + for (i = 0; i < actctx->num_assemblies; i++) + { + struct assembly *assembly = &actctx->assemblies[i]; + for (j = 0; j < assembly->num_dlls; j++) + { + struct dll_redirect *dll = &assembly->dlls[j]; + for (k = 0; k < dll->entities.num; k++) + { + struct entity *entity = &dll->entities.base[k]; + if (entity->kind == ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION) + { + if (!strncmpiW(section_name->Buffer, entity->u.class.name, snlen) && !entity->u.class.name[snlen]) + return fill_keyed_data(data, entity, dll, i); + } + } + } + } + return STATUS_SXS_KEY_NOT_FOUND; +} + +static NTSTATUS find_string(ACTIVATION_CONTEXT* actctx, ULONG section_kind, + const UNICODE_STRING *section_name, + DWORD flags, PACTCTX_SECTION_KEYED_DATA data) +{ + NTSTATUS status; + + switch (section_kind) + { + case ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION: + status = find_dll_redirection(actctx, section_name, data); + break; + case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION: + status = find_window_class(actctx, section_name, data); + break; + case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION: + case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION: + case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION: + case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION: + case ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE: + case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES: + DPRINT1("Unsupported yet section_kind %x\n", section_kind); + return STATUS_SXS_SECTION_NOT_FOUND; + default: + DPRINT1("Unknown section_kind %x\n", section_kind); + return STATUS_SXS_SECTION_NOT_FOUND; + } + + if (status != STATUS_SUCCESS) return status; + + if (flags & FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) + { + actctx_addref(actctx); + data->hActCtx = actctx; + } + return STATUS_SUCCESS; +} + +/* initialize the activation context for the current process */ +void actctx_init(void) +{ + ACTCTXW ctx; + HANDLE handle; + + ctx.cbSize = sizeof(ctx); + ctx.lpSource = NULL; + ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID; + ctx.hModule = NtCurrentTeb()->ProcessEnvironmentBlock->ImageBaseAddress; + ctx.lpResourceName = (LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID; + + if (!RtlCreateActivationContext( &handle, &ctx )) process_actctx = check_actctx(handle); +} /* FUNCTIONS ***************************************************************/ +NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, void *ptr ) +{ + const ACTCTXW *pActCtx = ptr; + const WCHAR *directory = NULL; + ACTIVATION_CONTEXT *actctx; + UNICODE_STRING nameW; + ULONG lang = 0; + NTSTATUS status = STATUS_NO_MEMORY; + HANDLE file = 0; + struct actctx_loader acl; + + DPRINT("%p %08x\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0); + + if (!pActCtx || pActCtx->cbSize < sizeof(*pActCtx) || + (pActCtx->dwFlags & ~ACTCTX_FLAGS_ALL)) + return STATUS_INVALID_PARAMETER; + + + if (!(actctx = RtlAllocateHeap( RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*actctx) ))) + return STATUS_NO_MEMORY; + + actctx->magic = ACTCTX_MAGIC; + actctx->ref_count = 1; + actctx->config.type = ACTIVATION_CONTEXT_PATH_TYPE_NONE; + actctx->config.info = NULL; + actctx->appdir.type = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE; + if (pActCtx->dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID) + { + if (!(actctx->appdir.info = strdupW( pActCtx->lpApplicationName ))) goto error; + } + else + { + UNICODE_STRING dir; + WCHAR *p; + + if ((status = get_module_filename( NtCurrentTeb()->ProcessEnvironmentBlock->ImageBaseAddress, &dir, 0 ))) + goto error; + + if ((p = strrchrW( dir.Buffer, '\\' ))) p[1] = 0; + actctx->appdir.info = dir.Buffer; + } + + nameW.Buffer = NULL; + if (pActCtx->lpSource) + { + if (!RtlDosPathNameToNtPathName_U(pActCtx->lpSource, &nameW, NULL, NULL)) + { + status = STATUS_NO_SUCH_FILE; + goto error; + } + status = open_nt_file( &file, &nameW ); + if (status) + { + RtlFreeUnicodeString( &nameW ); + goto error; + } + } + + acl.actctx = actctx; + acl.dependencies = NULL; + acl.num_dependencies = 0; + acl.allocated_dependencies = 0; + + if (pActCtx->dwFlags & ACTCTX_FLAG_LANGID_VALID) lang = pActCtx->wLangId; + if (pActCtx->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID) directory = pActCtx->lpAssemblyDirectory; + + if (pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) + { + /* if we have a resource it's a PE file */ + if (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID) + { + status = get_manifest_in_module( &acl, NULL, NULL, directory, FALSE, pActCtx->hModule, + pActCtx->lpResourceName, lang ); + if (status && status != STATUS_SXS_CANT_GEN_ACTCTX) + /* FIXME: what to do if pActCtx->lpSource is set */ + status = get_manifest_in_associated_manifest( &acl, NULL, NULL, directory, + pActCtx->hModule, pActCtx->lpResourceName ); + } + else if (pActCtx->lpSource) + { + status = get_manifest_in_pe_file( &acl, NULL, nameW.Buffer, directory, FALSE, + file, pActCtx->lpResourceName, lang ); + if (status && status != STATUS_SXS_CANT_GEN_ACTCTX) + status = get_manifest_in_associated_manifest( &acl, NULL, nameW.Buffer, directory, + NULL, pActCtx->lpResourceName ); + } + else status = STATUS_INVALID_PARAMETER; + } + else + { + status = get_manifest_in_manifest_file( &acl, NULL, nameW.Buffer, directory, FALSE, file ); + } + + if (file) NtClose( file ); + RtlFreeUnicodeString( &nameW ); + + if (status == STATUS_SUCCESS) status = parse_depend_manifests(&acl); + free_depend_manifests( &acl ); + + if (status == STATUS_SUCCESS) *handle = actctx; + else actctx_release( actctx ); + + return status; + +error: + if (file) NtClose( file ); + actctx_release( actctx ); + return status; +} + VOID NTAPI -RtlAddRefActivationContext(PVOID Context) +RtlAddRefActivationContext(HANDLE handle) { - UNIMPLEMENTED; + ACTIVATION_CONTEXT *actctx; + + if ((actctx = check_actctx( handle ))) actctx_addref( actctx ); +} + +VOID +NTAPI +RtlReleaseActivationContext( HANDLE handle ) +{ + ACTIVATION_CONTEXT *actctx; + + if ((actctx = check_actctx( handle ))) actctx_release( actctx ); +} + +NTSTATUS +NTAPI RtlActivateActivationContext( ULONG unknown, HANDLE handle, PULONG_PTR cookie ) +{ + RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame; + + if (!(frame = RtlAllocateHeap( RtlGetProcessHeap(), 0, sizeof(*frame) ))) + return STATUS_NO_MEMORY; + + frame->Previous = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; + frame->ActivationContext = handle; + frame->Flags = 0; + + NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = frame; + RtlAddRefActivationContext( handle ); + + *cookie = (ULONG_PTR)frame; + DPRINT( "%p cookie=%lx\n", handle, *cookie ); + return STATUS_SUCCESS; +} + + +NTSTATUS +NTAPI +RtlDeactivateActivationContext( ULONG flags, ULONG_PTR cookie ) +{ + RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame, *top; + + DPRINT( "%x cookie=%lx\n", flags, cookie ); + + /* find the right frame */ + top = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; + for (frame = top; frame; frame = frame->Previous) + if ((ULONG_PTR)frame == cookie) break; + + if (!frame) + RtlRaiseStatus( STATUS_SXS_INVALID_DEACTIVATION ); + + if (frame != top && !(flags & DEACTIVATE_ACTCTX_FLAG_FORCE_EARLY_DEACTIVATION)) + RtlRaiseStatus( STATUS_SXS_EARLY_DEACTIVATION ); + + /* pop everything up to and including frame */ + NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = frame->Previous; + + while (top != NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame) + { + frame = top->Previous; + RtlReleaseActivationContext( top->ActivationContext ); + RtlFreeHeap( RtlGetProcessHeap(), 0, top ); + top = frame; + } + + return STATUS_SUCCESS; +} + +VOID +NTAPI RtlFreeThreadActivationContextStack(void) +{ + RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame; + + frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; + while (frame) + { + RTL_ACTIVATION_CONTEXT_STACK_FRAME *prev = frame->Previous; + RtlReleaseActivationContext( frame->ActivationContext ); + RtlFreeHeap( RtlGetProcessHeap(), 0, frame ); + frame = prev; + } + NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NULL; +} + + +NTSTATUS +NTAPI RtlGetActiveActivationContext( HANDLE *handle ) +{ + if (NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame) + { + *handle = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame->ActivationContext; + RtlAddRefActivationContext( *handle ); + } + else + *handle = 0; + + return STATUS_SUCCESS; +} + + +BOOLEAN +NTAPI RtlIsActivationContextActive( HANDLE handle ) +{ + RTL_ACTIVATION_CONTEXT_STACK_FRAME *frame; + + for (frame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; frame; frame = frame->Previous) + if (frame->ActivationContext == handle) return TRUE; + return FALSE; +} + +NTSTATUS +NTAPI +RtlQueryInformationActivationContext( ULONG flags, HANDLE handle, PVOID subinst, + ULONG class, PVOID buffer, + SIZE_T bufsize, SIZE_T *retlen ) +{ + ACTIVATION_CONTEXT *actctx; + NTSTATUS status; + + DPRINT("%08x %p %p %u %p %ld %p\n", flags, handle, + subinst, class, buffer, bufsize, retlen); + + if (retlen) *retlen = 0; + if ((status = find_query_actctx( &handle, flags, class ))) return status; + + switch (class) + { + case ActivationContextBasicInformation: + { + ACTIVATION_CONTEXT_BASIC_INFORMATION *info = buffer; + + if (retlen) *retlen = sizeof(*info); + if (!info || bufsize < sizeof(*info)) return STATUS_BUFFER_TOO_SMALL; + + info->hActCtx = handle; + info->dwFlags = 0; /* FIXME */ + if (!(flags & QUERY_ACTCTX_FLAG_NO_ADDREF)) RtlAddRefActivationContext( handle ); + } + break; + + case ActivationContextDetailedInformation: + { + ACTIVATION_CONTEXT_DETAILED_INFORMATION *acdi = buffer; + struct assembly *assembly = NULL; + SIZE_T len, manifest_len = 0, config_len = 0, appdir_len = 0; + LPWSTR ptr; + + if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + + if (actctx->num_assemblies) assembly = actctx->assemblies; + + if (assembly && assembly->manifest.info) + manifest_len = strlenW(assembly->manifest.info) + 1; + if (actctx->config.info) config_len = strlenW(actctx->config.info) + 1; + if (actctx->appdir.info) appdir_len = strlenW(actctx->appdir.info) + 1; + len = sizeof(*acdi) + (manifest_len + config_len + appdir_len) * sizeof(WCHAR); + + if (retlen) *retlen = len; + if (!buffer || bufsize < len) return STATUS_BUFFER_TOO_SMALL; + + acdi->dwFlags = 0; + acdi->ulFormatVersion = assembly ? 1 : 0; /* FIXME */ + acdi->ulAssemblyCount = actctx->num_assemblies; + acdi->ulRootManifestPathType = assembly ? assembly->manifest.type : 0 /* FIXME */; + acdi->ulRootManifestPathChars = assembly && assembly->manifest.info ? manifest_len - 1 : 0; + acdi->ulRootConfigurationPathType = actctx->config.type; + acdi->ulRootConfigurationPathChars = actctx->config.info ? config_len - 1 : 0; + acdi->ulAppDirPathType = actctx->appdir.type; + acdi->ulAppDirPathChars = actctx->appdir.info ? appdir_len - 1 : 0; + ptr = (LPWSTR)(acdi + 1); + if (manifest_len) + { + acdi->lpRootManifestPath = ptr; + memcpy(ptr, assembly->manifest.info, manifest_len * sizeof(WCHAR)); + ptr += manifest_len; + } + else acdi->lpRootManifestPath = NULL; + if (config_len) + { + acdi->lpRootConfigurationPath = ptr; + memcpy(ptr, actctx->config.info, config_len * sizeof(WCHAR)); + ptr += config_len; + } + else acdi->lpRootConfigurationPath = NULL; + if (appdir_len) + { + acdi->lpAppDirPath = ptr; + memcpy(ptr, actctx->appdir.info, appdir_len * sizeof(WCHAR)); + } + else acdi->lpAppDirPath = NULL; + } + break; + + case AssemblyDetailedInformationInActivationContext: + { + ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *afdi = buffer; + struct assembly *assembly; + WCHAR *assembly_id; + DWORD index; + SIZE_T len, id_len = 0, ad_len = 0, path_len = 0; + LPWSTR ptr; + + if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + if (!subinst) return STATUS_INVALID_PARAMETER; + + index = *(DWORD*)subinst; + if (!index || index > actctx->num_assemblies) return STATUS_INVALID_PARAMETER; + + assembly = &actctx->assemblies[index - 1]; + + if (!(assembly_id = build_assembly_id( &assembly->id ))) return STATUS_NO_MEMORY; + id_len = strlenW(assembly_id) + 1; + if (assembly->directory) ad_len = strlenW(assembly->directory) + 1; + + if (assembly->manifest.info && + (assembly->type == ASSEMBLY_MANIFEST || assembly->type == ASSEMBLY_SHARED_MANIFEST)) + path_len = strlenW(assembly->manifest.info) + 1; + + len = sizeof(*afdi) + (id_len + ad_len + path_len) * sizeof(WCHAR); + + if (retlen) *retlen = len; + if (!buffer || bufsize < len) + { + RtlFreeHeap( RtlGetProcessHeap(), 0, assembly_id ); + return STATUS_BUFFER_TOO_SMALL; + } + + afdi->ulFlags = 0; /* FIXME */ + afdi->ulEncodedAssemblyIdentityLength = (id_len - 1) * sizeof(WCHAR); + afdi->ulManifestPathType = assembly->manifest.type; + afdi->ulManifestPathLength = assembly->manifest.info ? (path_len - 1) * sizeof(WCHAR) : 0; + /* FIXME afdi->liManifestLastWriteTime = 0; */ + afdi->ulPolicyPathType = ACTIVATION_CONTEXT_PATH_TYPE_NONE; /* FIXME */ + afdi->ulPolicyPathLength = 0; + /* FIXME afdi->liPolicyLastWriteTime = 0; */ + afdi->ulMetadataSatelliteRosterIndex = 0; /* FIXME */ + afdi->ulManifestVersionMajor = 1; + afdi->ulManifestVersionMinor = 0; + afdi->ulPolicyVersionMajor = 0; /* FIXME */ + afdi->ulPolicyVersionMinor = 0; /* FIXME */ + afdi->ulAssemblyDirectoryNameLength = ad_len ? (ad_len - 1) * sizeof(WCHAR) : 0; + ptr = (LPWSTR)(afdi + 1); + afdi->lpAssemblyEncodedAssemblyIdentity = ptr; + memcpy( ptr, assembly_id, id_len * sizeof(WCHAR) ); + ptr += id_len; + if (path_len) + { + afdi->lpAssemblyManifestPath = ptr; + memcpy(ptr, assembly->manifest.info, path_len * sizeof(WCHAR)); + ptr += path_len; + } else afdi->lpAssemblyManifestPath = NULL; + afdi->lpAssemblyPolicyPath = NULL; /* FIXME */ + if (ad_len) + { + afdi->lpAssemblyDirectoryName = ptr; + memcpy(ptr, assembly->directory, ad_len * sizeof(WCHAR)); + ptr += ad_len; + } + else afdi->lpAssemblyDirectoryName = NULL; + RtlFreeHeap( RtlGetProcessHeap(), 0, assembly_id ); + } + break; + + case FileInformationInAssemblyOfAssemblyInActivationContext: + { + const ACTIVATION_CONTEXT_QUERY_INDEX *acqi = subinst; + ASSEMBLY_FILE_DETAILED_INFORMATION *afdi = buffer; + struct assembly *assembly; + struct dll_redirect *dll; + SIZE_T len, dll_len = 0; + LPWSTR ptr; + + if (!(actctx = check_actctx(handle))) return STATUS_INVALID_PARAMETER; + if (!acqi) return STATUS_INVALID_PARAMETER; + + if (acqi->ulAssemblyIndex >= actctx->num_assemblies) + return STATUS_INVALID_PARAMETER; + assembly = &actctx->assemblies[acqi->ulAssemblyIndex]; + + if (acqi->ulFileIndexInAssembly >= assembly->num_dlls) + return STATUS_INVALID_PARAMETER; + dll = &assembly->dlls[acqi->ulFileIndexInAssembly]; + + if (dll->name) dll_len = strlenW(dll->name) + 1; + len = sizeof(*afdi) + dll_len * sizeof(WCHAR); + + if (!buffer || bufsize < len) + { + if (retlen) *retlen = len; + return STATUS_BUFFER_TOO_SMALL; + } + if (retlen) *retlen = 0; /* yes that's what native does !! */ + afdi->ulFlags = ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION; + afdi->ulFilenameLength = dll_len ? (dll_len - 1) * sizeof(WCHAR) : 0; + afdi->ulPathLength = 0; /* FIXME */ + ptr = (LPWSTR)(afdi + 1); + if (dll_len) + { + afdi->lpFileName = ptr; + memcpy( ptr, dll->name, dll_len * sizeof(WCHAR) ); + } else afdi->lpFileName = NULL; + afdi->lpFilePath = NULL; /* FIXME */ + } + break; + + default: + DPRINT( "class %u not implemented\n", class ); + return STATUS_NOT_IMPLEMENTED; + } + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +RtlFindActivationContextSectionString( ULONG flags, const GUID *guid, ULONG section_kind, + UNICODE_STRING *section_name, PVOID ptr ) +{ + PACTCTX_SECTION_KEYED_DATA data = ptr; + NTSTATUS status = STATUS_SXS_KEY_NOT_FOUND; + + if (guid) + { + DPRINT1("expected guid == NULL\n"); + return STATUS_INVALID_PARAMETER; + } + if (flags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) + { + DPRINT1("unknown flags %08x\n", flags); + return STATUS_INVALID_PARAMETER; + } + if (!data || data->cbSize < offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) || + !section_name || !section_name->Buffer) + { + DPRINT1("invalid parameter\n"); + return STATUS_INVALID_PARAMETER; + } + + ASSERT(NtCurrentTeb()); + ASSERT(NtCurrentTeb()->ActivationContextStackPointer); + + if (NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame) + { + ACTIVATION_CONTEXT *actctx = check_actctx(NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame->ActivationContext); + if (actctx) status = find_string( actctx, section_kind, section_name, flags, data ); + } + + if (status != STATUS_SUCCESS) + status = find_string( process_actctx, section_kind, section_name, flags, data ); + + return status; +} + +/* Stubs */ + +NTSTATUS +NTAPI +RtlAllocateActivationContextStack(IN PVOID *Context) +{ + PACTIVATION_CONTEXT_STACK ContextStack; + ContextStack = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (ACTIVATION_CONTEXT_STACK) ); + if (!ContextStack) + { + return STATUS_NO_MEMORY; + } + + ContextStack->ActiveFrame = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RTL_ACTIVATION_CONTEXT_STACK_FRAME)); + if (!ContextStack->ActiveFrame) return STATUS_NO_MEMORY; + + *Context = ContextStack; + + /* FIXME: Documentation on MSDN reads that activation contexts are only created + for modules that have a valid manifest file or resource */ + actctx_init(); + + return STATUS_SUCCESS; } NTSTATUS @@ -66,86 +2671,12 @@ RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTE NTSTATUS NTAPI -RtlAllocateActivationContextStack(IN PVOID *Context) +RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame) { UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -NTAPI -RtlGetActiveActivationContext(IN PVOID *Context) -{ - /* - if (NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame) - { - *Context = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame->ActivationContext; - RtlAddRefActivationContext(*Context); - } - else - *Context = 0; - */ - *Context = ACTCTX_FAKE_HANDLE; - return STATUS_SUCCESS; -} - -VOID -NTAPI -RtlReleaseActivationContext(IN PVOID *Context) -{ - UNIMPLEMENTED; -} - -NTSTATUS -NTAPI -RtlFindActivationContextSectionString(IN ULONG dwFlags, - IN const GUID *ExtensionGuid, - IN ULONG SectionType, - IN PUNICODE_STRING SectionName, - IN OUT PVOID ReturnedData) -{ - PACTCTX_SECTION_KEYED_DATA Data = ReturnedData; - - UNIMPLEMENTED; - - if (!Data || Data->cbSize < offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) || - !SectionName || !SectionName->Buffer) - { - return STATUS_INVALID_PARAMETER; - } - - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -RtlQueryInformationActivationContext(DWORD dwFlags, - PVOID Context, - PVOID pvSubInstance, - ULONG ulInfoClass, - PVOID pvBuffer, - SIZE_T cbBuffer OPTIONAL, - SIZE_T *pcbWrittenOrRequired OPTIONAL) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -RtlQueryInformationActiveActivationContext(ULONG ulInfoClass, - PVOID pvBuffer, - SIZE_T cbBuffer OPTIONAL, - SIZE_T *pcbWrittenOrRequired OPTIONAL) -{ - return RtlQueryInformationActivationContext(QUERY_ACTCTX_FLAG_ACTIVE, - NULL, - NULL, - ulInfoClass, - pvBuffer, - cbBuffer, - pcbWrittenOrRequired); -} NTSTATUS NTAPI @@ -159,115 +2690,3 @@ RtlZombifyActivationContext(PVOID Context) return STATUS_NOT_IMPLEMENTED; } -NTSTATUS -NTAPI -RtlDeactivateActivationContext(DWORD dwFlags, - ULONG_PTR ulCookie) -{ - UNIMPLEMENTED; - - if (ulCookie == ACTCTX_FAKE_COOKIE) - return STATUS_SUCCESS; - - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS -NTAPI -RtlActivateActivationContext(IN ULONG Unknown, IN HANDLE Handle, OUT PULONG_PTR Cookie) -{ - /* - PRTL_ACTIVATION_CONTEXT_STACK_FRAME Frame; - - Frame = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*Frame) ); - if (!Frame) - return STATUS_NO_MEMORY; - - Frame->Previous = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame; - Frame->ActivationContext = Handle; - Frame->Flags = 0; - NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = Frame; - RtlAddRefActivationContext(Handle); - - *Cookie = (ULONG_PTR)Frame; - DPRINT( "%p Cookie=%lx\n", Handle, *Cookie ); - */ - - UNIMPLEMENTED; - - if (Cookie) - *Cookie = ACTCTX_FAKE_COOKIE; - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -RtlCreateActivationContext(OUT PHANDLE Handle, IN OUT PVOID ReturnedData) -{ - PCACTCTXW pActCtx = (PCACTCTXW) ReturnedData; - UNICODE_STRING NameW; - NTSTATUS Status = STATUS_SUCCESS; - HANDLE hFile = INVALID_HANDLE_VALUE; - - UNIMPLEMENTED; - - if (!pActCtx || (pActCtx->cbSize < sizeof(*pActCtx)) || - (pActCtx->dwFlags & ~ACTCTX_FLAGS_ALL)) - return STATUS_INVALID_PARAMETER; - - NameW.Buffer = NULL; - if (pActCtx->lpSource) - { - if (!RtlDosPathNameToNtPathName_U(pActCtx->lpSource, &NameW, NULL, NULL)) - { - Status = STATUS_NO_SUCH_FILE; - goto Error; - } - Status = open_nt_file( &hFile, &NameW ); - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString( &NameW ); - goto Error; - } - } - - if (pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) - { - /* if we have a resource it's a PE file */ - if (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID) - { - } - else if (pActCtx->lpSource) - { - } - else - { - Status = STATUS_INVALID_PARAMETER; - } - } - else - { - /* manifest file */ - } - - if (hFile) - NtClose( hFile ); - if (NameW.Buffer) - RtlFreeUnicodeString( &NameW ); - - *Handle = ACTCTX_FAKE_HANDLE; - return Status; - -Error: - if (hFile) NtClose( hFile ); - return Status; - -} From 0c2fe0a124a78d563f9e2520648c413a95be39ec Mon Sep 17 00:00:00 2001 From: Dmitry Gorbachev Date: Wed, 2 Dec 2009 17:11:32 +0000 Subject: [PATCH 135/140] Update log2lines to version 1.5. Jan Roeloffzen, bug #4342. svn path=/trunk/; revision=44363 --- reactos/tools/rsym/log2lines.c | 192 +++++++++++++++++++++++++++------ 1 file changed, 158 insertions(+), 34 deletions(-) diff --git a/reactos/tools/rsym/log2lines.c b/reactos/tools/rsym/log2lines.c index c2616c25946..9da33528987 100644 --- a/reactos/tools/rsym/log2lines.c +++ b/reactos/tools/rsym/log2lines.c @@ -10,11 +10,12 @@ #include "rsym.h" -#define LOG2LINES_VERSION "1.4" +#define LOG2LINES_VERSION "1.5" #define INVALID_BASE 0xFFFFFFFFL #define DEF_OPT_DIR "output-i386" +#define SOURCES_ENV "_ROSBE_ROSSOURCEDIR" #if defined (__DJGPP__) || defined (__WIN32__) @@ -52,6 +53,7 @@ "%s x -y -r %s" PATH_STR "reactos" PATH_STR "reactos.cab -o%s" PATH_STR "reactos" PATH_STR "reactos > " DEV_NULL #define LINESIZE 1024 +#define NAMESIZE 80 #define log(outFile, fmt, ...) \ { \ @@ -90,13 +92,26 @@ struct summ_struct int total; }; +struct lineinfo_struct +{ + int valid; + char file1[LINESIZE]; + char func1[NAMESIZE]; + int nr1; + char file2[LINESIZE]; + char func2[NAMESIZE]; + int nr2; +}; + typedef struct cache_struct CACHE; typedef struct summ_struct SUMM; +typedef struct lineinfo_struct LINEINFO; static CACHE cache; static SUMM summ; +static LINEINFO lastLine; -static char *optchars = "bcd:fFhl:mMrstTuUvz:"; +static char *optchars = "bcd:fFhl:mMrsS:tTuUvz:"; static int opt_buffered= 0; // -b static int opt_help = 0; // -h static int opt_force = 0; // -f @@ -107,6 +122,7 @@ static int opt_mark = 0; // -m static int opt_Mark = 0; // -M static int opt_raw = 0; // -r static int opt_stats = 0; // -s +static int opt_Source = 0; // -S static int opt_twice = 0; // -t static int opt_Twice = 0; // -T static int opt_undo = 0; // -u @@ -120,6 +136,63 @@ static FILE *logFile = NULL; static char *cache_name; static char *tmp_name; +static char sources_path[LINESIZE]; + +static void +clearLastLine(void) +{ + memset(&lastLine, 0, sizeof(LINEINFO)); +} + +static void +log_file(FILE *outFile, char *fileName, int max ) +{ + int i = 0, min = 0; + char s[LINESIZE]; + char p[LINESIZE]; + FILE *src; + + strcpy(p, sources_path); + strcat(p, fileName); + if ((src = fopen(p, "r"))) + { + min = max - opt_Source; + min = (min < 0) ? 0 : min; + while (i < max && fgets(s, LINESIZE, src)) + { + if (i >= min) + log(outFile, "| %4.4d %s", i + 1, s); + i++; + } + fclose(src); + } + else if (opt_verbose) + fprintf(stderr, "Can't open: %s (check " SOURCES_ENV ")\n", p); +} + +static void +logSource(FILE *outFile) +{ + log_file(outFile, lastLine.file1, lastLine.nr1); + if (lastLine.nr2) + { + log(outFile, "| ---- [%u] ----\n", lastLine.nr2); + log_file(outFile, lastLine.file2, lastLine.nr2); + } +} + +static void +reportSource(FILE *outFile) +{ + if (!opt_Source) + return; + if (lastLine.valid) + { + logSource(outFile); + } + clearLastLine(); +} + static char * basename(char *path) { @@ -206,17 +279,24 @@ print_offset(void *data, size_t offset, char *toString) } if (e || e2) { + strcpy(lastLine.file1, &Strings[e->FileOffset]); + strcpy(lastLine.func1, &Strings[e->FunctionOffset]); + lastLine.nr1 = e->SourceLine; + lastLine.valid = 1; if (e2) { + strcpy(lastLine.file2, &Strings[e2->FileOffset]); + strcpy(lastLine.func2, &Strings[e2->FunctionOffset]); + lastLine.nr2 = e2->SourceLine; bFileOffsetChanged = e->FileOffset != e2->FileOffset; if (e->FileOffset != e2->FileOffset || e->FunctionOffset != e2->FunctionOffset) summ.majordiff++; /* - * - "%.0s" displays nothing, but processes argument - * - bFileOffsetChanged implies always display 2nd SourceLine even if the same - * - also for FunctionOffset - */ + * - "%.0s" displays nothing, but processes argument + * - bFileOffsetChanged implies always display 2nd SourceLine even if the same + * - also for FunctionOffset + */ strcat(fmt, "%s"); if (bFileOffsetChanged) strcat(fmt, "[%s]"); @@ -238,23 +318,23 @@ print_offset(void *data, size_t offset, char *toString) if (toString) { // put in toString if provided snprintf(toString, LINESIZE, fmt, - &Strings[e->FileOffset], - &Strings[e2->FileOffset], - (unsigned int)e->SourceLine, - (unsigned int)e2->SourceLine, - &Strings[e->FunctionOffset], - &Strings[e2->FunctionOffset]); + &Strings[e->FileOffset], + &Strings[e2->FileOffset], + (unsigned int)e->SourceLine, + (unsigned int)e2->SourceLine, + &Strings[e->FunctionOffset], + &Strings[e2->FunctionOffset]); } else { - strcat(fmt, "\n"); - printf(fmt, - &Strings[e->FileOffset], - &Strings[e2->FileOffset], - (unsigned int)e->SourceLine, - (unsigned int)e2->SourceLine, - &Strings[e->FunctionOffset], - &Strings[e2->FunctionOffset]); + strcat(fmt, "\n"); + printf(fmt, + &Strings[e->FileOffset], + &Strings[e2->FileOffset], + (unsigned int)e->SourceLine, + (unsigned int)e2->SourceLine, + &Strings[e->FunctionOffset], + &Strings[e2->FunctionOffset]); } } else @@ -262,16 +342,16 @@ print_offset(void *data, size_t offset, char *toString) if (toString) { // put in toString if provided snprintf(toString, LINESIZE, "%s:%u (%s)", - &Strings[e->FileOffset], - (unsigned int)e->SourceLine, - &Strings[e->FunctionOffset]); + &Strings[e->FileOffset], + (unsigned int)e->SourceLine, + &Strings[e->FunctionOffset]); } else { printf("%s:%u (%s)\n", - &Strings[e->FileOffset], - (unsigned int)e->SourceLine, - &Strings[e->FunctionOffset]); + &Strings[e->FileOffset], + (unsigned int)e->SourceLine, + &Strings[e->FunctionOffset]); } } return 0; @@ -831,9 +911,19 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut) if (!*Line) return; + res = 1; mark = ""; s = remove_mark(Line); + if (opt_undo) + { + /* Strip all lines added by this tool: */ + char buf[NAMESIZE]; + if (sscanf(s, "| %s", buf) == 1) + if (buf[0] == '0' || strcmp(buf, "----") == 0 || atoi(buf)) + res = 0; + } + sep = strchr(s, ':'); if (sep) { @@ -947,6 +1037,7 @@ translate_files(FILE *inFile, FILE *outFile) translate_line(outFile, Line, path, LineOut); i = 0; translate_char(c, outFile); + reportSource(outFile); break; case '<': i = 0; @@ -1005,6 +1096,7 @@ translate_files(FILE *inFile, FILE *outFile) if (!opt_raw) { translate_line(outFile, Line, path, LineOut); + reportSource(outFile); } else { @@ -1075,20 +1167,27 @@ static char *verboseUsage = " - Offset error: Image exists, but error retrieving offset info.\n" " - Total: Total number of lines attempted to translate.\n" " Also some version info is displayed.\n\n" -" -t Translate twice. The address itself and for (address - 1)\n" +" -S \n" +" Source lines. Display up to lines until linenumber.\n" +" The environment variable _ROSBE_ROSSOURCEDIR should be correctly set.\n" +" For a reliable result, these sources should be up to date with\n" +" the revision you test.\n" +" Can be combined with -tT.\n" +" Implies -U. Retranslation needed for retrieving source info.\n\n" +" -t Translate twice. The address itself and for (address - 1).\n" " Show extra filename, func and linenumber between [..] if they differ\n" " So if only the linenumbers differ, then only show the extra\n" " linenumber.\n\n" -" -T As -t, but the original filename+func+linenumber gets replaced\n\n" +" -T As -t, but show only filename+func+linenumber for (address - 1.)\n\n" " -u Undo translations.\n" " Lines are translated back (reverted) to the form \n" -" Overrides console mode -c.\n\n" +" Also removes all lines previously added by this tool (see -S)\n\n" " -U Undo and reprocess.\n" " Reverted to the form , and then retranslated\n" -" Overrides console mode -c, implies -u.\n\n" +" Implies -u.\n\n" " -v Show detailed errors and tracing.\n" " Repeating this option adds more verbosity.\n" -" Default: only (major) errors\n" "\n\n" +" Default: only (major) errors\n\n" " -z \n" " Specify path to 7z. See also option -d.\n" " Default: '7z'\n" @@ -1113,6 +1212,14 @@ static char *verboseUsage = " The following command line invocations are equivalent:\n" " log2lines msi.dll 2e35d msi.dll 2235 msiexec.exe 30a8 msiexec.exe 2e89\n" " log2lines msi.dll 2e35d 2235 msiexec.exe 30a8 2e89\n\n" +" Generate source lines from backtrace ('bt') output. Show 2 lines of context:\n" +" log2lines -S 2 -d bootcd-38701-dbg.7z < bugxxxx.log\n" +" \n" +" | 0258 #else\n" +" | 0259 mainret = main (\n" +" \n" +" | 0159 return __tmainCRTStartup ();\n" +" | 0160 }\n" "\n"; static void @@ -1277,6 +1384,14 @@ main(int argc, const char **argv) int opt; int optCount = 0; int i; + char *s; + + strcpy(sources_path, ""); + if ((s = getenv(SOURCES_ENV))) + { + strcpy(sources_path, s); + strcat(sources_path, PATH_STR); + } strcpy(opt_scanned, ""); for (i = 1; i < argc; i++) @@ -1289,6 +1404,7 @@ main(int argc, const char **argv) strcpy(opt_7z, CMD_7Z); memset(&summ, 0, sizeof(SUMM)); + clearLastLine(); while (-1 != (opt = getopt(argc, (char **const)argv, optchars))) { @@ -1332,6 +1448,10 @@ main(int argc, const char **argv) case 's': opt_stats++; break; + case 'S': + optCount++; + opt_Source = atoi(optarg); + break; case 't': opt_twice++; break; @@ -1360,9 +1480,12 @@ main(int argc, const char **argv) } optCount++; } - if (opt_undo) - opt_console = 0; - + if (opt_Source) + { + /* need to retranslate for source info: */ + opt_undo++; + opt_redo++; + } argc -= optCount; if (check_directory(opt_force)) return 3; @@ -1413,6 +1536,7 @@ main(int argc, const char **argv) if (opt_verbose > 1) fprintf(stderr, "translating %s %s\n", base, offset); translate_file(base, my_atoi(offset), NULL); + reportSource(stdout); } else { From 93d086d81a23d9b9e7e09f54410f365104de33b2 Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Wed, 2 Dec 2009 18:28:52 +0000 Subject: [PATCH 136/140] Martin Ettl : Fix various resource and memory leaks See issue #4974 for more details. svn path=/trunk/; revision=44364 --- reactos/base/applications/network/telnet/src/tnetwork.h | 2 +- reactos/base/applications/tsclient/rdesktop/printercache.c | 1 + reactos/base/applications/tsclient/rdesktop/rdesktop.c | 3 +++ reactos/base/applications/tsclient/rdesktop/uiports/qtwin.cpp | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/reactos/base/applications/network/telnet/src/tnetwork.h b/reactos/base/applications/network/telnet/src/tnetwork.h index 64dfb1179a7..bcc78c7012f 100644 --- a/reactos/base/applications/network/telnet/src/tnetwork.h +++ b/reactos/base/applications/network/telnet/src/tnetwork.h @@ -24,7 +24,7 @@ public: TNetwork(SOCKET s = 0): socket(s), local_echo(1), line_mode(1), net_type(TN_NETSOCKET), naws_func((Naws_func_t)NULL), local_address((char *)NULL) {} - ~TNetwork() {if(local_address) delete local_address;} + ~TNetwork() {if(local_address) delete[] local_address;} void SetSocket(SOCKET s); SOCKET GetSocket() {return socket;} diff --git a/reactos/base/applications/tsclient/rdesktop/printercache.c b/reactos/base/applications/tsclient/rdesktop/printercache.c index 38b38bbe5c2..c2d39bf5aa9 100644 --- a/reactos/base/applications/tsclient/rdesktop/printercache.c +++ b/reactos/base/applications/tsclient/rdesktop/printercache.c @@ -180,6 +180,7 @@ printercache_load_blob(char *printer_name, uint8 ** data) if (fstat(fd, &st)) { xfree(path); + close(fd); return 0; } diff --git a/reactos/base/applications/tsclient/rdesktop/rdesktop.c b/reactos/base/applications/tsclient/rdesktop/rdesktop.c index 425ce058b08..37e5f38fb61 100644 --- a/reactos/base/applications/tsclient/rdesktop/rdesktop.c +++ b/reactos/base/applications/tsclient/rdesktop/rdesktop.c @@ -1405,7 +1405,10 @@ load_licence(RDPCLIENT * This, unsigned char **data) return -1; if (fstat(fd, &st)) + { + close(fd); return -1; + } *data = (uint8 *) xmalloc(st.st_size); length = read(fd, *data, st.st_size); diff --git a/reactos/base/applications/tsclient/rdesktop/uiports/qtwin.cpp b/reactos/base/applications/tsclient/rdesktop/uiports/qtwin.cpp index 718ba2df052..a23727ea5dc 100644 --- a/reactos/base/applications/tsclient/rdesktop/uiports/qtwin.cpp +++ b/reactos/base/applications/tsclient/rdesktop/uiports/qtwin.cpp @@ -1475,6 +1475,8 @@ int load_licence(uint8 ** data) } if (fstat(fd, &st)) { + close(fd); + xfree(path); return -1; } *data = (uint8 *) xmalloc(st.st_size); From 23df1a2f4b3453211d4776b94043cfcec2f6918d Mon Sep 17 00:00:00 2001 From: Gregor Schneider Date: Wed, 2 Dec 2009 18:58:05 +0000 Subject: [PATCH 137/140] Move tsclient to rosapps (not included in build process and superseded by Geds mstsc implementation) [1/2] svn path=/trunk/; revision=44365 --- .../applications/net/tsclient/MissTosca.sln | 38 + .../applications/net/tsclient/mstsc/mstsc.cpp | 7 + .../net/tsclient/mstsc/mstsc.vcproj | 223 + .../net/tsclient/mstsc/stdafx.cpp | 8 + .../applications/net/tsclient/mstsc/stdafx.h | 15 + .../net/tsclient/mstscax/mstscax.cpp | 7 + .../net/tsclient/mstscax/mstscax.vcproj | 223 + .../net/tsclient/mstscax/stdafx.cpp | 8 + .../net/tsclient/mstscax/stdafx.h | 15 + .../porting-tools/mstscax/mstscax.cpp | 5011 +++++++++ .../porting-tools/mstscax/mstscax.def | 14 + .../porting-tools/mstscax/mstscax.sln | 20 + .../porting-tools/mstscax/mstscax.vcproj | 229 + .../tsclient/porting-tools/mstscax/stdafx.cpp | 1 + .../tsclient/porting-tools/mstscax/stdafx.h | 33 + .../rdesktop-core-tester/activex.cpp | 6095 +++++++++++ .../rdesktop-core-tester/mstsclib.idl | 561 ++ .../rdesktop-core-tester/mstsclib.rc | 3 + .../rdesktop-core-tester/mstsclib_h.h | 8946 +++++++++++++++++ .../rdesktop-core-tester/mstsclib_i.c | 145 + .../rdesktop-core-tester/mstsclib_redist.idl | 3 + .../rdesktop-core-tester/mstsclib_redist.rc | 3 + .../rdesktop-core-tester/mstsclib_redist_h.h | 8946 +++++++++++++++++ .../rdesktop-core-tester/mstsclib_redist_i.c | 145 + .../rdesktop-core-tester.cpp | 653 ++ .../rdesktop-core-tester.vcproj | 377 + .../rdesktop-core-tester/stdafx.cpp | 3 + .../rdesktop-core-tester/stdafx.h | 32 + .../rdesktop-core-tester/typelib.rh | 21 + .../net/tsclient/rdesktop/COPYING | 346 + .../net/tsclient/rdesktop/Makefile.in | 158 + .../applications/net/tsclient/rdesktop/README | 32 + .../net/tsclient/rdesktop/bitmap.c | 1112 ++ .../net/tsclient/rdesktop/bootstrap | 3 + .../net/tsclient/rdesktop/cache.c | 414 + .../net/tsclient/rdesktop/channels.c | 177 + .../net/tsclient/rdesktop/cliprdr.c | 182 + .../net/tsclient/rdesktop/config.guess | 1411 +++ .../net/tsclient/rdesktop/config.sub | 1500 +++ .../net/tsclient/rdesktop/configure.ac | 727 ++ .../net/tsclient/rdesktop/constants.h | 430 + .../applications/net/tsclient/rdesktop/disk.c | 1246 +++ .../applications/net/tsclient/rdesktop/disk.h | 139 + .../net/tsclient/rdesktop/doc/AUTHORS | 14 + .../net/tsclient/rdesktop/doc/ChangeLog | 86 + .../net/tsclient/rdesktop/doc/HACKING | 28 + .../net/tsclient/rdesktop/doc/TODO | 89 + .../net/tsclient/rdesktop/doc/ipv6.txt | 29 + .../tsclient/rdesktop/doc/keymap-names.txt | 124 + .../net/tsclient/rdesktop/doc/keymapping.txt | 243 + .../net/tsclient/rdesktop/doc/keynums.png | Bin 0 -> 9173 bytes .../net/tsclient/rdesktop/doc/licensing.txt | 56 + .../tsclient/rdesktop/doc/lspci-channel.txt | 39 + .../net/tsclient/rdesktop/doc/patches.txt | 340 + .../net/tsclient/rdesktop/doc/rdesktop.1 | 217 + .../net/tsclient/rdesktop/doc/redirection.txt | 74 + .../rdesktop/doc/seamlessrdp-channel.txt | 284 + .../net/tsclient/rdesktop/ewmhints.c | 456 + .../net/tsclient/rdesktop/indent-all.sh | 3 + .../net/tsclient/rdesktop/install-sh | 251 + .../applications/net/tsclient/rdesktop/iso.c | 240 + .../net/tsclient/rdesktop/keymaps/ar | 98 + .../net/tsclient/rdesktop/keymaps/common | 229 + .../net/tsclient/rdesktop/keymaps/convert-map | 63 + .../net/tsclient/rdesktop/keymaps/cs | 87 + .../net/tsclient/rdesktop/keymaps/da | 120 + .../net/tsclient/rdesktop/keymaps/de | 114 + .../net/tsclient/rdesktop/keymaps/de-ch | 169 + .../net/tsclient/rdesktop/keymaps/en-dv | 216 + .../net/tsclient/rdesktop/keymaps/en-gb | 119 + .../net/tsclient/rdesktop/keymaps/en-us | 35 + .../net/tsclient/rdesktop/keymaps/es | 105 + .../net/tsclient/rdesktop/keymaps/et | 86 + .../net/tsclient/rdesktop/keymaps/fi | 122 + .../net/tsclient/rdesktop/keymaps/fo | 77 + .../net/tsclient/rdesktop/keymaps/fr | 181 + .../net/tsclient/rdesktop/keymaps/fr-be | 135 + .../net/tsclient/rdesktop/keymaps/fr-ca | 50 + .../net/tsclient/rdesktop/keymaps/fr-ch | 169 + .../net/tsclient/rdesktop/keymaps/he | 91 + .../net/tsclient/rdesktop/keymaps/hr | 125 + .../net/tsclient/rdesktop/keymaps/hu | 115 + .../net/tsclient/rdesktop/keymaps/is | 140 + .../net/tsclient/rdesktop/keymaps/it | 115 + .../net/tsclient/rdesktop/keymaps/ja | 107 + .../net/tsclient/rdesktop/keymaps/ko | 37 + .../net/tsclient/rdesktop/keymaps/lt | 57 + .../net/tsclient/rdesktop/keymaps/lv | 128 + .../net/tsclient/rdesktop/keymaps/mk | 101 + .../net/tsclient/rdesktop/keymaps/modifiers | 18 + .../net/tsclient/rdesktop/keymaps/nl | 60 + .../net/tsclient/rdesktop/keymaps/nl-be | 142 + .../net/tsclient/rdesktop/keymaps/no | 119 + .../net/tsclient/rdesktop/keymaps/pl | 122 + .../net/tsclient/rdesktop/keymaps/pt | 113 + .../net/tsclient/rdesktop/keymaps/pt-br | 69 + .../net/tsclient/rdesktop/keymaps/ru | 109 + .../net/tsclient/rdesktop/keymaps/sl | 110 + .../net/tsclient/rdesktop/keymaps/sv | 80 + .../net/tsclient/rdesktop/keymaps/th | 131 + .../net/tsclient/rdesktop/keymaps/tr | 139 + .../net/tsclient/rdesktop/licence.c | 328 + .../net/tsclient/rdesktop/lspci.c | 177 + .../applications/net/tsclient/rdesktop/mcs.c | 471 + .../applications/net/tsclient/rdesktop/mppc.c | 377 + .../net/tsclient/rdesktop/orders.c | 1390 +++ .../net/tsclient/rdesktop/orders.h | 373 + .../net/tsclient/rdesktop/parallel.c | 187 + .../net/tsclient/rdesktop/parse.h | 95 + .../net/tsclient/rdesktop/printer.c | 162 + .../net/tsclient/rdesktop/printercache.c | 300 + .../net/tsclient/rdesktop/proto.h | 323 + .../net/tsclient/rdesktop/proto.head | 27 + .../net/tsclient/rdesktop/proto.tail | 8 + .../net/tsclient/rdesktop/pstcache.c | 196 + .../tsclient/rdesktop/rdesktop-core.vcproj | 251 + .../net/tsclient/rdesktop/rdesktop.c | 1559 +++ .../net/tsclient/rdesktop/rdesktop.h | 313 + .../net/tsclient/rdesktop/rdesktop.spec | 40 + .../applications/net/tsclient/rdesktop/rdp.c | 1510 +++ .../applications/net/tsclient/rdesktop/rdp5.c | 128 + .../net/tsclient/rdesktop/rdpdr.c | 1171 +++ .../net/tsclient/rdesktop/rdpsnd.c | 255 + .../net/tsclient/rdesktop/rdpsnd_libao.c | 273 + .../net/tsclient/rdesktop/rdpsnd_oss.c | 319 + .../net/tsclient/rdesktop/rdpsnd_sgi.c | 340 + .../net/tsclient/rdesktop/rdpsnd_sun.c | 313 + .../net/tsclient/rdesktop/scancodes.h | 376 + .../net/tsclient/rdesktop/seamless.c | 449 + .../net/tsclient/rdesktop/seamless.h | 19 + .../net/tsclient/rdesktop/secure.c | 974 ++ .../net/tsclient/rdesktop/serial.c | 1074 ++ .../applications/net/tsclient/rdesktop/tcp.c | 368 + .../net/tsclient/rdesktop/types.h | 283 + .../tsclient/rdesktop/uiports/makefile_nanox | 25 + .../net/tsclient/rdesktop/uiports/makefile_qt | 77 + .../tsclient/rdesktop/uiports/makefile_qte | 24 + .../tsclient/rdesktop/uiports/makefile_svga | 36 + .../tsclient/rdesktop/uiports/makefile_xxx | 18 + .../tsclient/rdesktop/uiports/nanoxreadme.txt | 9 + .../net/tsclient/rdesktop/uiports/nanoxwin.c | 1547 +++ .../tsclient/rdesktop/uiports/qtereadme.txt | 12 + .../net/tsclient/rdesktop/uiports/qtewin.cpp | 2557 +++++ .../net/tsclient/rdesktop/uiports/qtewin.h | 107 + .../tsclient/rdesktop/uiports/qtreadme.txt | 12 + .../net/tsclient/rdesktop/uiports/qtwin.cpp | 1828 ++++ .../net/tsclient/rdesktop/uiports/qtwin.h | 32 + .../net/tsclient/rdesktop/uiports/readme.txt | 17 + .../tsclient/rdesktop/uiports/svgareadme.txt | 39 + .../net/tsclient/rdesktop/uiports/svgawin.c | 1947 ++++ .../net/tsclient/rdesktop/uiports/xxxwin.c | 365 + .../net/tsclient/rdesktop/vnc/vnc.c | 1376 +++ .../net/tsclient/rdesktop/vnc/vnc.h | 68 + .../net/tsclient/rdesktop/vnc/x11stubs.c | 1405 +++ .../net/tsclient/rdesktop/vnc/x11stubs.h | 33 + .../net/tsclient/rdesktop/xclip.c | 1109 ++ .../net/tsclient/rdesktop/xkeymap.c | 1017 ++ .../net/tsclient/rdesktop/xproto.h | 11 + .../applications/net/tsclient/rdesktop/xwin.c | 3568 +++++++ 159 files changed, 78306 insertions(+) create mode 100644 rosapps/applications/net/tsclient/MissTosca.sln create mode 100644 rosapps/applications/net/tsclient/mstsc/mstsc.cpp create mode 100644 rosapps/applications/net/tsclient/mstsc/mstsc.vcproj create mode 100644 rosapps/applications/net/tsclient/mstsc/stdafx.cpp create mode 100644 rosapps/applications/net/tsclient/mstsc/stdafx.h create mode 100644 rosapps/applications/net/tsclient/mstscax/mstscax.cpp create mode 100644 rosapps/applications/net/tsclient/mstscax/mstscax.vcproj create mode 100644 rosapps/applications/net/tsclient/mstscax/stdafx.cpp create mode 100644 rosapps/applications/net/tsclient/mstscax/stdafx.h create mode 100644 rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.cpp create mode 100644 rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.def create mode 100644 rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.sln create mode 100644 rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.vcproj create mode 100644 rosapps/applications/net/tsclient/porting-tools/mstscax/stdafx.cpp create mode 100644 rosapps/applications/net/tsclient/porting-tools/mstscax/stdafx.h create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/activex.cpp create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib.idl create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib.rc create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_h.h create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_i.c create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist.idl create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist.rc create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_h.h create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_i.c create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.vcproj create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/stdafx.cpp create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/stdafx.h create mode 100644 rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/typelib.rh create mode 100644 rosapps/applications/net/tsclient/rdesktop/COPYING create mode 100644 rosapps/applications/net/tsclient/rdesktop/Makefile.in create mode 100644 rosapps/applications/net/tsclient/rdesktop/README create mode 100644 rosapps/applications/net/tsclient/rdesktop/bitmap.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/bootstrap create mode 100644 rosapps/applications/net/tsclient/rdesktop/cache.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/channels.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/cliprdr.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/config.guess create mode 100644 rosapps/applications/net/tsclient/rdesktop/config.sub create mode 100644 rosapps/applications/net/tsclient/rdesktop/configure.ac create mode 100644 rosapps/applications/net/tsclient/rdesktop/constants.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/disk.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/disk.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/AUTHORS create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/ChangeLog create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/HACKING create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/TODO create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/ipv6.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/keymap-names.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/keymapping.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/keynums.png create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/licensing.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/lspci-channel.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/patches.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/rdesktop.1 create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/redirection.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/doc/seamlessrdp-channel.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/ewmhints.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/indent-all.sh create mode 100644 rosapps/applications/net/tsclient/rdesktop/install-sh create mode 100644 rosapps/applications/net/tsclient/rdesktop/iso.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/ar create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/common create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/convert-map create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/cs create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/da create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/de create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/de-ch create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/en-dv create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/en-gb create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/en-us create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/es create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/et create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/fi create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/fo create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/fr create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/fr-be create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/fr-ca create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/fr-ch create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/he create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/hr create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/hu create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/is create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/it create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/ja create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/ko create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/lt create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/lv create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/mk create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/modifiers create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/nl create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/nl-be create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/no create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/pl create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/pt create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/pt-br create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/ru create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/sl create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/sv create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/th create mode 100644 rosapps/applications/net/tsclient/rdesktop/keymaps/tr create mode 100644 rosapps/applications/net/tsclient/rdesktop/licence.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/lspci.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/mcs.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/mppc.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/orders.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/orders.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/parallel.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/parse.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/printer.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/printercache.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/proto.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/proto.head create mode 100644 rosapps/applications/net/tsclient/rdesktop/proto.tail create mode 100644 rosapps/applications/net/tsclient/rdesktop/pstcache.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdesktop-core.vcproj create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdesktop.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdesktop.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdesktop.spec create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdp.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdp5.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdpdr.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdpsnd.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdpsnd_libao.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdpsnd_oss.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdpsnd_sgi.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/rdpsnd_sun.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/scancodes.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/seamless.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/seamless.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/secure.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/serial.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/tcp.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/types.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/makefile_nanox create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/makefile_qt create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/makefile_qte create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/makefile_svga create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/makefile_xxx create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/nanoxreadme.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/nanoxwin.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/qtereadme.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/qtewin.cpp create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/qtewin.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/qtreadme.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/qtwin.cpp create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/qtwin.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/readme.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/svgareadme.txt create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/svgawin.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/uiports/xxxwin.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/vnc/vnc.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/vnc/vnc.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/vnc/x11stubs.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/vnc/x11stubs.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/xclip.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/xkeymap.c create mode 100644 rosapps/applications/net/tsclient/rdesktop/xproto.h create mode 100644 rosapps/applications/net/tsclient/rdesktop/xwin.c diff --git a/rosapps/applications/net/tsclient/MissTosca.sln b/rosapps/applications/net/tsclient/MissTosca.sln new file mode 100644 index 00000000000..4156cc20bc3 --- /dev/null +++ b/rosapps/applications/net/tsclient/MissTosca.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rdesktop-core", "rdesktop\rdesktop-core.vcproj", "{8620E9B2-9AF0-4F69-A5AF-C195D5F86372}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mstsc", "mstsc\mstsc.vcproj", "{1B415732-1F37-415F-957B-EA436301860D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mstscax", "mstscax\mstscax.vcproj", "{2C217E9E-9D77-4D6A-9259-216FD56BA56F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rdesktop-core-tester", "porting-tools\rdesktop-core-tester\rdesktop-core-tester.vcproj", "{B172A623-E2BD-4E3F-86E6-620548FE255B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8620E9B2-9AF0-4F69-A5AF-C195D5F86372}.Debug|Win32.ActiveCfg = Debug|Win32 + {8620E9B2-9AF0-4F69-A5AF-C195D5F86372}.Debug|Win32.Build.0 = Debug|Win32 + {8620E9B2-9AF0-4F69-A5AF-C195D5F86372}.Release|Win32.ActiveCfg = Release|Win32 + {8620E9B2-9AF0-4F69-A5AF-C195D5F86372}.Release|Win32.Build.0 = Release|Win32 + {1B415732-1F37-415F-957B-EA436301860D}.Debug|Win32.ActiveCfg = Debug|Win32 + {1B415732-1F37-415F-957B-EA436301860D}.Debug|Win32.Build.0 = Debug|Win32 + {1B415732-1F37-415F-957B-EA436301860D}.Release|Win32.ActiveCfg = Release|Win32 + {1B415732-1F37-415F-957B-EA436301860D}.Release|Win32.Build.0 = Release|Win32 + {2C217E9E-9D77-4D6A-9259-216FD56BA56F}.Debug|Win32.ActiveCfg = Debug|Win32 + {2C217E9E-9D77-4D6A-9259-216FD56BA56F}.Debug|Win32.Build.0 = Debug|Win32 + {2C217E9E-9D77-4D6A-9259-216FD56BA56F}.Release|Win32.ActiveCfg = Release|Win32 + {2C217E9E-9D77-4D6A-9259-216FD56BA56F}.Release|Win32.Build.0 = Release|Win32 + {B172A623-E2BD-4E3F-86E6-620548FE255B}.Debug|Win32.ActiveCfg = Debug|Win32 + {B172A623-E2BD-4E3F-86E6-620548FE255B}.Debug|Win32.Build.0 = Debug|Win32 + {B172A623-E2BD-4E3F-86E6-620548FE255B}.Release|Win32.ActiveCfg = Release|Win32 + {B172A623-E2BD-4E3F-86E6-620548FE255B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/rosapps/applications/net/tsclient/mstsc/mstsc.cpp b/rosapps/applications/net/tsclient/mstsc/mstsc.cpp new file mode 100644 index 00000000000..106d7296c01 --- /dev/null +++ b/rosapps/applications/net/tsclient/mstsc/mstsc.cpp @@ -0,0 +1,7 @@ +#include "stdafx.h" + +int _tmain(int argc, _TCHAR* argv[]) +{ + return 0; +} + diff --git a/rosapps/applications/net/tsclient/mstsc/mstsc.vcproj b/rosapps/applications/net/tsclient/mstsc/mstsc.vcproj new file mode 100644 index 00000000000..a6d58a9cc1c --- /dev/null +++ b/rosapps/applications/net/tsclient/mstsc/mstsc.vcproj @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/applications/net/tsclient/mstsc/stdafx.cpp b/rosapps/applications/net/tsclient/mstsc/stdafx.cpp new file mode 100644 index 00000000000..f7caa754005 --- /dev/null +++ b/rosapps/applications/net/tsclient/mstsc/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// mstsc.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/rosapps/applications/net/tsclient/mstsc/stdafx.h b/rosapps/applications/net/tsclient/mstsc/stdafx.h new file mode 100644 index 00000000000..ddacb46d869 --- /dev/null +++ b/rosapps/applications/net/tsclient/mstsc/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/rosapps/applications/net/tsclient/mstscax/mstscax.cpp b/rosapps/applications/net/tsclient/mstscax/mstscax.cpp new file mode 100644 index 00000000000..106d7296c01 --- /dev/null +++ b/rosapps/applications/net/tsclient/mstscax/mstscax.cpp @@ -0,0 +1,7 @@ +#include "stdafx.h" + +int _tmain(int argc, _TCHAR* argv[]) +{ + return 0; +} + diff --git a/rosapps/applications/net/tsclient/mstscax/mstscax.vcproj b/rosapps/applications/net/tsclient/mstscax/mstscax.vcproj new file mode 100644 index 00000000000..7b3b3b0144f --- /dev/null +++ b/rosapps/applications/net/tsclient/mstscax/mstscax.vcproj @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/applications/net/tsclient/mstscax/stdafx.cpp b/rosapps/applications/net/tsclient/mstscax/stdafx.cpp new file mode 100644 index 00000000000..9a99ced5d1d --- /dev/null +++ b/rosapps/applications/net/tsclient/mstscax/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// mstscax.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/rosapps/applications/net/tsclient/mstscax/stdafx.h b/rosapps/applications/net/tsclient/mstscax/stdafx.h new file mode 100644 index 00000000000..ddacb46d869 --- /dev/null +++ b/rosapps/applications/net/tsclient/mstscax/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.cpp b/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.cpp new file mode 100644 index 00000000000..0f01f402370 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.cpp @@ -0,0 +1,5011 @@ +#include "stdafx.h" + +namespace +{ + using namespace MSTSCLib; + + typedef HRESULT (STDAPICALLTYPE * PFNDLLGETCLASSOBJECT)(IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID FAR * ppv); + typedef HRESULT (STDAPICALLTYPE * PFNDLLCANUNLOADNOW)(void); + typedef ULONG (STDAPICALLTYPE * PFNDLLGETTSCCTLVER)(void); + + PFNDLLGETCLASSOBJECT pfnDllGetClassObject = NULL; + PFNDLLCANUNLOADNOW pfnDllCanUnloadNow = NULL; + PFNDLLGETTSCCTLVER pfnDllGetTscCtlVer = NULL; + + HMODULE hmMstscax = NULL; + + extern "C" char __ImageBase; + static const HMODULE hmSelf = reinterpret_cast(&__ImageBase); + + void init() + { + if(hmMstscax) + return; + + TCHAR szFileName[MAX_PATH + 1]; + GetModuleFileName(hmSelf, szFileName, MAX_PATH); + + std::basic_string strFileName(&szFileName[0]); + std::reverse_iterator::const_iterator > begin(strFileName.end()); + std::reverse_iterator::const_iterator > end(strFileName.begin()); + std::basic_string::const_iterator endPath = std::find(begin, end, TEXT('\\')).base(); + + std::basic_string strPath(strFileName.begin(), endPath); + strPath.append(TEXT("original\\mstscax.dll")); + + hmMstscax = LoadLibrary(strPath.c_str()); + pfnDllGetClassObject = (PFNDLLGETCLASSOBJECT)GetProcAddress(hmMstscax, "DllGetClassObject"); + pfnDllCanUnloadNow = (PFNDLLCANUNLOADNOW)GetProcAddress(hmMstscax, "DllCanUnloadNow"); + pfnDllGetTscCtlVer = (PFNDLLGETTSCCTLVER)GetProcAddress(hmMstscax, "DllGetTscCtlVer"); + } + + void dbgprintf(LPCTSTR fmt, ...) + { + TCHAR buf[0x1000]; + + va_list args; + va_start(args, fmt); + StringCbVPrintf(buf, sizeof(buf), fmt, args); + va_end(args); + + StringCbCat(buf, sizeof(buf), TEXT("\n")); + + OutputDebugString(buf); + } + +#if 0 + const IID MsTscAxIIDs[] = + { + IID_IMsRdpClient, + IID_IMsTscAx, + //IID_IMsTscAxEvents, + IID_IMsTscNonScriptable, + IID_IMsRdpClientNonScriptable, + }; + + const IID MsRdpClient[] = + { + IID_IMsRdpClient, + IID_IMsTscAx, + //IID_IMsTscAxEvents, + IID_IMsTscNonScriptable, + IID_IMsRdpClientNonScriptable, + }; + + const IID MsRdpClient2[] = + { + IID_IMsRdpClient2, + IID_IMsRdpClient, + IID_IMsTscAx, + //IID_IMsTscAxEvents, + IID_IMsTscNonScriptable, + IID_IMsRdpClientNonScriptable, + }; + + const IID MsRdpClient3[] = + { + IID_IMsRdpClient3, + IID_IMsRdpClient2, + IID_IMsRdpClient, + IID_IMsTscAx, + //IID_IMsTscAxEvents, + IID_IMsTscNonScriptable, + IID_IMsRdpClientNonScriptable, + }; + + const IID MsRdpClient4[] = + { + IID_IMsRdpClient4, + IID_IMsRdpClient3, + IID_IMsRdpClient2, + IID_IMsRdpClient, + IID_IMsTscAx, + //IID_IMsTscAxEvents, + IID_IMsTscNonScriptable, + IID_IMsRdpClientNonScriptable, + IID_IMsRdpClientNonScriptable2, + }; +#endif + + std::wstring UUIDToString(const UUID& uuid) + { + std::wstring s; + LPOLESTR str; + StringFromCLSID(uuid, &str); + s += str; + CoTaskMemFree(str); + return s; + } + + std::wstring MonikerToString(IMoniker * pmk) + { + LPOLESTR pszName = NULL; + + if(SUCCEEDED(pmk->GetDisplayName(NULL, NULL, &pszName))) + { + std::wstring s(pszName); + CoTaskMemFree(pszName); + return s; + } + else + return std::wstring(L""); + } + + std::basic_string RectToString(const RECT& rc) + { + if(&rc == NULL) + return TEXT(""); + + std::basic_ostringstream o; + o << "{" << " left:" << rc.left << " top:" << rc.top << " right:" << rc.right << " bottom:" << rc.bottom << " }"; + return o.str(); + } + + std::basic_string RectToString(const RECTL& rc) + { + if(&rc == NULL) + return TEXT(""); + + std::basic_ostringstream o; + o << "{" << " left:" << rc.left << " top:" << rc.top << " right:" << rc.right << " bottom:" << rc.bottom << " }"; + return o.str(); + } + + std::basic_string SizeToString(const SIZE& sz) + { + if(&sz == NULL) + return TEXT(""); + + std::basic_ostringstream o; + o << "{ " << " cx:" << sz.cx << " cy:" << sz.cy << " }"; + return o.str(); + } + + template LPCTSTR BooleanToString(const T& X) + { + return X ? TEXT("true") : TEXT("false"); + } + + std::basic_string VariantToString(const VARIANT& var) + { + std::basic_ostringstream o; + + switch(var.vt & VT_TYPEMASK) + { + case VT_EMPTY: o << ""; break; + case VT_NULL: o << ""; break; + case VT_I2: o << "short"; break; + case VT_I4: o << "long"; break; + case VT_R4: o << "float"; break; + case VT_R8: o << "double"; break; + case VT_CY: o << "CURRENCY"; break; + case VT_DATE: o << "DATE"; break; + case VT_BSTR: o << "string"; break; + case VT_DISPATCH: o << "IDispatch *"; break; + case VT_ERROR: o << "SCODE"; break; + case VT_BOOL: o << "bool"; break; + case VT_VARIANT: o << "VARIANT *"; break; + case VT_UNKNOWN: o << "IUnknown *"; break; + case VT_DECIMAL: o << "DECIMAL"; break; + case VT_I1: o << "char"; break; + case VT_UI1: o << "unsigned char"; break; + case VT_UI2: o << "unsigned short"; break; + case VT_UI4: o << "unsigned long"; break; + case VT_I8: o << "long long"; break; + case VT_UI8: o << "unsigned long long"; break; + case VT_INT: o << "int"; break; + case VT_UINT: o << "unsigned int"; break; + case VT_VOID: o << "void"; break; + case VT_HRESULT: o << "HRESULT"; break; + case VT_PTR: o << "void *"; break; + case VT_SAFEARRAY: o << "SAFEARRAY *"; break; + case VT_LPSTR: o << "LPSTR"; break; + case VT_LPWSTR: o << "LPWSTR"; break; + case VT_RECORD: o << "struct { }"; break; + case VT_INT_PTR: o << "intptr_t"; break; + case VT_UINT_PTR: o << "uintptr_t"; break; + case VT_FILETIME: o << "FILETIME"; break; + default: o << "???"; break; + } + + if(var.vt & VT_ARRAY) + o << "[]"; + else if(var.vt & VT_BYREF) + o << " *"; + else + { + switch(var.vt & VT_TYPEMASK) + { + case VT_EMPTY: + case VT_NULL: + case VT_RECORD: + case VT_VOID: + + // TODO + case VT_CY: + case VT_DATE: + case VT_DECIMAL: + case VT_FILETIME: + break; + + default: + o << " = "; + } + + switch(var.vt & VT_TYPEMASK) + { + case VT_I2: o << var.iVal; break; + case VT_I4: o << var.lVal; break; + case VT_R4: o << var.fltVal; break; + case VT_R8: o << var.dblVal; break; + case VT_BSTR: o << std::wstring(var.bstrVal, var.bstrVal + SysStringLen(var.bstrVal)); break; + case VT_BOOL: o << var.boolVal ? "true" : "false"; break; + case VT_I1: o << int(var.cVal); break; + case VT_UI1: o << unsigned int(var.bVal); break; + case VT_UI2: o << var.uiVal; break; + case VT_UI4: o << var.ulVal; break; + case VT_I8: o << var.llVal; break; + case VT_UI8: o << var.ullVal; break; + case VT_INT: o << var.intVal; break; + case VT_UINT: o << var.uintVal; break; + case VT_LPSTR: o << LPSTR(var.byref); break; + case VT_LPWSTR: o << LPWSTR(var.byref); break; + case VT_INT_PTR: o << var.intVal; break; // BUGBUG + case VT_UINT_PTR: o << var.uintVal; break; // BUGBUG + + case VT_DISPATCH: + case VT_VARIANT: + case VT_UNKNOWN: + case VT_PTR: + case VT_SAFEARRAY: + case VT_RECORD: + o << var.byref; break; + + case VT_ERROR: + case VT_HRESULT: + o << std::hex << var.ulVal; break; + + case VT_EMPTY: + case VT_NULL: + case VT_VOID: + break; + + default: + assert(0); + } + } + + return o.str(); + } + +#pragma warning(disable:4584) + + IConnectionPointContainer * HookIConnectionPointContainer(IConnectionPointContainer * p); + IEnumConnectionPoints * HookIEnumConnectionPoints(IEnumConnectionPoints * p); + IConnectionPoint * HookIConnectionPoint(IConnectionPoint * p); + IEnumConnections * HookIEnumConnections(IEnumConnections * p); + + class CConnectionPointContainer: public IConnectionPointContainer + { + private: + LONG m_refCount; + IConnectionPointContainer * m_IConnectionPointContainer; + + public: + CConnectionPointContainer(IConnectionPointContainer * pIConnectionPointContainer): + m_refCount(1), + m_IConnectionPointContainer(pIConnectionPointContainer) + { } + + ~CConnectionPointContainer() { m_IConnectionPointContainer->Release(); } + + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) + { + HRESULT hr = S_OK; + + dbgprintf(TEXT("CConnectionPointContainer::QueryInterface(%ls, %p)"), UUIDToString(riid).c_str(), ppvObject); + + if(riid == IID_IUnknown || riid == IID_IConnectionPointContainer) + *ppvObject = this; + else + { + *ppvObject = NULL; + hr = E_NOINTERFACE; + } + + dbgprintf(TEXT("CConnectionPointContainer::QueryInterface -> %08X, ppvObject = %p"), hr, *ppvObject); + return hr; + } + + virtual ULONG STDMETHODCALLTYPE AddRef(void) + { + return InterlockedIncrement(&m_refCount); + } + + virtual ULONG STDMETHODCALLTYPE Release(void) + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + virtual HRESULT STDMETHODCALLTYPE EnumConnectionPoints(IEnumConnectionPoints ** ppEnum) + { + dbgprintf(TEXT("CConnectionPointContainer::EnumConnectionPoints(%p)"), ppEnum); + HRESULT hr = m_IConnectionPointContainer->EnumConnectionPoints(ppEnum); + dbgprintf(TEXT("CConnectionPointContainer::EnumConnectionPoints -> %08X, pEnum = %p"), hr, *ppEnum); + + if(SUCCEEDED(hr)) + *ppEnum = HookIEnumConnectionPoints(*ppEnum); + + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE FindConnectionPoint(REFIID riid, IConnectionPoint ** ppCP) + { + dbgprintf(TEXT("CConnectionPointContainer::FindConnectionPoint(%ls, %p)"), UUIDToString(riid).c_str(), ppCP); + HRESULT hr = m_IConnectionPointContainer->FindConnectionPoint(riid, ppCP); + dbgprintf(TEXT("CConnectionPointContainer::FindConnectionPoint -> %08X, pCP = %p"), hr, *ppCP); + + if(SUCCEEDED(hr)) + *ppCP = HookIConnectionPoint(*ppCP); + + return hr; + } + }; + + class CEnumConnectionPoints: public IEnumConnectionPoints + { + private: + LONG m_refCount; + IEnumConnectionPoints * m_IEnumConnectionPoints; + + public: + CEnumConnectionPoints(IEnumConnectionPoints * pIEnumConnectionPoints): + m_refCount(1), + m_IEnumConnectionPoints(pIEnumConnectionPoints) + { } + + ~CEnumConnectionPoints() { m_IEnumConnectionPoints->Release(); } + + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) + { + HRESULT hr = S_OK; + + dbgprintf(TEXT("CEnumConnectionPoints::QueryInterface(%ls, %p)"), UUIDToString(riid).c_str(), ppvObject); + + if(riid == IID_IUnknown || riid == IID_IEnumConnectionPoints) + *ppvObject = this; + else + { + *ppvObject = NULL; + hr = E_NOINTERFACE; + } + + dbgprintf(TEXT("CEnumConnectionPoints::QueryInterface -> %08X, ppvObject = %p"), hr, *ppvObject); + return hr; + } + + virtual ULONG STDMETHODCALLTYPE AddRef(void) + { + return InterlockedIncrement(&m_refCount); + } + + virtual ULONG STDMETHODCALLTYPE Release(void) + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + virtual HRESULT STDMETHODCALLTYPE Next(ULONG cConnections, LPCONNECTIONPOINT * ppCP, ULONG * pcFetched) + { + dbgprintf(TEXT("CEnumConnectionPoints::Next(%lu, %p, %p)"), cConnections, ppCP, pcFetched); + HRESULT hr = m_IEnumConnectionPoints->Next(cConnections, ppCP, pcFetched); + dbgprintf(TEXT("CEnumConnectionPoints:: -> %08X, pCP = %p, cFetched = %lu"), hr, *ppCP, *pcFetched); + + if(SUCCEEDED(hr)) + *ppCP = HookIConnectionPoint(*ppCP); + + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Skip(ULONG cConnections) + { + dbgprintf(TEXT("CEnumConnectionPoints::Skip(%lu)"), cConnections); + HRESULT hr = m_IEnumConnectionPoints->Skip(cConnections); + dbgprintf(TEXT("CEnumConnectionPoints:: -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Reset(void) + { + dbgprintf(TEXT("CEnumConnectionPoints::Reset()")); + HRESULT hr = m_IEnumConnectionPoints->Reset(); + dbgprintf(TEXT("CEnumConnectionPoints:: -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Clone(IEnumConnectionPoints ** ppEnum) + { + dbgprintf(TEXT("CEnumConnectionPoints::Clone(%p)"), ppEnum); + HRESULT hr = m_IEnumConnectionPoints->Clone(ppEnum); + dbgprintf(TEXT("CEnumConnectionPoints:: -> %08X, pEnum"), hr, *ppEnum); + + if(SUCCEEDED(hr)) + *ppEnum = HookIEnumConnectionPoints(*ppEnum); + + return hr; + } + }; + + class CConnectionPoint: public IConnectionPoint + { + private: + LONG m_refCount; + IConnectionPoint * m_IConnectionPoint; + + public: + CConnectionPoint(IConnectionPoint * pIConnectionPoint): + m_refCount(1), + m_IConnectionPoint(pIConnectionPoint) + { } + + ~CConnectionPoint() { m_IConnectionPoint->Release(); } + + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) + { + HRESULT hr = S_OK; + + dbgprintf(TEXT("CConnectionPoint::QueryInterface(%ls, %p)"), UUIDToString(riid).c_str(), ppvObject); + + if(riid == IID_IUnknown || riid == IID_IConnectionPoint) + *ppvObject = this; + else + { + *ppvObject = NULL; + hr = E_NOINTERFACE; + } + + dbgprintf(TEXT("CConnectionPoint::QueryInterface -> %08X, ppvObject = %p"), hr, *ppvObject); + return hr; + } + + virtual ULONG STDMETHODCALLTYPE AddRef(void) + { + return InterlockedIncrement(&m_refCount); + } + + virtual ULONG STDMETHODCALLTYPE Release(void) + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + virtual HRESULT STDMETHODCALLTYPE GetConnectionInterface(IID * pIID) + { + dbgprintf(TEXT("CConnectionPoint::GetConnectionInterface(%p)"), pIID); + HRESULT hr = m_IConnectionPoint->GetConnectionInterface(pIID); + dbgprintf(TEXT("CConnectionPoint::GetConnectionInterface -> %08X, IID = %ls"), hr, UUIDToString(*pIID).c_str()); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetConnectionPointContainer(IConnectionPointContainer ** ppCPC) + { + dbgprintf(TEXT("CConnectionPoint::GetConnectionPointContainer(%p)"), ppCPC); + HRESULT hr = m_IConnectionPoint->GetConnectionPointContainer(ppCPC); + dbgprintf(TEXT("CConnectionPoint::GetConnectionPointContainer -> %08X, pCPC = %p"), hr, *ppCPC); + + if(SUCCEEDED(hr)) + *ppCPC = HookIConnectionPointContainer(*ppCPC); + + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Advise(IUnknown * pUnkSink, DWORD * pdwCookie) + { + dbgprintf(TEXT("CConnectionPoint::Advise(%p, %p)"), pUnkSink, pdwCookie); + HRESULT hr = m_IConnectionPoint->Advise(pUnkSink, pdwCookie); + dbgprintf(TEXT("CConnectionPoint::Advise -> %08X, dwCookie = %lu"), hr, *pdwCookie); + // TODO: hook sink + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Unadvise(DWORD dwCookie) + { + dbgprintf(TEXT("CConnectionPoint::Unadvise(%lu)"), dwCookie); + HRESULT hr = m_IConnectionPoint->Unadvise(dwCookie); + dbgprintf(TEXT("CConnectionPoint::Unadvise -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE EnumConnections(IEnumConnections ** ppEnum) + { + dbgprintf(TEXT("CConnectionPoint::EnumConnections(%p)"), ppEnum); + HRESULT hr = m_IConnectionPoint->EnumConnections(ppEnum); + dbgprintf(TEXT("CConnectionPoint::EnumConnections -> %08X, pEnum = %p"), hr, *ppEnum); + + if(SUCCEEDED(hr)) + *ppEnum = HookIEnumConnections(*ppEnum); + + return hr; + } + }; + + class CEnumConnections: public IEnumConnections + { + private: + LONG m_refCount; + IEnumConnections * m_IEnumConnections; + + public: + CEnumConnections(IEnumConnections * pIEnumConnections): + m_refCount(1), + m_IEnumConnections(pIEnumConnections) + { } + + ~CEnumConnections() { m_IEnumConnections->Release(); } + + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) + { + HRESULT hr = S_OK; + + dbgprintf(TEXT("CEnumConnections::QueryInterface(%ls, %p)"), UUIDToString(riid).c_str(), ppvObject); + + if(riid == IID_IUnknown || riid == IID_IEnumConnections) + *ppvObject = this; + else + { + *ppvObject = NULL; + hr = E_NOINTERFACE; + } + + dbgprintf(TEXT("CEnumConnections::QueryInterface -> %08X, ppvObject = %p"), hr, *ppvObject); + return hr; + } + + virtual ULONG STDMETHODCALLTYPE AddRef(void) + { + return InterlockedIncrement(&m_refCount); + } + + virtual ULONG STDMETHODCALLTYPE Release(void) + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + virtual HRESULT STDMETHODCALLTYPE Next(ULONG cConnections, LPCONNECTDATA pCD, ULONG * pcFetched) + { + dbgprintf(TEXT("CEnumConnections::Next(%lu, %p, %p)"), cConnections, pCD, pcFetched); + HRESULT hr = m_IEnumConnections->Next(cConnections, pCD, pcFetched); + dbgprintf(TEXT("CEnumConnections:: -> %08X, CD = { pUnk = %p, dwCookie = %lu }, cFetched = %lu"), hr, pCD->pUnk, pCD->dwCookie, *pcFetched); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Skip(ULONG cConnections) + { + dbgprintf(TEXT("CEnumConnections::Skip(%lu)"), cConnections); + HRESULT hr = m_IEnumConnections->Skip(cConnections); + dbgprintf(TEXT("CEnumConnections:: -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Reset(void) + { + dbgprintf(TEXT("CEnumConnections::Reset()")); + HRESULT hr = m_IEnumConnections->Reset(); + dbgprintf(TEXT("CEnumConnections:: -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Clone(IEnumConnections ** ppEnum) + { + dbgprintf(TEXT("CEnumConnections::Clone(%p)"), ppEnum); + HRESULT hr = m_IEnumConnections->Clone(ppEnum); + dbgprintf(TEXT("CEnumConnections:: -> %08X, pEnum"), hr, *ppEnum); + + if(SUCCEEDED(hr)) + *ppEnum = HookIEnumConnections(*ppEnum); + + return hr; + } + }; + + IConnectionPointContainer * HookIConnectionPointContainer(IConnectionPointContainer * p) + { + return new CConnectionPointContainer(p); + } + + IEnumConnectionPoints * HookIEnumConnectionPoints(IEnumConnectionPoints * p) + { + return new CEnumConnectionPoints(p); + } + + IConnectionPoint * HookIConnectionPoint(IConnectionPoint * p) + { + return new CConnectionPoint(p); + } + + IEnumConnections * HookIEnumConnections(IEnumConnections * p) + { + return new CEnumConnections(p); + } + + class CAdvancedSettings: public IMsRdpClientAdvancedSettings4 + { + private: + LONG m_refCount; + IUnknown * m_IUnknown; + IDispatch * m_IDispatch; + IMsTscAdvancedSettings * m_IMsTscAdvancedSettings; + IMsRdpClientAdvancedSettings * m_IMsRdpClientAdvancedSettings; + IMsRdpClientAdvancedSettings2 * m_IMsRdpClientAdvancedSettings2; + IMsRdpClientAdvancedSettings3 * m_IMsRdpClientAdvancedSettings3; + IMsRdpClientAdvancedSettings4 * m_IMsRdpClientAdvancedSettings4; + + IDispatch * getIDispatch() + { + assert(m_IDispatch); + return m_IDispatch; + } + + IMsTscAdvancedSettings * getIMsTscAdvancedSettings() + { + if(m_IMsTscAdvancedSettings) + return m_IMsTscAdvancedSettings; + else if(m_IMsRdpClientAdvancedSettings) + m_IMsTscAdvancedSettings = m_IMsRdpClientAdvancedSettings; + else if(m_IMsRdpClientAdvancedSettings2) + m_IMsTscAdvancedSettings = m_IMsRdpClientAdvancedSettings2; + else if(m_IMsRdpClientAdvancedSettings3) + m_IMsTscAdvancedSettings = m_IMsRdpClientAdvancedSettings3; + else if(m_IMsRdpClientAdvancedSettings4) + m_IMsTscAdvancedSettings = m_IMsRdpClientAdvancedSettings4; + + if(m_IMsTscAdvancedSettings) + { + m_IMsTscAdvancedSettings->AddRef(); + return m_IMsTscAdvancedSettings; + } + + m_IUnknown->QueryInterface(&m_IMsTscAdvancedSettings); + return m_IMsTscAdvancedSettings; + } + + IMsRdpClientAdvancedSettings * getIMsRdpClientAdvancedSettings() + { + if(m_IMsRdpClientAdvancedSettings) + return m_IMsRdpClientAdvancedSettings; + else if(m_IMsRdpClientAdvancedSettings2) + m_IMsRdpClientAdvancedSettings = m_IMsRdpClientAdvancedSettings2; + else if(m_IMsRdpClientAdvancedSettings3) + m_IMsRdpClientAdvancedSettings = m_IMsRdpClientAdvancedSettings3; + else if(m_IMsRdpClientAdvancedSettings4) + m_IMsRdpClientAdvancedSettings = m_IMsRdpClientAdvancedSettings4; + + if(m_IMsRdpClientAdvancedSettings) + { + m_IMsRdpClientAdvancedSettings->AddRef(); + return m_IMsRdpClientAdvancedSettings; + } + + m_IUnknown->QueryInterface(&m_IMsRdpClientAdvancedSettings); + return m_IMsRdpClientAdvancedSettings; + } + + IMsRdpClientAdvancedSettings2 * getIMsRdpClientAdvancedSettings2() + { + if(m_IMsRdpClientAdvancedSettings2) + return m_IMsRdpClientAdvancedSettings2; + else if(m_IMsRdpClientAdvancedSettings3) + m_IMsRdpClientAdvancedSettings2 = m_IMsRdpClientAdvancedSettings3; + else if(m_IMsRdpClientAdvancedSettings4) + m_IMsRdpClientAdvancedSettings2 = m_IMsRdpClientAdvancedSettings4; + + if(m_IMsRdpClientAdvancedSettings2) + { + m_IMsRdpClientAdvancedSettings2->AddRef(); + return m_IMsRdpClientAdvancedSettings2; + } + + m_IUnknown->QueryInterface(&m_IMsRdpClientAdvancedSettings2); + return m_IMsRdpClientAdvancedSettings2; + } + + IMsRdpClientAdvancedSettings3 * getIMsRdpClientAdvancedSettings3() + { + if(m_IMsRdpClientAdvancedSettings3) + return m_IMsRdpClientAdvancedSettings3; + else if(m_IMsRdpClientAdvancedSettings4) + m_IMsRdpClientAdvancedSettings3 = m_IMsRdpClientAdvancedSettings4; + + if(m_IMsRdpClientAdvancedSettings3) + { + m_IMsRdpClientAdvancedSettings3->AddRef(); + return m_IMsRdpClientAdvancedSettings3; + } + + m_IUnknown->QueryInterface(&m_IMsRdpClientAdvancedSettings3); + return m_IMsRdpClientAdvancedSettings3; + } + + IMsRdpClientAdvancedSettings4 * getIMsRdpClientAdvancedSettings4() + { + if(m_IMsRdpClientAdvancedSettings4) + return m_IMsRdpClientAdvancedSettings4; + + if(m_IMsRdpClientAdvancedSettings4) + { + m_IMsRdpClientAdvancedSettings4->AddRef(); + return m_IMsRdpClientAdvancedSettings4; + } + + m_IUnknown->QueryInterface(&m_IMsRdpClientAdvancedSettings4); + return m_IMsRdpClientAdvancedSettings4; + } + + ~CAdvancedSettings() + { + m_IUnknown->Release(); + m_IDispatch->Release(); + + if(m_IMsTscAdvancedSettings) + m_IMsTscAdvancedSettings->Release(); + + if(m_IMsRdpClientAdvancedSettings) + m_IMsRdpClientAdvancedSettings->Release(); + + if(m_IMsRdpClientAdvancedSettings2) + m_IMsRdpClientAdvancedSettings2->Release(); + + if(m_IMsRdpClientAdvancedSettings3) + m_IMsRdpClientAdvancedSettings3->Release(); + + if(m_IMsRdpClientAdvancedSettings4) + m_IMsRdpClientAdvancedSettings4->Release(); + } + + void Init(IMsTscAdvancedSettings * p) + { + m_IMsTscAdvancedSettings = p; + } + + void Init(IMsRdpClientAdvancedSettings * p) + { + m_IMsRdpClientAdvancedSettings = p; + } + + void Init(IMsRdpClientAdvancedSettings2 * p) + { + m_IMsRdpClientAdvancedSettings2 = p; + } + + void Init(IMsRdpClientAdvancedSettings3 * p) + { + m_IMsRdpClientAdvancedSettings3 = p; + } + + void Init(IMsRdpClientAdvancedSettings4 * p) + { + m_IMsRdpClientAdvancedSettings4 = p; + } + + public: + template CAdvancedSettings(Interface * p): + m_refCount(1), + m_IUnknown(p), + m_IDispatch(p), + m_IMsTscAdvancedSettings(NULL), + m_IMsRdpClientAdvancedSettings(NULL), + m_IMsRdpClientAdvancedSettings2(NULL), + m_IMsRdpClientAdvancedSettings3(NULL), + m_IMsRdpClientAdvancedSettings4(NULL) + { + assert(p); + p->AddRef(); + p->AddRef(); + Init(p); + } + + /* IUnknown */ + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) + { + HRESULT hr; + IUnknown * pvObject; + + dbgprintf(TEXT("CAdvancedSettings::QueryInterface(%ls, %p)"), UUIDToString(riid).c_str(), ppvObject); + +#define QIBEGIN() \ + if(riid == IID_IUnknown) \ + { \ + hr = S_OK; \ + pvObject = (IUnknown *)(this); \ + } + +#define QI(I) \ + else if(riid == IID_ ## I) \ + { \ + if(m_ ## I) \ + { \ + m_ ## I->AddRef(); \ + hr = S_OK; \ + } \ + else \ + { \ + hr = m_IUnknown->QueryInterface(&m_ ## I); \ + } \ + \ + if(SUCCEEDED(hr)) \ + pvObject = static_cast(this); \ + } + +#define QIEND() \ + else \ + { \ + hr = E_NOINTERFACE; \ + pvObject = NULL; \ + } + + QIBEGIN() + QI(IDispatch) + QI(IMsTscAdvancedSettings) + QI(IMsRdpClientAdvancedSettings) + QI(IMsRdpClientAdvancedSettings2) + QI(IMsRdpClientAdvancedSettings3) + QI(IMsRdpClientAdvancedSettings4) + QIEND() + +#undef QIBEGIN +#undef QIEND +#undef QI + + if(SUCCEEDED(hr)) + { + assert(pvObject); + pvObject->AddRef(); + } + else + { + assert(pvObject == NULL); + } + + *ppvObject = pvObject; + + dbgprintf(TEXT("CAdvancedSettings::QueryInterface -> %08X, ppvObject = %p"), hr, *ppvObject); + return hr; + } + + virtual ULONG STDMETHODCALLTYPE AddRef(void) + { + return InterlockedIncrement(&m_refCount); + } + + virtual ULONG STDMETHODCALLTYPE Release(void) + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + /* IDispatch */ + /* + * p = get(); + dbgprintf(TEXT("CAdvancedSettings::()"), ); + HRESULT hr = p->(); + dbgprintf(TEXT("CAdvancedSettings:: -> %08X, "), hr, ); + return hr; + */ + virtual STDMETHODIMP IDispatch::GetTypeInfoCount(UINT * pctinfo) + { + IDispatch * pIDispatch = getIDispatch(); + dbgprintf(TEXT("CAdvancedSettings::GetTypeInfoCount(%p)"), pctinfo); + HRESULT hr = pIDispatch->GetTypeInfoCount(pctinfo); + dbgprintf(TEXT("CAdvancedSettings::GetTypeInfoCount -> %08X, ctinfo = %u"), hr, *pctinfo); + return hr; + } + + virtual STDMETHODIMP IDispatch::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) + { + IDispatch * pIDispatch = getIDispatch(); + dbgprintf(TEXT("CAdvancedSettings::GetTypeInfo(%u, %lu, %p)"), iTInfo, lcid, ppTInfo); + HRESULT hr = pIDispatch->GetTypeInfo(iTInfo, lcid, ppTInfo); + dbgprintf(TEXT("CAdvancedSettings::GetTypeInfo -> %08X, pTInfo = %p"), hr, *ppTInfo); + return hr; + } + + virtual STDMETHODIMP IDispatch::GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) + { + IDispatch * pIDispatch = getIDispatch(); + dbgprintf(TEXT("CAdvancedSettings::GetIDsOfNames(%ls, %ls, %d, %lu, %p)"), UUIDToString(riid).c_str(), *rgszNames, cNames, lcid, rgDispId); + HRESULT hr = pIDispatch->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId); + dbgprintf(TEXT("CAdvancedSettings::GetIDsOfNames -> %08X, rgDispId = %ld"), hr, *rgDispId); + return hr; + } + + virtual STDMETHODIMP IDispatch::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) + { + // TODO + IDispatch * pIDispatch = getIDispatch(); + dbgprintf(TEXT("CAdvancedSettings::Invoke()")/*, */); + HRESULT hr = pIDispatch->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + dbgprintf(TEXT("CAdvancedSettings::Invoke -> %08X, "), hr/*, */); + return hr; + } + + /* IMsTscAdvancedSettings */ + virtual STDMETHODIMP IMsTscAdvancedSettings::put_Compress(long pcompress) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_Compress(%ld)"), pcompress); + HRESULT hr = pIMsTscAdvancedSettings->put_Compress(pcompress); + dbgprintf(TEXT("CAdvancedSettings::put_Compress -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_Compress(long * pcompress) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_Compress(%p)"), pcompress); + HRESULT hr = pIMsTscAdvancedSettings->get_Compress(pcompress); + dbgprintf(TEXT("CAdvancedSettings::get_Compress -> %08X, compress = %ld"), hr, *pcompress); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_BitmapPeristence(long pbitmapPeristence) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapPeristence(%ld)"), pbitmapPeristence); + HRESULT hr = pIMsTscAdvancedSettings->put_BitmapPeristence(pbitmapPeristence); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapPeristence -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_BitmapPeristence(long * pbitmapPeristence) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapPeristence(%p)"), pbitmapPeristence); + HRESULT hr = pIMsTscAdvancedSettings->get_BitmapPeristence(pbitmapPeristence); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapPeristence -> %08X, bitmapPeristence = %ld"), hr, *pbitmapPeristence); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_allowBackgroundInput(long pallowBackgroundInput) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_allowBackgroundInput(%ld)"), pallowBackgroundInput); + HRESULT hr = pIMsTscAdvancedSettings->put_allowBackgroundInput(pallowBackgroundInput); + dbgprintf(TEXT("CAdvancedSettings::put_allowBackgroundInput -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_allowBackgroundInput(long * pallowBackgroundInput) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_allowBackgroundInput(%p)"), pallowBackgroundInput); + HRESULT hr = pIMsTscAdvancedSettings->get_allowBackgroundInput(pallowBackgroundInput); + dbgprintf(TEXT("CAdvancedSettings::get_allowBackgroundInput -> %08X, allowBackgroundInput = %ld"), hr, *pallowBackgroundInput); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_KeyBoardLayoutStr(BSTR rhs) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_KeyBoardLayoutStr(%ls)"), rhs); + HRESULT hr = pIMsTscAdvancedSettings->put_KeyBoardLayoutStr(rhs); + dbgprintf(TEXT("CAdvancedSettings::put_KeyBoardLayoutStr -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_PluginDlls(BSTR rhs) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_PluginDlls(%ls)"), rhs); + HRESULT hr = pIMsTscAdvancedSettings->put_PluginDlls(rhs); + dbgprintf(TEXT("CAdvancedSettings::put_PluginDlls -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_IconFile(BSTR rhs) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_IconFile(%ls)"), rhs); + HRESULT hr = pIMsTscAdvancedSettings->put_IconFile(rhs); + dbgprintf(TEXT("CAdvancedSettings::put_IconFile -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_IconIndex(long rhs) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_IconIndex(%ld)"), rhs); + HRESULT hr = pIMsTscAdvancedSettings->put_IconIndex(rhs); + dbgprintf(TEXT("CAdvancedSettings::put_IconIndex -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_ContainerHandledFullScreen(long pContainerHandledFullScreen) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_ContainerHandledFullScreen(%ld)"), pContainerHandledFullScreen); + HRESULT hr = pIMsTscAdvancedSettings->put_ContainerHandledFullScreen(pContainerHandledFullScreen); + dbgprintf(TEXT("CAdvancedSettings::put_ContainerHandledFullScreen -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_ContainerHandledFullScreen(long * pContainerHandledFullScreen) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_ContainerHandledFullScreen(%p)"), pContainerHandledFullScreen); + HRESULT hr = pIMsTscAdvancedSettings->get_ContainerHandledFullScreen(pContainerHandledFullScreen); + dbgprintf(TEXT("CAdvancedSettings::get_ContainerHandledFullScreen -> %08X, ContainerHandledFullScreen = %ld"), hr, *pContainerHandledFullScreen); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_DisableRdpdr(long pDisableRdpdr) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_DisableRdpdr(%ld)"), pDisableRdpdr); + HRESULT hr = pIMsTscAdvancedSettings->put_DisableRdpdr(pDisableRdpdr); + dbgprintf(TEXT("CAdvancedSettings::put_DisableRdpdr -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_DisableRdpdr(long * pDisableRdpdr) + { + IMsTscAdvancedSettings * pIMsTscAdvancedSettings = getIMsTscAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_DisableRdpdr(%p)"), pDisableRdpdr); + HRESULT hr = pIMsTscAdvancedSettings->get_DisableRdpdr(pDisableRdpdr); + dbgprintf(TEXT("CAdvancedSettings::get_DisableRdpdr -> %08X, DisableRdpdr = %ld"), hr, *pDisableRdpdr); + return hr; + } + + /* IMsRdpClientAdvancedSettings */ + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_SmoothScroll(long psmoothScroll) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_SmoothScroll(%ld)"), psmoothScroll); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_SmoothScroll(psmoothScroll); + dbgprintf(TEXT("CAdvancedSettings::put_SmoothScroll -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_SmoothScroll(long * psmoothScroll) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_SmoothScroll(%p)"), psmoothScroll); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_SmoothScroll(psmoothScroll); + dbgprintf(TEXT("CAdvancedSettings::get_SmoothScroll -> %08X, smoothScroll = %ld"), hr, *psmoothScroll); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_AcceleratorPassthrough(long pacceleratorPassthrough) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_AcceleratorPassthrough(%ld)"), pacceleratorPassthrough); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_AcceleratorPassthrough(pacceleratorPassthrough); + dbgprintf(TEXT("CAdvancedSettings::put_AcceleratorPassthrough -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_AcceleratorPassthrough(long * pacceleratorPassthrough) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_AcceleratorPassthrough(%p)"), pacceleratorPassthrough); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_AcceleratorPassthrough(pacceleratorPassthrough); + dbgprintf(TEXT("CAdvancedSettings::get_AcceleratorPassthrough -> %08X, acceleratorPassthrough = %ld"), hr, *pacceleratorPassthrough); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ShadowBitmap(long pshadowBitmap) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_ShadowBitmap(%ld)"), pshadowBitmap); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_ShadowBitmap(pshadowBitmap); + dbgprintf(TEXT("CAdvancedSettings::put_ShadowBitmap -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_ShadowBitmap(long * pshadowBitmap) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_ShadowBitmap(%p)"), pshadowBitmap); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_ShadowBitmap(pshadowBitmap); + dbgprintf(TEXT("CAdvancedSettings::get_ShadowBitmap -> %08X, shadowBitmap = %ld"), hr, *pshadowBitmap); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_TransportType(long ptransportType) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_TransportType(%ld)"), ptransportType); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_TransportType(ptransportType); + dbgprintf(TEXT("CAdvancedSettings::put_TransportType -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_TransportType(long * ptransportType) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_TransportType(%p)"), ptransportType); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_TransportType(ptransportType); + dbgprintf(TEXT("CAdvancedSettings::get_TransportType -> %08X, transportType = %ld"), hr, *ptransportType); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_SasSequence(long psasSequence) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_SasSequence(%ld)"), psasSequence); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_SasSequence(psasSequence); + dbgprintf(TEXT("CAdvancedSettings::put_SasSequence -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_SasSequence(long * psasSequence) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_SasSequence(%p)"), psasSequence); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_SasSequence(psasSequence); + dbgprintf(TEXT("CAdvancedSettings::get_SasSequence -> %08X, sasSequence = %ld"), hr, *psasSequence); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_EncryptionEnabled(long pencryptionEnabled) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_EncryptionEnabled(%ld)"), pencryptionEnabled); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_EncryptionEnabled(pencryptionEnabled); + dbgprintf(TEXT("CAdvancedSettings::put_EncryptionEnabled -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_EncryptionEnabled(long * pencryptionEnabled) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_EncryptionEnabled(%p)"), pencryptionEnabled); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_EncryptionEnabled(pencryptionEnabled); + dbgprintf(TEXT("CAdvancedSettings::get_EncryptionEnabled -> %08X, encryptionEnabled = %ld"), hr, *pencryptionEnabled); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_DedicatedTerminal(long pdedicatedTerminal) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_DedicatedTerminal(%ld)"), pdedicatedTerminal); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_DedicatedTerminal(pdedicatedTerminal); + dbgprintf(TEXT("CAdvancedSettings::put_DedicatedTerminal -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_DedicatedTerminal(long * pdedicatedTerminal) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_DedicatedTerminal(%p)"), pdedicatedTerminal); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_DedicatedTerminal(pdedicatedTerminal); + dbgprintf(TEXT("CAdvancedSettings::get_DedicatedTerminal -> %08X, dedicatedTerminal = %ld"), hr, *pdedicatedTerminal); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RDPPort(long prdpPort) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_RDPPort(%ld)"), prdpPort); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_RDPPort(prdpPort); + dbgprintf(TEXT("CAdvancedSettings::put_RDPPort -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RDPPort(long * prdpPort) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_RDPPort(%p)"), prdpPort); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_RDPPort(prdpPort); + dbgprintf(TEXT("CAdvancedSettings::get_RDPPort -> %08X, rdpPort = %ld"), hr, *prdpPort); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_EnableMouse(long penableMouse) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_EnableMouse(%ld)"), penableMouse); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_EnableMouse(penableMouse); + dbgprintf(TEXT("CAdvancedSettings::put_EnableMouse -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_EnableMouse(long * penableMouse) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_EnableMouse(%p)"), penableMouse); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_EnableMouse(penableMouse); + dbgprintf(TEXT("CAdvancedSettings::get_EnableMouse -> %08X, enableMouse = %ld"), hr, *penableMouse); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_DisableCtrlAltDel(long pdisableCtrlAltDel) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_DisableCtrlAltDel(%ld)"), pdisableCtrlAltDel); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_DisableCtrlAltDel(pdisableCtrlAltDel); + dbgprintf(TEXT("CAdvancedSettings::put_DisableCtrlAltDel -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_DisableCtrlAltDel(long * pdisableCtrlAltDel) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_DisableCtrlAltDel(%p)"), pdisableCtrlAltDel); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_DisableCtrlAltDel(pdisableCtrlAltDel); + dbgprintf(TEXT("CAdvancedSettings::get_DisableCtrlAltDel -> %08X, disableCtrlAltDel = %ld"), hr, *pdisableCtrlAltDel); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_EnableWindowsKey(long penableWindowsKey) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_EnableWindowsKey(%ld)"), penableWindowsKey); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_EnableWindowsKey(penableWindowsKey); + dbgprintf(TEXT("CAdvancedSettings::put_EnableWindowsKey -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_EnableWindowsKey(long * penableWindowsKey) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_EnableWindowsKey(%p)"), penableWindowsKey); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_EnableWindowsKey(penableWindowsKey); + dbgprintf(TEXT("CAdvancedSettings::get_EnableWindowsKey -> %08X, enableWindowsKey = %ld"), hr, *penableWindowsKey); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_DoubleClickDetect(long pdoubleClickDetect) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_DoubleClickDetect(%ld)"), pdoubleClickDetect); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_DoubleClickDetect(pdoubleClickDetect); + dbgprintf(TEXT("CAdvancedSettings::put_DoubleClickDetect -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_DoubleClickDetect(long * pdoubleClickDetect) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_DoubleClickDetect(%p)"), pdoubleClickDetect); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_DoubleClickDetect(pdoubleClickDetect); + dbgprintf(TEXT("CAdvancedSettings::get_DoubleClickDetect -> %08X, doubleClickDetect = %ld"), hr, *pdoubleClickDetect); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_MaximizeShell(long pmaximizeShell) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_MaximizeShell(%ld)"), pmaximizeShell); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_MaximizeShell(pmaximizeShell); + dbgprintf(TEXT("CAdvancedSettings::put_MaximizeShell -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_MaximizeShell(long * pmaximizeShell) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_MaximizeShell(%p)"), pmaximizeShell); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_MaximizeShell(pmaximizeShell); + dbgprintf(TEXT("CAdvancedSettings::get_MaximizeShell -> %08X, maximizeShell = %ld"), hr, *pmaximizeShell); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyFullScreen(long photKeyFullScreen) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyFullScreen(%ld)"), photKeyFullScreen); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_HotKeyFullScreen(photKeyFullScreen); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyFullScreen -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyFullScreen(long * photKeyFullScreen) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyFullScreen(%p)"), photKeyFullScreen); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_HotKeyFullScreen(photKeyFullScreen); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyFullScreen -> %08X, hotKeyFullScreen = %ld"), hr, *photKeyFullScreen); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyCtrlEsc(long photKeyCtrlEsc) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyCtrlEsc(%ld)"), photKeyCtrlEsc); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_HotKeyCtrlEsc(photKeyCtrlEsc); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyCtrlEsc -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyCtrlEsc(long * photKeyCtrlEsc) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyCtrlEsc(%p)"), photKeyCtrlEsc); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_HotKeyCtrlEsc(photKeyCtrlEsc); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyCtrlEsc -> %08X, hotKeyCtrlEsc = %ld"), hr, *photKeyCtrlEsc); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyAltEsc(long photKeyAltEsc) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyAltEsc(%ld)"), photKeyAltEsc); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_HotKeyAltEsc(photKeyAltEsc); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyAltEsc -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyAltEsc(long * photKeyAltEsc) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyAltEsc(%p)"), photKeyAltEsc); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_HotKeyAltEsc(photKeyAltEsc); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyAltEsc -> %08X, hotKeyAltEsc = %ld"), hr, *photKeyAltEsc); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyAltTab(long photKeyAltTab) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyAltTab(%ld)"), photKeyAltTab); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_HotKeyAltTab(photKeyAltTab); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyAltTab -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyAltTab(long * photKeyAltTab) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyAltTab(%p)"), photKeyAltTab); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_HotKeyAltTab(photKeyAltTab); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyAltTab -> %08X, hotKeyAltTab = %ld"), hr, *photKeyAltTab); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyAltShiftTab(long photKeyAltShiftTab) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyAltShiftTab(%ld)"), photKeyAltShiftTab); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_HotKeyAltShiftTab(photKeyAltShiftTab); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyAltShiftTab -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyAltShiftTab(long * photKeyAltShiftTab) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyAltShiftTab(%p)"), photKeyAltShiftTab); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_HotKeyAltShiftTab(photKeyAltShiftTab); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyAltShiftTab -> %08X, hotKeyAltShiftTab = %ld"), hr, *photKeyAltShiftTab); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyAltSpace(long photKeyAltSpace) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyAltSpace(%ld)"), photKeyAltSpace); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_HotKeyAltSpace(photKeyAltSpace); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyAltSpace -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyAltSpace(long * photKeyAltSpace) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyAltSpace(%p)"), photKeyAltSpace); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_HotKeyAltSpace(photKeyAltSpace); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyAltSpace -> %08X, hotKeyAltSpace = %ld"), hr, *photKeyAltSpace); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyCtrlAltDel(long photKeyCtrlAltDel) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyCtrlAltDel(%ld)"), photKeyCtrlAltDel); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_HotKeyCtrlAltDel(photKeyCtrlAltDel); + dbgprintf(TEXT("CAdvancedSettings::put_HotKeyCtrlAltDel -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyCtrlAltDel(long * photKeyCtrlAltDel) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyCtrlAltDel(%p)"), photKeyCtrlAltDel); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_HotKeyCtrlAltDel(photKeyCtrlAltDel); + dbgprintf(TEXT("CAdvancedSettings::get_HotKeyCtrlAltDel -> %08X, hotKeyCtrlAltDel = %ld"), hr, *photKeyCtrlAltDel); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_orderDrawThreshold(long porderDrawThreshold) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_orderDrawThreshold(%ld)"), porderDrawThreshold); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_orderDrawThreshold(porderDrawThreshold); + dbgprintf(TEXT("CAdvancedSettings::put_orderDrawThreshold -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_orderDrawThreshold(long * porderDrawThreshold) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_orderDrawThreshold(%p)"), porderDrawThreshold); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_orderDrawThreshold(porderDrawThreshold); + dbgprintf(TEXT("CAdvancedSettings::get_orderDrawThreshold -> %08X, orderDrawThreshold = %ld"), hr, *porderDrawThreshold); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapCacheSize(long pbitmapCacheSize) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapCacheSize(%ld)"), pbitmapCacheSize); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_BitmapCacheSize(pbitmapCacheSize); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapCacheSize -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapCacheSize(long * pbitmapCacheSize) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapCacheSize(%p)"), pbitmapCacheSize); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_BitmapCacheSize(pbitmapCacheSize); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapCacheSize -> %08X, bitmapCacheSize = %ld"), hr, *pbitmapCacheSize); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapVirtualCacheSize(long pbitmapVirtualCacheSize) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapVirtualCacheSize(%ld)"), pbitmapVirtualCacheSize); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_BitmapVirtualCacheSize(pbitmapVirtualCacheSize); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapVirtualCacheSize -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapVirtualCacheSize(long * pbitmapVirtualCacheSize) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapVirtualCacheSize(%p)"), pbitmapVirtualCacheSize); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_BitmapVirtualCacheSize(pbitmapVirtualCacheSize); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapVirtualCacheSize -> %08X, bitmapVirtualCacheSize = %ld"), hr, *pbitmapVirtualCacheSize); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ScaleBitmapCachesByBPP(long pbScale) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_ScaleBitmapCachesByBPP(%ld)"), pbScale); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_ScaleBitmapCachesByBPP(pbScale); + dbgprintf(TEXT("CAdvancedSettings::put_ScaleBitmapCachesByBPP -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_ScaleBitmapCachesByBPP(long * pbScale) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_ScaleBitmapCachesByBPP(%p)"), pbScale); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_ScaleBitmapCachesByBPP(pbScale); + dbgprintf(TEXT("CAdvancedSettings::get_ScaleBitmapCachesByBPP -> %08X, bScale = %ld"), hr, *pbScale); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_NumBitmapCaches(long pnumBitmapCaches) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_NumBitmapCaches(%ld)"), pnumBitmapCaches); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_NumBitmapCaches(pnumBitmapCaches); + dbgprintf(TEXT("CAdvancedSettings::put_NumBitmapCaches -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_NumBitmapCaches(long * pnumBitmapCaches) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_NumBitmapCaches(%p)"), pnumBitmapCaches); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_NumBitmapCaches(pnumBitmapCaches); + dbgprintf(TEXT("CAdvancedSettings::get_NumBitmapCaches -> %08X, numBitmapCaches = %ld"), hr, *pnumBitmapCaches); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_CachePersistenceActive(long pcachePersistenceActive) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_CachePersistenceActive(%ld)"), pcachePersistenceActive); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_CachePersistenceActive(pcachePersistenceActive); + dbgprintf(TEXT("CAdvancedSettings::put_CachePersistenceActive -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_CachePersistenceActive(long * pcachePersistenceActive) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_CachePersistenceActive(%p)"), pcachePersistenceActive); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_CachePersistenceActive(pcachePersistenceActive); + dbgprintf(TEXT("CAdvancedSettings::get_CachePersistenceActive -> %08X, cachePersistenceActive = %ld"), hr, *pcachePersistenceActive); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_PersistCacheDirectory(BSTR rhs) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_PersistCacheDirectory(%ls)"), rhs); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_PersistCacheDirectory(rhs); + dbgprintf(TEXT("CAdvancedSettings::put_PersistCacheDirectory -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_brushSupportLevel(long pbrushSupportLevel) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_brushSupportLevel(%ld)"), pbrushSupportLevel); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_brushSupportLevel(pbrushSupportLevel); + dbgprintf(TEXT("CAdvancedSettings::put_brushSupportLevel -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_brushSupportLevel(long * pbrushSupportLevel) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_brushSupportLevel(%p)"), pbrushSupportLevel); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_brushSupportLevel(pbrushSupportLevel); + dbgprintf(TEXT("CAdvancedSettings::get_brushSupportLevel -> %08X, brushSupportLevel = %ld"), hr, *pbrushSupportLevel); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_minInputSendInterval(long pminInputSendInterval) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_minInputSendInterval(%ld)"), pminInputSendInterval); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_minInputSendInterval(pminInputSendInterval); + dbgprintf(TEXT("CAdvancedSettings::put_minInputSendInterval -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_minInputSendInterval(long * pminInputSendInterval) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_minInputSendInterval(%p)"), pminInputSendInterval); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_minInputSendInterval(pminInputSendInterval); + dbgprintf(TEXT("CAdvancedSettings::get_minInputSendInterval -> %08X, minInputSendInterval = %ld"), hr, *pminInputSendInterval); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_InputEventsAtOnce(long pinputEventsAtOnce) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_InputEventsAtOnce(%ld)"), pinputEventsAtOnce); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_InputEventsAtOnce(pinputEventsAtOnce); + dbgprintf(TEXT("CAdvancedSettings::put_InputEventsAtOnce -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_InputEventsAtOnce(long * pinputEventsAtOnce) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_InputEventsAtOnce(%p)"), pinputEventsAtOnce); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_InputEventsAtOnce(pinputEventsAtOnce); + dbgprintf(TEXT("CAdvancedSettings::get_InputEventsAtOnce -> %08X, inputEventsAtOnce = %ld"), hr, *pinputEventsAtOnce); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_maxEventCount(long pmaxEventCount) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_maxEventCount(%ld)"), pmaxEventCount); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_maxEventCount(pmaxEventCount); + dbgprintf(TEXT("CAdvancedSettings::put_maxEventCount -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_maxEventCount(long * pmaxEventCount) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_maxEventCount(%p)"), pmaxEventCount); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_maxEventCount(pmaxEventCount); + dbgprintf(TEXT("CAdvancedSettings::get_maxEventCount -> %08X, maxEventCount = %ld"), hr, *pmaxEventCount); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_keepAliveInterval(long pkeepAliveInterval) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_keepAliveInterval(%ld)"), pkeepAliveInterval); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_keepAliveInterval(pkeepAliveInterval); + dbgprintf(TEXT("CAdvancedSettings::put_keepAliveInterval -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_keepAliveInterval(long * pkeepAliveInterval) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_keepAliveInterval(%p)"), pkeepAliveInterval); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_keepAliveInterval(pkeepAliveInterval); + dbgprintf(TEXT("CAdvancedSettings::get_keepAliveInterval -> %08X, keepAliveInterval = %ld"), hr, *pkeepAliveInterval); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_shutdownTimeout(long pshutdownTimeout) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_shutdownTimeout(%ld)"), pshutdownTimeout); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_shutdownTimeout(pshutdownTimeout); + dbgprintf(TEXT("CAdvancedSettings::put_shutdownTimeout -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_shutdownTimeout(long * pshutdownTimeout) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_shutdownTimeout(%p)"), pshutdownTimeout); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_shutdownTimeout(pshutdownTimeout); + dbgprintf(TEXT("CAdvancedSettings::get_shutdownTimeout -> %08X, shutdownTimeout = %ld"), hr, *pshutdownTimeout); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_overallConnectionTimeout(long poverallConnectionTimeout) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_overallConnectionTimeout(%ld)"), poverallConnectionTimeout); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_overallConnectionTimeout(poverallConnectionTimeout); + dbgprintf(TEXT("CAdvancedSettings::put_overallConnectionTimeout -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_overallConnectionTimeout(long * poverallConnectionTimeout) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_overallConnectionTimeout(%p)"), poverallConnectionTimeout); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_overallConnectionTimeout(poverallConnectionTimeout); + dbgprintf(TEXT("CAdvancedSettings::get_overallConnectionTimeout -> %08X, overallConnectionTimeout = %ld"), hr, *poverallConnectionTimeout); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_singleConnectionTimeout(long psingleConnectionTimeout) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_singleConnectionTimeout(%ld)"), psingleConnectionTimeout); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_singleConnectionTimeout(psingleConnectionTimeout); + dbgprintf(TEXT("CAdvancedSettings::put_singleConnectionTimeout -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_singleConnectionTimeout(long * psingleConnectionTimeout) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_singleConnectionTimeout(%p)"), psingleConnectionTimeout); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_singleConnectionTimeout(psingleConnectionTimeout); + dbgprintf(TEXT("CAdvancedSettings::get_singleConnectionTimeout -> %08X, singleConnectionTimeout = %ld"), hr, *psingleConnectionTimeout); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_KeyboardType(long pkeyboardType) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_KeyboardType(%ld)"), pkeyboardType); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_KeyboardType(pkeyboardType); + dbgprintf(TEXT("CAdvancedSettings::put_KeyboardType -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_KeyboardType(long * pkeyboardType) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_KeyboardType(%p)"), pkeyboardType); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_KeyboardType(pkeyboardType); + dbgprintf(TEXT("CAdvancedSettings::get_KeyboardType -> %08X, keyboardType = %ld"), hr, *pkeyboardType); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_KeyboardSubType(long pkeyboardSubType) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_KeyboardSubType(%ld)"), pkeyboardSubType); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_KeyboardSubType(pkeyboardSubType); + dbgprintf(TEXT("CAdvancedSettings::put_KeyboardSubType -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_KeyboardSubType(long * pkeyboardSubType) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_KeyboardSubType(%p)"), pkeyboardSubType); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_KeyboardSubType(pkeyboardSubType); + dbgprintf(TEXT("CAdvancedSettings::get_KeyboardSubType -> %08X, keyboardSubType = %ld"), hr, *pkeyboardSubType); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_KeyboardFunctionKey(long pkeyboardFunctionKey) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_KeyboardFunctionKey(%ld)"), pkeyboardFunctionKey); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_KeyboardFunctionKey(pkeyboardFunctionKey); + dbgprintf(TEXT("CAdvancedSettings::put_KeyboardFunctionKey -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_KeyboardFunctionKey(long * pkeyboardFunctionKey) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_KeyboardFunctionKey(%p)"), pkeyboardFunctionKey); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_KeyboardFunctionKey(pkeyboardFunctionKey); + dbgprintf(TEXT("CAdvancedSettings::get_KeyboardFunctionKey -> %08X, keyboardFunctionKey = %ld"), hr, *pkeyboardFunctionKey); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_WinceFixedPalette(long pwinceFixedPalette) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_WinceFixedPalette(%ld)"), pwinceFixedPalette); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_WinceFixedPalette(pwinceFixedPalette); + dbgprintf(TEXT("CAdvancedSettings::put_WinceFixedPalette -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_WinceFixedPalette(long * pwinceFixedPalette) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_WinceFixedPalette(%p)"), pwinceFixedPalette); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_WinceFixedPalette(pwinceFixedPalette); + dbgprintf(TEXT("CAdvancedSettings::get_WinceFixedPalette -> %08X, winceFixedPalette = %ld"), hr, *pwinceFixedPalette); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ConnectToServerConsole(VARIANT_BOOL pConnectToConsole) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_ConnectToServerConsole(%s)"), BooleanToString(pConnectToConsole)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_ConnectToServerConsole(pConnectToConsole); + dbgprintf(TEXT("CAdvancedSettings::put_ConnectToServerConsole -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_ConnectToServerConsole(VARIANT_BOOL * pConnectToConsole) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_ConnectToServerConsole(%p)"), pConnectToConsole); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_ConnectToServerConsole(pConnectToConsole); + dbgprintf(TEXT("CAdvancedSettings::get_ConnectToServerConsole -> %08X, ConnectToConsole = %s"), hr, BooleanToString(*pConnectToConsole)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapPersistence(long pbitmapPersistence) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapPersistence(%ld)"), pbitmapPersistence); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_BitmapPersistence(pbitmapPersistence); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapPersistence -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapPersistence(long * pbitmapPersistence) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapPersistence(%p)"), pbitmapPersistence); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_BitmapPersistence(pbitmapPersistence); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapPersistence -> %08X, bitmapPersistence = %ld"), hr, *pbitmapPersistence); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_MinutesToIdleTimeout(long pminutesToIdleTimeout) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_MinutesToIdleTimeout(%ld)"), pminutesToIdleTimeout); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_MinutesToIdleTimeout(pminutesToIdleTimeout); + dbgprintf(TEXT("CAdvancedSettings::put_MinutesToIdleTimeout -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_MinutesToIdleTimeout(long * pminutesToIdleTimeout) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_MinutesToIdleTimeout(%p)"), pminutesToIdleTimeout); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_MinutesToIdleTimeout(pminutesToIdleTimeout); + dbgprintf(TEXT("CAdvancedSettings::get_MinutesToIdleTimeout -> %08X, minutesToIdleTimeout = %ld"), hr, *pminutesToIdleTimeout); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_SmartSizing(VARIANT_BOOL pfSmartSizing) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_SmartSizing(%s)"), BooleanToString(pfSmartSizing)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_SmartSizing(pfSmartSizing); + dbgprintf(TEXT("CAdvancedSettings::put_SmartSizing -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_SmartSizing(VARIANT_BOOL * pfSmartSizing) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_SmartSizing(%p)"), pfSmartSizing); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_SmartSizing(pfSmartSizing); + dbgprintf(TEXT("CAdvancedSettings::get_SmartSizing -> %08X, fSmartSizing = %s"), hr, BooleanToString(*pfSmartSizing)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RdpdrLocalPrintingDocName(BSTR pLocalPrintingDocName) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_RdpdrLocalPrintingDocName(%ls)"), pLocalPrintingDocName); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_RdpdrLocalPrintingDocName(pLocalPrintingDocName); + dbgprintf(TEXT("CAdvancedSettings::put_RdpdrLocalPrintingDocName -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RdpdrLocalPrintingDocName(BSTR * pLocalPrintingDocName) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_RdpdrLocalPrintingDocName(%p)"), pLocalPrintingDocName); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_RdpdrLocalPrintingDocName(pLocalPrintingDocName); + dbgprintf(TEXT("CAdvancedSettings::get_RdpdrLocalPrintingDocName -> %08X, LocalPrintingDocName = %ls"), hr, *pLocalPrintingDocName); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RdpdrClipCleanTempDirString(BSTR clipCleanTempDirString) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_RdpdrClipCleanTempDirString(%ls)"), clipCleanTempDirString); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_RdpdrClipCleanTempDirString(clipCleanTempDirString); + dbgprintf(TEXT("CAdvancedSettings::put_RdpdrClipCleanTempDirString -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RdpdrClipCleanTempDirString(BSTR * clipCleanTempDirString) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_RdpdrClipCleanTempDirString(%p)"), clipCleanTempDirString); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_RdpdrClipCleanTempDirString(clipCleanTempDirString); + dbgprintf(TEXT("CAdvancedSettings::get_RdpdrClipCleanTempDirString -> %08X, clipCleanTempDirString = %ls"), hr, *clipCleanTempDirString); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RdpdrClipPasteInfoString(BSTR clipPasteInfoString) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_RdpdrClipPasteInfoString(%ls)"), clipPasteInfoString); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_RdpdrClipPasteInfoString(clipPasteInfoString); + dbgprintf(TEXT("CAdvancedSettings::put_RdpdrClipPasteInfoString -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RdpdrClipPasteInfoString(BSTR * clipPasteInfoString) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_RdpdrClipPasteInfoString(%p)"), clipPasteInfoString); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_RdpdrClipPasteInfoString(clipPasteInfoString); + dbgprintf(TEXT("CAdvancedSettings::get_RdpdrClipPasteInfoString -> %08X, clipPasteInfoString = %ls"), hr, *clipPasteInfoString); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ClearTextPassword(BSTR rhs) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_ClearTextPassword(%ls)"), rhs); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_ClearTextPassword(rhs); + dbgprintf(TEXT("CAdvancedSettings::put_ClearTextPassword -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_DisplayConnectionBar(VARIANT_BOOL pDisplayConnectionBar) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_DisplayConnectionBar(%s)"), BooleanToString(pDisplayConnectionBar)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_DisplayConnectionBar(pDisplayConnectionBar); + dbgprintf(TEXT("CAdvancedSettings::put_DisplayConnectionBar -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_DisplayConnectionBar(VARIANT_BOOL * pDisplayConnectionBar) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_DisplayConnectionBar(%p)"), pDisplayConnectionBar); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_DisplayConnectionBar(pDisplayConnectionBar); + dbgprintf(TEXT("CAdvancedSettings::get_DisplayConnectionBar -> %08X, DisplayConnectionBar = %s"), hr, BooleanToString(*pDisplayConnectionBar)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_PinConnectionBar(VARIANT_BOOL pPinConnectionBar) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_PinConnectionBar(%s)"), BooleanToString(pPinConnectionBar)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_PinConnectionBar(pPinConnectionBar); + dbgprintf(TEXT("CAdvancedSettings::put_PinConnectionBar -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_PinConnectionBar(VARIANT_BOOL * pPinConnectionBar) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_PinConnectionBar(%p)"), pPinConnectionBar); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_PinConnectionBar(pPinConnectionBar); + dbgprintf(TEXT("CAdvancedSettings::get_PinConnectionBar -> %08X, PinConnectionBar = %s"), hr, BooleanToString(*pPinConnectionBar)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_GrabFocusOnConnect(VARIANT_BOOL pfGrabFocusOnConnect) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_GrabFocusOnConnect(%s)"), BooleanToString(pfGrabFocusOnConnect)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_GrabFocusOnConnect(pfGrabFocusOnConnect); + dbgprintf(TEXT("CAdvancedSettings::put_GrabFocusOnConnect -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_GrabFocusOnConnect(VARIANT_BOOL * pfGrabFocusOnConnect) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_GrabFocusOnConnect(%p)"), pfGrabFocusOnConnect); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_GrabFocusOnConnect(pfGrabFocusOnConnect); + dbgprintf(TEXT("CAdvancedSettings::get_GrabFocusOnConnect -> %08X, fGrabFocusOnConnect = %s"), hr, BooleanToString(*pfGrabFocusOnConnect)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_LoadBalanceInfo(BSTR pLBInfo) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_LoadBalanceInfo(%ls)"), pLBInfo); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_LoadBalanceInfo(pLBInfo); + dbgprintf(TEXT("CAdvancedSettings::put_LoadBalanceInfo -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_LoadBalanceInfo(BSTR * pLBInfo) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_LoadBalanceInfo(%p)"), pLBInfo); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_LoadBalanceInfo(pLBInfo); + dbgprintf(TEXT("CAdvancedSettings::get_LoadBalanceInfo -> %08X, LBInfo = %ls"), hr, *pLBInfo); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RedirectDrives(VARIANT_BOOL pRedirectDrives) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_RedirectDrives(%s)"), BooleanToString(pRedirectDrives)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_RedirectDrives(pRedirectDrives); + dbgprintf(TEXT("CAdvancedSettings::put_RedirectDrives -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RedirectDrives(VARIANT_BOOL * pRedirectDrives) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_RedirectDrives(%p)"), pRedirectDrives); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_RedirectDrives(pRedirectDrives); + dbgprintf(TEXT("CAdvancedSettings::get_RedirectDrives -> %08X, RedirectDrives = %s"), hr, BooleanToString(*pRedirectDrives)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RedirectPrinters(VARIANT_BOOL pRedirectPrinters) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_RedirectPrinters(%s)"), BooleanToString(pRedirectPrinters)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_RedirectPrinters(pRedirectPrinters); + dbgprintf(TEXT("CAdvancedSettings::put_RedirectPrinters -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RedirectPrinters(VARIANT_BOOL * pRedirectPrinters) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_RedirectPrinters(%p)"), pRedirectPrinters); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_RedirectPrinters(pRedirectPrinters); + dbgprintf(TEXT("CAdvancedSettings::get_RedirectPrinters -> %08X, RedirectPrinters = %s"), hr, BooleanToString(*pRedirectPrinters)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RedirectPorts(VARIANT_BOOL pRedirectPorts) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_RedirectPorts(%s)"), BooleanToString(pRedirectPorts)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_RedirectPorts(pRedirectPorts); + dbgprintf(TEXT("CAdvancedSettings::put_RedirectPorts -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RedirectPorts(VARIANT_BOOL * pRedirectPorts) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_RedirectPorts(%p)"), pRedirectPorts); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_RedirectPorts(pRedirectPorts); + dbgprintf(TEXT("CAdvancedSettings::get_RedirectPorts -> %08X, RedirectPorts = %s"), hr, BooleanToString(*pRedirectPorts)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RedirectSmartCards(VARIANT_BOOL pRedirectSmartCards) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_RedirectSmartCards(%s)"), BooleanToString(pRedirectSmartCards)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_RedirectSmartCards(pRedirectSmartCards); + dbgprintf(TEXT("CAdvancedSettings::put_RedirectSmartCards -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RedirectSmartCards(VARIANT_BOOL * pRedirectSmartCards) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_RedirectSmartCards(%p)"), pRedirectSmartCards); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_RedirectSmartCards(pRedirectSmartCards); + dbgprintf(TEXT("CAdvancedSettings::get_RedirectSmartCards -> %08X, RedirectSmartCards = %s"), hr, BooleanToString(*pRedirectSmartCards)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapVirtualCache16BppSize(long pBitmapVirtualCache16BppSize) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapVirtualCache16BppSize(%ld)"), pBitmapVirtualCache16BppSize); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_BitmapVirtualCache16BppSize(pBitmapVirtualCache16BppSize); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapVirtualCache16BppSize -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapVirtualCache16BppSize(long * pBitmapVirtualCache16BppSize) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapVirtualCache16BppSize(%p)"), pBitmapVirtualCache16BppSize); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_BitmapVirtualCache16BppSize(pBitmapVirtualCache16BppSize); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapVirtualCache16BppSize -> %08X, BitmapVirtualCache16BppSize = %ld"), hr, *pBitmapVirtualCache16BppSize); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapVirtualCache24BppSize(long pBitmapVirtualCache24BppSize) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapVirtualCache24BppSize(%ld)"), pBitmapVirtualCache24BppSize); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_BitmapVirtualCache24BppSize(pBitmapVirtualCache24BppSize); + dbgprintf(TEXT("CAdvancedSettings::put_BitmapVirtualCache24BppSize -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapVirtualCache24BppSize(long * pBitmapVirtualCache24BppSize) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapVirtualCache24BppSize(%p)"), pBitmapVirtualCache24BppSize); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_BitmapVirtualCache24BppSize(pBitmapVirtualCache24BppSize); + dbgprintf(TEXT("CAdvancedSettings::get_BitmapVirtualCache24BppSize -> %08X, BitmapVirtualCache24BppSize = %ld"), hr, *pBitmapVirtualCache24BppSize); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_PerformanceFlags(long pDisableList) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_PerformanceFlags(%ld)"), pDisableList); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_PerformanceFlags(pDisableList); + dbgprintf(TEXT("CAdvancedSettings::put_PerformanceFlags -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_PerformanceFlags(long * pDisableList) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_PerformanceFlags(%p)"), pDisableList); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_PerformanceFlags(pDisableList); + dbgprintf(TEXT("CAdvancedSettings::get_PerformanceFlags -> %08X, DisableList = %ld"), hr, *pDisableList); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ConnectWithEndpoint(VARIANT * rhs) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_ConnectWithEndpoint(%s)"), VariantToString(*rhs).c_str()); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_ConnectWithEndpoint(rhs); + dbgprintf(TEXT("CAdvancedSettings::put_ConnectWithEndpoint -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_NotifyTSPublicKey(VARIANT_BOOL pfNotify) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::put_NotifyTSPublicKey(%s)"), BooleanToString(pfNotify)); + HRESULT hr = pIMsRdpClientAdvancedSettings->put_NotifyTSPublicKey(pfNotify); + dbgprintf(TEXT("CAdvancedSettings::put_NotifyTSPublicKey -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_NotifyTSPublicKey(VARIANT_BOOL * pfNotify) + { + IMsRdpClientAdvancedSettings * pIMsRdpClientAdvancedSettings = getIMsRdpClientAdvancedSettings(); + dbgprintf(TEXT("CAdvancedSettings::get_NotifyTSPublicKey(%p)"), pfNotify); + HRESULT hr = pIMsRdpClientAdvancedSettings->get_NotifyTSPublicKey(pfNotify); + dbgprintf(TEXT("CAdvancedSettings::get_NotifyTSPublicKey -> %08X, fNotify = %s"), hr, BooleanToString(*pfNotify)); + return hr; + } + + /* IMsRdpClientAdvancedSettings2 */ + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::get_CanAutoReconnect(VARIANT_BOOL * pfCanAutoReconnect) + { + IMsRdpClientAdvancedSettings2 * pIMsRdpClientAdvancedSettings2 = getIMsRdpClientAdvancedSettings2(); + dbgprintf(TEXT("CAdvancedSettings::get_CanAutoReconnect(%p)"), pfCanAutoReconnect); + HRESULT hr = pIMsRdpClientAdvancedSettings2->get_CanAutoReconnect(pfCanAutoReconnect); + dbgprintf(TEXT("CAdvancedSettings::get_CanAutoReconnect -> %08X, fCanAutoReconnect = %s"), hr, BooleanToString(*pfCanAutoReconnect)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::put_EnableAutoReconnect(VARIANT_BOOL pfEnableAutoReconnect) + { + IMsRdpClientAdvancedSettings2 * pIMsRdpClientAdvancedSettings2 = getIMsRdpClientAdvancedSettings2(); + dbgprintf(TEXT("CAdvancedSettings::put_EnableAutoReconnect(%s)"), BooleanToString(pfEnableAutoReconnect)); + HRESULT hr = pIMsRdpClientAdvancedSettings2->put_EnableAutoReconnect(pfEnableAutoReconnect); + dbgprintf(TEXT("CAdvancedSettings::put_EnableAutoReconnect -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::get_EnableAutoReconnect(VARIANT_BOOL * pfEnableAutoReconnect) + { + IMsRdpClientAdvancedSettings2 * pIMsRdpClientAdvancedSettings2 = getIMsRdpClientAdvancedSettings2(); + dbgprintf(TEXT("CAdvancedSettings::get_EnableAutoReconnect(%p)"), pfEnableAutoReconnect); + HRESULT hr = pIMsRdpClientAdvancedSettings2->get_EnableAutoReconnect(pfEnableAutoReconnect); + dbgprintf(TEXT("CAdvancedSettings::get_EnableAutoReconnect -> %08X, fEnableAutoReconnect = %s"), hr, BooleanToString(*pfEnableAutoReconnect)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::put_MaxReconnectAttempts(long pMaxReconnectAttempts) + { + IMsRdpClientAdvancedSettings2 * pIMsRdpClientAdvancedSettings2 = getIMsRdpClientAdvancedSettings2(); + dbgprintf(TEXT("CAdvancedSettings::put_MaxReconnectAttempts(%ld)"), pMaxReconnectAttempts); + HRESULT hr = pIMsRdpClientAdvancedSettings2->put_MaxReconnectAttempts(pMaxReconnectAttempts); + dbgprintf(TEXT("CAdvancedSettings::put_MaxReconnectAttempts -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::get_MaxReconnectAttempts(long * pMaxReconnectAttempts) + { + IMsRdpClientAdvancedSettings2 * pIMsRdpClientAdvancedSettings2 = getIMsRdpClientAdvancedSettings2(); + dbgprintf(TEXT("CAdvancedSettings::get_MaxReconnectAttempts(%p)"), pMaxReconnectAttempts); + HRESULT hr = pIMsRdpClientAdvancedSettings2->get_MaxReconnectAttempts(pMaxReconnectAttempts); + dbgprintf(TEXT("CAdvancedSettings::get_MaxReconnectAttempts -> %08X, MaxReconnectAttempts = %ld"), hr, *pMaxReconnectAttempts); + return hr; + } + + /* IMsRdpClientAdvancedSettings3 */ + virtual STDMETHODIMP IMsRdpClientAdvancedSettings3::put_ConnectionBarShowMinimizeButton(VARIANT_BOOL pfShowMinimize) + { + IMsRdpClientAdvancedSettings3 * pIMsRdpClientAdvancedSettings3 = getIMsRdpClientAdvancedSettings3(); + dbgprintf(TEXT("CAdvancedSettings::put_ConnectionBarShowMinimizeButton(%s)"), BooleanToString(pfShowMinimize)); + HRESULT hr = pIMsRdpClientAdvancedSettings3->put_ConnectionBarShowMinimizeButton(pfShowMinimize); + dbgprintf(TEXT("CAdvancedSettings::put_ConnectionBarShowMinimizeButton -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings3::get_ConnectionBarShowMinimizeButton(VARIANT_BOOL * pfShowMinimize) + { + IMsRdpClientAdvancedSettings3 * pIMsRdpClientAdvancedSettings3 = getIMsRdpClientAdvancedSettings3(); + dbgprintf(TEXT("CAdvancedSettings::get_ConnectionBarShowMinimizeButton(%p)"), pfShowMinimize); + HRESULT hr = pIMsRdpClientAdvancedSettings3->get_ConnectionBarShowMinimizeButton(pfShowMinimize); + dbgprintf(TEXT("CAdvancedSettings::get_ConnectionBarShowMinimizeButton -> %08X, fShowMinimize = %s"), hr, BooleanToString(*pfShowMinimize)); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings3::put_ConnectionBarShowRestoreButton(VARIANT_BOOL pfShowRestore) + { + IMsRdpClientAdvancedSettings3 * pIMsRdpClientAdvancedSettings3 = getIMsRdpClientAdvancedSettings3(); + dbgprintf(TEXT("CAdvancedSettings::put_ConnectionBarShowRestoreButton(%s)"), BooleanToString(pfShowRestore)); + HRESULT hr = pIMsRdpClientAdvancedSettings3->put_ConnectionBarShowRestoreButton(pfShowRestore); + dbgprintf(TEXT("CAdvancedSettings::put_ConnectionBarShowRestoreButton -> %08X"), hr); + return hr; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings3::get_ConnectionBarShowRestoreButton(VARIANT_BOOL * pfShowRestore) + { + IMsRdpClientAdvancedSettings3 * pIMsRdpClientAdvancedSettings3 = getIMsRdpClientAdvancedSettings3(); + dbgprintf(TEXT("CAdvancedSettings::get_ConnectionBarShowRestoreButton(%p)"), pfShowRestore); + HRESULT hr = pIMsRdpClientAdvancedSettings3->get_ConnectionBarShowRestoreButton(pfShowRestore); + dbgprintf(TEXT("CAdvancedSettings::get_ConnectionBarShowRestoreButton -> %08X, fShowRestore = %s"), hr, BooleanToString(*pfShowRestore)); + return hr; + } + + /* IMsRdpClientAdvancedSettings4 */ + virtual STDMETHODIMP IMsRdpClientAdvancedSettings4::put_AuthenticationLevel(unsigned int puiAuthLevel) + { + IMsRdpClientAdvancedSettings4 * pIMsRdpClientAdvancedSettings4 = getIMsRdpClientAdvancedSettings4(); + dbgprintf(TEXT("CAdvancedSettings::put_AuthenticationLevel(%u)"), puiAuthLevel); + HRESULT hr = pIMsRdpClientAdvancedSettings4->put_AuthenticationLevel(puiAuthLevel); + dbgprintf(TEXT("CAdvancedSettings::put_AuthenticationLevel -> %08X"), hr); + return hr; + } + virtual STDMETHODIMP IMsRdpClientAdvancedSettings4::get_AuthenticationLevel(unsigned int * puiAuthLevel) + { + IMsRdpClientAdvancedSettings4 * pIMsRdpClientAdvancedSettings4 = getIMsRdpClientAdvancedSettings4(); + dbgprintf(TEXT("CAdvancedSettings::get_AuthenticationLevel(%p)"), puiAuthLevel); + HRESULT hr = pIMsRdpClientAdvancedSettings4->get_AuthenticationLevel(puiAuthLevel); + dbgprintf(TEXT("CAdvancedSettings::get_AuthenticationLevel -> %08X, uiAuthLevel = %ld"), hr, *puiAuthLevel); + return hr; + } + }; + + class CoClass: + /* Standard interfaces */ + public IUnknown, + public IDispatch, + public IConnectionPointContainer, + public IDataObject, + public IObjectSafety, + public IOleControl, + public IOleInPlaceActiveObject, + public IOleInPlaceObject, + public IOleObject, + public IOleWindow, + public IPersist, + public IPersistPropertyBag, + public IPersistStorage, + public IPersistStreamInit, + public IProvideClassInfo, + public IProvideClassInfo2, + public IQuickActivate, + public ISpecifyPropertyPages, + public IViewObject, + public IViewObject2, + + /* RDP client interfaces */ + public IMsRdpClient4, + public IMsRdpClientNonScriptable2 + { + private: + LONG m_refCount; + + IUnknown * m_IUnknown; + + IDispatch * m_IDispatch; + IConnectionPointContainer * m_IConnectionPointContainer; + IDataObject * m_IDataObject; + IObjectSafety * m_IObjectSafety; + IOleControl * m_IOleControl; + IOleInPlaceActiveObject * m_IOleInPlaceActiveObject; + IOleInPlaceObject * m_IOleInPlaceObject; + IOleObject * m_IOleObject; + IOleWindow * m_IOleWindow; + IPersist * m_IPersist; + IPersistPropertyBag * m_IPersistPropertyBag; + IPersistStorage * m_IPersistStorage; + IPersistStreamInit * m_IPersistStreamInit; + IProvideClassInfo * m_IProvideClassInfo; + IProvideClassInfo2 * m_IProvideClassInfo2; + IQuickActivate * m_IQuickActivate; + ISpecifyPropertyPages * m_ISpecifyPropertyPages; + IViewObject * m_IViewObject; + IViewObject2 * m_IViewObject2; + + IMsRdpClient * m_IMsRdpClient; + IMsRdpClient2 * m_IMsRdpClient2; + IMsRdpClient3 * m_IMsRdpClient3; + IMsRdpClient4 * m_IMsRdpClient4; + IMsTscAx * m_IMsTscAx; + IMsTscNonScriptable * m_IMsTscNonScriptable; + IMsRdpClientNonScriptable * m_IMsRdpClientNonScriptable; + IMsRdpClientNonScriptable2 * m_IMsRdpClientNonScriptable2; + + IDispatch * getIDispatch() + { + if(m_IDispatch) + return m_IDispatch; + + if(m_IMsRdpClient) + m_IDispatch = m_IMsRdpClient; + else if(m_IMsRdpClient2) + m_IDispatch = m_IMsRdpClient2; + else if(m_IMsRdpClient3) + m_IDispatch = m_IMsRdpClient3; + else if(m_IMsRdpClient4) + m_IDispatch = m_IMsRdpClient4; + else if(m_IMsTscAx) + m_IDispatch = m_IMsTscAx; + + if(m_IDispatch) + { + m_IDispatch->AddRef(); + return m_IDispatch; + } + + if(SUCCEEDED(m_IUnknown->QueryInterface(&m_IDispatch))) + return m_IDispatch; + + return NULL; + } + + IConnectionPointContainer * getIConnectionPointContainer() + { + if(m_IConnectionPointContainer) + return m_IConnectionPointContainer; + + m_IUnknown->QueryInterface(&m_IConnectionPointContainer); + return m_IConnectionPointContainer; + + } + + IDataObject * getIDataObject() + { + if(m_IDataObject) + return m_IDataObject; + + m_IUnknown->QueryInterface(&m_IDataObject); + return m_IDataObject; + } + + IObjectSafety * getIObjectSafety() + { + if(m_IObjectSafety) + return m_IObjectSafety; + + m_IUnknown->QueryInterface(&m_IObjectSafety); + return m_IObjectSafety; + } + + IOleControl * getIOleControl() + { + if(m_IOleControl) + return m_IOleControl; + + m_IUnknown->QueryInterface(&m_IOleControl); + return m_IOleControl; + } + + IOleInPlaceActiveObject * getIOleInPlaceActiveObject() + { + if(m_IOleInPlaceActiveObject) + return m_IOleInPlaceActiveObject; + + m_IUnknown->QueryInterface(&m_IOleInPlaceActiveObject); + return m_IOleInPlaceActiveObject; + } + + IOleInPlaceObject * getIOleInPlaceObject() + { + if(m_IOleInPlaceObject) + return m_IOleInPlaceObject; + + m_IUnknown->QueryInterface(&m_IOleInPlaceObject); + return m_IOleInPlaceObject; + } + + IOleObject * getIOleObject() + { + if(m_IOleObject) + return m_IOleObject; + + m_IUnknown->QueryInterface(&m_IOleObject); + return m_IOleObject; + } + + IOleWindow * getIOleWindow() + { + if(m_IOleWindow) + return m_IOleWindow; + + if(m_IOleInPlaceActiveObject) + m_IOleWindow = m_IOleInPlaceActiveObject; + + if(m_IOleWindow) + { + m_IOleWindow->AddRef(); + return m_IOleWindow; + } + + m_IUnknown->QueryInterface(&m_IOleWindow); + return m_IOleWindow; + } + + IPersist * getIPersist() + { + if(m_IPersist) + return m_IPersist; + + if(m_IPersistPropertyBag) + m_IPersist = m_IPersistPropertyBag; + else if(m_IPersistStorage) + m_IPersist = m_IPersistStorage; + else if(m_IPersistStreamInit) + m_IPersist = m_IPersistStreamInit; + + if(m_IPersist) + { + m_IPersist->AddRef(); + return m_IPersist; + } + + m_IUnknown->QueryInterface(&m_IPersist); + return m_IPersist; + } + + IPersistPropertyBag * getIPersistPropertyBag() + { + if(m_IPersistPropertyBag) + return m_IPersistPropertyBag; + + m_IUnknown->QueryInterface(&m_IPersistPropertyBag); + return m_IPersistPropertyBag; + } + + IPersistStorage * getIPersistStorage() + { + if(m_IPersistStorage) + return m_IPersistStorage; + + m_IUnknown->QueryInterface(&m_IPersistStorage); + return m_IPersistStorage; + } + + IPersistStreamInit * getIPersistStreamInit() + { + if(m_IPersistStreamInit) + return m_IPersistStreamInit; + + m_IUnknown->QueryInterface(&m_IPersistStreamInit); + return m_IPersistStreamInit; + } + + IProvideClassInfo * getIProvideClassInfo() + { + if(m_IProvideClassInfo) + return m_IProvideClassInfo; + + if(m_IProvideClassInfo2) + m_IProvideClassInfo = m_IProvideClassInfo2; + + if(m_IProvideClassInfo) + { + m_IProvideClassInfo->AddRef(); + return m_IProvideClassInfo; + } + + m_IUnknown->QueryInterface(&m_IProvideClassInfo); + return m_IProvideClassInfo; + } + + IProvideClassInfo2 * getIProvideClassInfo2() + { + if(m_IProvideClassInfo2) + return m_IProvideClassInfo2; + + m_IUnknown->QueryInterface(&m_IProvideClassInfo2); + return m_IProvideClassInfo2; + } + + IQuickActivate * getIQuickActivate() + { + if(m_IQuickActivate) + return m_IQuickActivate; + + m_IUnknown->QueryInterface(&m_IQuickActivate); + return m_IQuickActivate; + } + + ISpecifyPropertyPages * getISpecifyPropertyPages() + { + if(m_ISpecifyPropertyPages) + return m_ISpecifyPropertyPages; + + m_IUnknown->QueryInterface(&m_ISpecifyPropertyPages); + return m_ISpecifyPropertyPages; + } + + IViewObject * getIViewObject() + { + if(m_IViewObject) + return m_IViewObject; + + if(m_IViewObject2) + m_IViewObject = m_IViewObject2; + + if(m_IViewObject) + { + m_IViewObject->AddRef(); + return m_IViewObject; + } + + m_IUnknown->QueryInterface(&m_IViewObject); + return m_IViewObject; + } + + IViewObject2 * getIViewObject2() + { + if(m_IViewObject2) + return m_IViewObject2; + + m_IUnknown->QueryInterface(&m_IViewObject2); + return m_IViewObject2; + } + + IMsRdpClient * getIMsRdpClient() + { + if(m_IMsRdpClient) + return m_IMsRdpClient; + + if(m_IMsRdpClient2) + m_IMsRdpClient = m_IMsRdpClient2; + else if(m_IMsRdpClient3) + m_IMsRdpClient = m_IMsRdpClient3; + else if(m_IMsRdpClient4) + m_IMsRdpClient = m_IMsRdpClient4; + + if(m_IMsRdpClient) + { + m_IMsRdpClient->AddRef(); + return m_IMsRdpClient; + } + + m_IUnknown->QueryInterface(&m_IMsRdpClient); + return m_IMsRdpClient; + } + + IMsRdpClient2 * getIMsRdpClient2() + { + if(m_IMsRdpClient2) + return m_IMsRdpClient2; + + if(m_IMsRdpClient3) + m_IMsRdpClient2 = m_IMsRdpClient3; + else if(m_IMsRdpClient4) + m_IMsRdpClient2 = m_IMsRdpClient4; + + if(m_IMsRdpClient2) + { + m_IMsRdpClient2->AddRef(); + return m_IMsRdpClient2; + } + + m_IUnknown->QueryInterface(&m_IMsRdpClient2); + return m_IMsRdpClient2; + } + + IMsRdpClient3 * getIMsRdpClient3() + { + if(m_IMsRdpClient3) + return m_IMsRdpClient3; + + if(m_IMsRdpClient4) + m_IMsRdpClient3 = m_IMsRdpClient4; + + if(m_IMsRdpClient3) + { + m_IMsRdpClient3->AddRef(); + return m_IMsRdpClient3; + } + + m_IUnknown->QueryInterface(&m_IMsRdpClient3); + return m_IMsRdpClient3; + } + + IMsRdpClient4 * getIMsRdpClient4() + { + if(m_IMsRdpClient4) + return m_IMsRdpClient4; + + m_IUnknown->QueryInterface(&m_IMsRdpClient4); + return m_IMsRdpClient4; + } + + IMsTscAx * getIMsTscAx() + { + if(m_IMsTscAx) + return m_IMsTscAx; + + if(m_IMsRdpClient) + m_IMsTscAx = m_IMsRdpClient; + else if(m_IMsRdpClient2) + m_IMsTscAx = m_IMsRdpClient2; + else if(m_IMsRdpClient3) + m_IMsTscAx = m_IMsRdpClient3; + else if(m_IMsRdpClient4) + m_IMsTscAx = m_IMsRdpClient4; + + if(m_IMsTscAx) + { + m_IMsTscAx->AddRef(); + return m_IMsTscAx; + } + + m_IUnknown->QueryInterface(&m_IMsTscAx); + return m_IMsTscAx; + } + + IMsTscNonScriptable * getIMsTscNonScriptable() + { + if(m_IMsTscNonScriptable) + return m_IMsTscNonScriptable; + + if(m_IMsRdpClientNonScriptable) + m_IMsTscNonScriptable = m_IMsRdpClientNonScriptable; + else if(m_IMsRdpClientNonScriptable2) + m_IMsTscNonScriptable = m_IMsRdpClientNonScriptable2; + + if(m_IMsTscNonScriptable) + { + m_IMsTscNonScriptable->AddRef(); + return m_IMsTscNonScriptable; + } + + m_IUnknown->QueryInterface(&m_IMsTscNonScriptable); + return m_IMsTscNonScriptable; + } + + IMsRdpClientNonScriptable * getIMsRdpClientNonScriptable() + { + if(m_IMsRdpClientNonScriptable) + return m_IMsRdpClientNonScriptable; + + if(m_IMsRdpClientNonScriptable2) + m_IMsRdpClientNonScriptable = m_IMsRdpClientNonScriptable2; + + if(m_IMsRdpClientNonScriptable) + { + m_IMsRdpClientNonScriptable->AddRef(); + return m_IMsRdpClientNonScriptable; + } + + m_IUnknown->QueryInterface(&m_IMsRdpClientNonScriptable); + return m_IMsRdpClientNonScriptable; + } + + IMsRdpClientNonScriptable2 * getIMsRdpClientNonScriptable2() + { + if(m_IMsRdpClientNonScriptable2) + return m_IMsRdpClientNonScriptable2; + + m_IUnknown->QueryInterface(&m_IMsRdpClientNonScriptable2); + return m_IMsRdpClientNonScriptable2; + } + + private: + IUnknown * m_outer; + + HRESULT queryInterface(REFIID riid, void ** ppvObject) + { + HRESULT hr; + IUnknown * pvObject = NULL; + + dbgprintf(TEXT("IUnknown::QueryInterface(%ls, %p)"), UUIDToString(riid).c_str(), ppvObject); + +#define QIBEGIN() \ + if(riid == IID_IUnknown) \ + { \ + assert(0); \ + } + +#define QI(I) \ + else if(riid == IID_ ## I) \ + { \ + if(m_ ## I) \ + { \ + m_ ## I->AddRef(); \ + hr = S_OK; \ + } \ + else \ + { \ + hr = m_IUnknown->QueryInterface(&m_ ## I); \ + } \ + \ + if(SUCCEEDED(hr)) \ + pvObject = static_cast(this); \ + } + +#define QIEND() \ + else \ + { \ + hr = E_NOINTERFACE; \ + pvObject = NULL; \ + } + + QIBEGIN() + + /* Standard interfaces */ + QI(IDispatch) + QI(IConnectionPointContainer) + QI(IDataObject) + QI(IObjectSafety) + QI(IOleControl) + QI(IOleInPlaceActiveObject) + QI(IOleInPlaceObject) + QI(IOleObject) + QI(IOleWindow) + QI(IPersist) + QI(IPersistPropertyBag) + QI(IPersistStorage) + QI(IPersistStreamInit) + QI(IProvideClassInfo) + QI(IProvideClassInfo2) + QI(IQuickActivate) + QI(ISpecifyPropertyPages) + QI(IViewObject) + QI(IViewObject2) + + /* Terminal services client */ + QI(IMsRdpClient) + QI(IMsRdpClient2) + QI(IMsRdpClient3) + QI(IMsRdpClient4) + QI(IMsTscAx) + QI(IMsTscNonScriptable) + QI(IMsRdpClientNonScriptable) + QI(IMsRdpClientNonScriptable2) + QIEND() + +#undef QIBEGIN +#undef QIEND +#undef QI + + if(SUCCEEDED(hr)) + { + assert(pvObject); + pvObject->AddRef(); + } + else + { + assert(pvObject == NULL); + } + + *ppvObject = pvObject; + + dbgprintf(TEXT("IUnknown::QueryInterface -> %08X, ppvObject = %p"), hr, *ppvObject); + return hr; + } + + ULONG addRef() + { + return InterlockedIncrement(&m_refCount); + } + + ULONG release() + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + friend class CoClassInner; + + class CoClassInner: public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) + { + if(riid == IID_IUnknown) + { + AddRef(); + *ppvObject = this; + return S_OK; + } + + return InnerToOuter(this)->queryInterface(riid, ppvObject); + } + + virtual ULONG STDMETHODCALLTYPE AddRef() + { + return InnerToOuter(this)->addRef(); + } + + virtual ULONG STDMETHODCALLTYPE Release() + { + return InnerToOuter(this)->release(); + } + } + m_inner; + + static CoClass * InnerToOuter(CoClassInner * inner) + { + return CONTAINING_RECORD(inner, CoClass, m_inner); + } + + private: + CoClass(IUnknown * pUnknw, IUnknown * pUnkOuter): + m_refCount(1), + m_outer(pUnkOuter), + m_IUnknown(pUnknw), + m_IDispatch(NULL), + m_IConnectionPointContainer(NULL), + m_IDataObject(NULL), + m_IObjectSafety(NULL), + m_IOleControl(NULL), + m_IOleInPlaceActiveObject(NULL), + m_IOleInPlaceObject(NULL), + m_IOleObject(NULL), + m_IOleWindow(NULL), + m_IPersist(NULL), + m_IPersistPropertyBag(NULL), + m_IPersistStorage(NULL), + m_IPersistStreamInit(NULL), + m_IProvideClassInfo(NULL), + m_IProvideClassInfo2(NULL), + m_IQuickActivate(NULL), + m_ISpecifyPropertyPages(NULL), + m_IViewObject(NULL), + m_IViewObject2(NULL), + m_IMsRdpClient(NULL), + m_IMsRdpClient2(NULL), + m_IMsRdpClient3(NULL), + m_IMsRdpClient4(NULL), + m_IMsTscAx(NULL), + m_IMsTscNonScriptable(NULL), + m_IMsRdpClientNonScriptable(NULL), + m_IMsRdpClientNonScriptable2(NULL) + { + if(m_outer == NULL) + m_outer = &m_inner; + } + + public: + static HRESULT CreateInstance(IUnknown * pUnknw, IUnknown * pUnkOuter, REFIID riid, void ** ppvObject) + { + HRESULT hr = S_OK; + + if(pUnkOuter && riid != IID_IUnknown) + hr = CLASS_E_NOAGGREGATION; + else + { + CoClass * p = new CoClass(pUnknw, pUnkOuter); + + if(p == NULL) + hr = E_OUTOFMEMORY; + else + { + hr = p->m_inner.QueryInterface(riid, ppvObject); + + if(FAILED(hr)) + delete p; + else + p->m_inner.Release(); + } + } + + if(FAILED(hr)) + pUnknw->Release(); + + return hr; + } + + private: + ~CoClass() + { + if(m_IUnknown) + m_IUnknown->Release(); + + if(m_IDispatch) + m_IDispatch->Release(); + + if(m_IConnectionPointContainer) + m_IConnectionPointContainer->Release(); + + if(m_IDataObject) + m_IDataObject->Release(); + + if(m_IObjectSafety) + m_IObjectSafety->Release(); + + if(m_IOleControl) + m_IOleControl->Release(); + + if(m_IOleInPlaceActiveObject) + m_IOleInPlaceActiveObject->Release(); + + if(m_IOleInPlaceObject) + m_IOleInPlaceObject->Release(); + + if(m_IOleObject) + m_IOleObject->Release(); + + if(m_IOleWindow) + m_IOleWindow->Release(); + + if(m_IPersist) + m_IPersist->Release(); + + if(m_IPersistPropertyBag) + m_IPersistPropertyBag->Release(); + + if(m_IPersistStorage) + m_IPersistStorage->Release(); + + if(m_IPersistStreamInit) + m_IPersistStreamInit->Release(); + + if(m_IProvideClassInfo) + m_IProvideClassInfo->Release(); + + if(m_IProvideClassInfo2) + m_IProvideClassInfo2->Release(); + + if(m_IQuickActivate) + m_IQuickActivate->Release(); + + if(m_ISpecifyPropertyPages) + m_ISpecifyPropertyPages->Release(); + + if(m_IViewObject) + m_IViewObject->Release(); + + if(m_IViewObject2) + m_IViewObject2->Release(); + + if(m_IMsRdpClient) + m_IMsRdpClient->Release(); + + if(m_IMsRdpClient2) + m_IMsRdpClient2->Release(); + + if(m_IMsRdpClient3) + m_IMsRdpClient3->Release(); + + if(m_IMsRdpClient4) + m_IMsRdpClient4->Release(); + + if(m_IMsTscAx) + m_IMsTscAx->Release(); + + if(m_IMsTscNonScriptable) + m_IMsTscNonScriptable->Release(); + + if(m_IMsRdpClientNonScriptable) + m_IMsRdpClientNonScriptable->Release(); + + if(m_IMsRdpClientNonScriptable2) + m_IMsRdpClientNonScriptable2->Release(); + } + + /* IUnknown */ + public: + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) + { + return m_outer->QueryInterface(riid, ppvObject); + } + + virtual ULONG STDMETHODCALLTYPE AddRef(void) + { + return m_outer->AddRef(); + } + + virtual ULONG STDMETHODCALLTYPE Release(void) + { + return m_outer->Release(); + } + + /* IDispatch */ + private: + static void FreeExcepInfo(const EXCEPINFO& excepInfo) + { + if(excepInfo.bstrSource) + SysFreeString(excepInfo.bstrSource); + + if(excepInfo.bstrDescription) + SysFreeString(excepInfo.bstrDescription); + + if(excepInfo.bstrHelpFile) + SysFreeString(excepInfo.bstrHelpFile); + } + + static std::basic_string ExcepInfoToString(const EXCEPINFO& excepInfo) + { + std::basic_ostringstream o; + + o << "{"; + o << " code: " << excepInfo.wCode << " from: " << std::basic_string(excepInfo.bstrSource, excepInfo.bstrSource + SysStringLen(excepInfo.bstrSource)); + + BSTR bstrDescription = NULL; + + if(excepInfo.bstrDescription) + bstrDescription = excepInfo.bstrDescription; + else if(excepInfo.pfnDeferredFillIn) + { + EXCEPINFO excepInfoCopy = excepInfo; + + if(SUCCEEDED(excepInfoCopy.pfnDeferredFillIn(&excepInfoCopy)) && excepInfoCopy.bstrDescription) + { + bstrDescription = excepInfoCopy.bstrDescription; + excepInfoCopy.bstrDescription = NULL; + } + + if(excepInfoCopy.bstrSource == excepInfo.bstrSource) + excepInfoCopy.bstrSource = NULL; + + if(excepInfoCopy.bstrHelpFile == excepInfo.bstrDescription) + excepInfoCopy.bstrDescription = NULL; + + FreeExcepInfo(excepInfoCopy); + } + + if(bstrDescription) + { + o << " msg: " << std::basic_string(bstrDescription, bstrDescription + SysStringLen(bstrDescription)); + + if(excepInfo.bstrDescription == NULL) + SysFreeString(bstrDescription); + } + + o << " }"; + + return o.str().c_str(); + } + + public: + virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT * pctinfo) + { + IDispatch * pIDispatch = getIDispatch(); + dbgprintf(TEXT("IDispatch::GetTypeInfoCount(%p)"), pctinfo); + HRESULT hr = pIDispatch->GetTypeInfoCount(pctinfo); + dbgprintf(TEXT("IDispatch::GetTypeInfoCount -> %08X, ctinfo = %lu"), hr, *pctinfo); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) + { + IDispatch * pIDispatch = getIDispatch(); + dbgprintf(TEXT("IDispatch::GetTypeInfo(%lu, %08X, %p)"), iTInfo, lcid, ppTInfo); + HRESULT hr = pIDispatch->GetTypeInfo(iTInfo, lcid, ppTInfo); + dbgprintf(TEXT("IDispatch::GetTypeInfo -> %08X, pTInfo = %p"), hr, *ppTInfo); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) + { + IDispatch * pIDispatch = getIDispatch(); + std::wstring strtemp; + + std::wostringstream strtempo; + + strtemp.resize(0); + strtemp += L"[ "; + + for(UINT i = 0; i < cNames; ++ i) + { + if(i) + strtemp += L", "; + + strtemp += rgszNames[i]; + } + + strtemp += L" ]"; + + dbgprintf(TEXT("IDispatch::GetIDsOfNames(%ls, %ls, %lu, %08X, %p)"), UUIDToString(riid).c_str(), strtemp.c_str(), cNames, lcid, rgDispId); + HRESULT hr = pIDispatch->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId); + + strtemp.resize(0); + strtempo.str(strtemp); + + strtempo << L"[ "; + + for(UINT i = 0; i < cNames; ++ i) + { + if(i) + strtempo << L", "; + + strtempo << rgDispId[i]; + } + + strtempo << L" ]"; + + dbgprintf(TEXT("IDispatch::GetIDsOfNames -> %08X, rgDispId = %ls"), hr, strtempo.str().c_str()); + + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) + { + IDispatch * pIDispatch = getIDispatch(); + + std::basic_ostringstream strtempo; + + strtempo << L"{"; + + for(unsigned int i = pDispParams->cArgs, j = pDispParams->cNamedArgs; j < pDispParams->cArgs; -- i, ++ j) + { + strtempo << L" "; + strtempo << VariantToString(pDispParams->rgvarg[i - 1]); + strtempo << L","; + } + + for(unsigned int i = pDispParams->cArgs - pDispParams->cNamedArgs; i > 0; -- i) + { + strtempo << L" "; + strtempo << L"["; strtempo << pDispParams->rgdispidNamedArgs[i - 1]; strtempo << L"] => "; + strtempo << VariantToString(pDispParams->rgvarg[i - 1]); + strtempo << L","; + } + + strtempo << L" }"; + + dbgprintf(TEXT("IDispatch::Invoke(%ld, %ls, %08X, %04X, %s, %p, %p, %p)"), dispIdMember, UUIDToString(riid).c_str(), lcid, wFlags, strtempo.str().c_str(), pVarResult, pExcepInfo, puArgErr); + + VARIANT VarResult = { }; + EXCEPINFO ExcepInfo = { }; + + if(pVarResult == NULL) + pVarResult = &VarResult; + + if(pExcepInfo == NULL) + pExcepInfo = &ExcepInfo; + + HRESULT hr = pIDispatch->Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + dbgprintf(TEXT("IDispatch::Invoke -> %08X, returns %s, throws %s"), hr, VariantToString(*pVarResult).c_str(), ExcepInfoToString(*pExcepInfo).c_str()); + + FreeExcepInfo(ExcepInfo); + + return hr; + } + + /* IConnectionPointContainer */ + public: + virtual HRESULT STDMETHODCALLTYPE EnumConnectionPoints(IEnumConnectionPoints ** ppEnum) + { + IConnectionPointContainer * pIConnectionPointContainer = getIConnectionPointContainer(); + dbgprintf(TEXT("IConnectionPointContainer::EnumConnectionPoints(%p)"), ppEnum); + HRESULT hr = pIConnectionPointContainer->EnumConnectionPoints(ppEnum); + dbgprintf(TEXT("IConnectionPointContainer::EnumConnectionPoints -> %08X, pEnum = %p"), hr, *ppEnum); + + if(SUCCEEDED(hr)) + *ppEnum = HookIEnumConnectionPoints(*ppEnum); + + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE FindConnectionPoint(REFIID riid, IConnectionPoint ** ppCP) + { + IConnectionPointContainer * pIConnectionPointContainer = getIConnectionPointContainer(); + dbgprintf(TEXT("IConnectionPointContainer::FindConnectionPoint(%ls, %p)"), UUIDToString(riid).c_str(), ppCP); + HRESULT hr = pIConnectionPointContainer->FindConnectionPoint(riid, ppCP); + dbgprintf(TEXT("IConnectionPointContainer::FindConnectionPoint -> %08X, pCP = %p"), hr, *ppCP); + + if(SUCCEEDED(hr)) + *ppCP = HookIConnectionPoint(*ppCP); + + return hr; + } + + /* IDataObject */ + private: + static std::basic_string TargetDeviceToString(const DVTARGETDEVICE& targetdev) + { + if(&targetdev == NULL) + return TEXT(""); + + std::basic_ostringstream o; + + o << "{"; + o << LPCWSTR(targetdev.tdData[targetdev.tdDriverNameOffset]); + + if(targetdev.tdDeviceNameOffset) + { + o << ","; + o << LPCWSTR(targetdev.tdData[targetdev.tdDeviceNameOffset]); + } + + if(targetdev.tdPortNameOffset) + { + o << ","; + o << LPCWSTR(targetdev.tdData[targetdev.tdPortNameOffset]); + } + + o << " }"; + + return o.str(); + } + + static LPCTSTR AspectToString(DWORD aspect) + { + switch(aspect) + { + case DVASPECT_CONTENT: return TEXT("content"); + case DVASPECT_THUMBNAIL: return TEXT("thumbnail"); + case DVASPECT_ICON: return TEXT("icon"); + case DVASPECT_DOCPRINT: return TEXT("printable"); + default: return TEXT(""); + } + } + + static LPCTSTR TymedToString(DWORD tymed) + { + switch(tymed) + { + case TYMED_HGLOBAL: return TEXT("memory"); + case TYMED_FILE: return TEXT("file"); + case TYMED_ISTREAM: return TEXT("IStream"); + case TYMED_ISTORAGE: return TEXT("IStorage"); + case TYMED_GDI: return TEXT("bitmap"); + case TYMED_MFPICT: return TEXT("metafile"); + case TYMED_ENHMF: return TEXT("enhanced metafile"); + case TYMED_NULL: return TEXT(""); + default: return TEXT(""); + } + } + + static std::basic_string FormatEtcToString(const FORMATETC& formatetc) + { + std::basic_ostringstream o; + + o << "{"; + + // cfFormat + o << " format: "; + + switch(formatetc.cfFormat) + { + case CF_TEXT: o << "ANSI text"; break; + case CF_BITMAP: o << "bitmap"; break; + case CF_METAFILEPICT: o << "metafile"; break; + case CF_SYLK: o << "symlink"; break; + case CF_DIF: o << "DIF"; break; + case CF_TIFF: o << "TIFF"; break; + case CF_OEMTEXT: o << "OEM text"; break; + case CF_DIB: o << "DIBv4"; break; + case CF_PALETTE: o << "palette"; break; + case CF_PENDATA: o << "pen data"; break; + case CF_RIFF: o << "RIFF"; break; + case CF_WAVE: o << "WAV"; break; + case CF_UNICODETEXT: o << "Unicode text"; break; + case CF_ENHMETAFILE: o << "enhanced metafile"; break; + case CF_HDROP: o << "list of files"; break; + case CF_LOCALE: o << "LCID"; break; + case CF_DIBV5: o << "DIBv5"; break; + case CF_OWNERDISPLAY: o << ""; break; + case CF_DSPTEXT: o << ""; break; + case CF_DSPBITMAP: o << ""; break; + case CF_DSPMETAFILEPICT: o << ""; break; + case CF_DSPENHMETAFILE: o << ""; break; + + default: + o << "<"; + + if(formatetc.cfFormat >= CF_PRIVATEFIRST && formatetc.cfFormat <= CF_PRIVATELAST) + o << "private"; + else if(formatetc.cfFormat >= CF_GDIOBJFIRST && formatetc.cfFormat <= CF_GDIOBJLAST) + o << "GDI object"; + else + o << "unknown"; + + o << " " << std::hex << formatetc.cfFormat << std::dec << ">"; + } + + // ptd + if(formatetc.ptd) + o << " device: " << TargetDeviceToString(*formatetc.ptd); + + // dwAspect + o << " aspect: " << AspectToString(formatetc.dwAspect); + + // lindex + if(formatetc.dwAspect == DVASPECT_CONTENT || formatetc.dwAspect == DVASPECT_DOCPRINT) + o << " page split: " << formatetc.lindex; + + // tymed + o << " medium: " << TymedToString(formatetc.tymed); + + return o.str(); + } + + static std::basic_string MediumToString(const STGMEDIUM& medium) + { + std::basic_ostringstream o; + + o << "{ "; + o << TymedToString(medium.tymed); + o << " }"; + + return o.str(); + } + + public: + virtual HRESULT STDMETHODCALLTYPE GetData(FORMATETC * pformatetcIn, STGMEDIUM * pmedium) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::GetData(%s, %p)"), FormatEtcToString(*pformatetcIn).c_str(), pmedium); + HRESULT hr = pIDataObject->GetData(pformatetcIn, pmedium); + dbgprintf(TEXT("IDataObject::GetData -> %08X, %s"), hr, MediumToString(*pmedium).c_str()); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetDataHere(FORMATETC * pformatetc, STGMEDIUM * pmedium) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::GetDataHere(%s, %p)"), FormatEtcToString(*pformatetc).c_str(), pmedium); + HRESULT hr = pIDataObject->GetDataHere(pformatetc, pmedium); + dbgprintf(TEXT("IDataObject::GetDataHere -> %08X, medium = %s"), hr, MediumToString(*pmedium).c_str()); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE QueryGetData(FORMATETC * pformatetc) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::QueryGetData(%s)"), FormatEtcToString(*pformatetc).c_str()); + HRESULT hr = pIDataObject->QueryGetData(pformatetc); + dbgprintf(TEXT("IDataObject::QueryGetData -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(FORMATETC * pformatectIn, FORMATETC * pformatetcOut) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::GetCanonicalFormatEtc(%s, %p)"), FormatEtcToString(*pformatectIn).c_str(), pformatetcOut); + HRESULT hr = pIDataObject->GetCanonicalFormatEtc(pformatectIn, pformatetcOut); + dbgprintf(TEXT("IDataObject::GetCanonicalFormatEtc -> %08X, formatetcOut = %s"), hr, FormatEtcToString(*pformatetcOut).c_str()); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE SetData(FORMATETC * pformatetc, STGMEDIUM * pmedium, BOOL fRelease) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::SetData(%s, %p, %s)"), FormatEtcToString(*pformatetc).c_str(), MediumToString(*pmedium).c_str(), fRelease ? TEXT("true") : TEXT("false")); + HRESULT hr = pIDataObject->SetData(pformatetc, pmedium, fRelease); + dbgprintf(TEXT("IDataObject::SetData -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC ** ppenumFormatEtc) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::EnumFormatEtc(%lu, %p)"), dwDirection, ppenumFormatEtc); + HRESULT hr = pIDataObject->EnumFormatEtc(dwDirection, ppenumFormatEtc); + dbgprintf(TEXT("IDataObject::EnumFormatEtc -> %08X, penumFormatEtc = %p"), hr, *ppenumFormatEtc); + // TODO: hook + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE DAdvise(FORMATETC * pformatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::DAdvise(%s, %lu, %p, %p)"), FormatEtcToString(*pformatetc).c_str(), advf, pAdvSink, pdwConnection); + HRESULT hr = pIDataObject->DAdvise(pformatetc, advf, pAdvSink, pdwConnection); + dbgprintf(TEXT("IDataObject::DAdvise -> %08X, dwConnection = %lu"), hr, *pdwConnection); + // TODO: hook + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE DUnadvise(DWORD dwConnection) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::DUnadvise(%lu)"), dwConnection); + HRESULT hr = pIDataObject->DUnadvise(dwConnection); + dbgprintf(TEXT("IDataObject::DUnadvise -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE EnumDAdvise(IEnumSTATDATA ** ppenumAdvise) + { + IDataObject * pIDataObject = getIDataObject(); + dbgprintf(TEXT("IDataObject::EnumDAdvise(%p)"), ppenumAdvise); + HRESULT hr = pIDataObject->EnumDAdvise(ppenumAdvise); + dbgprintf(TEXT("IDataObject::EnumDAdvise -> %08X, penumAdvise = %p"), hr, *ppenumAdvise); + // TODO: hook + return hr; + } + + /* IObjectSafety */ + public: + virtual HRESULT STDMETHODCALLTYPE IObjectSafety::GetInterfaceSafetyOptions(REFIID riid, DWORD * pdwSupportedOptions, DWORD * pdwEnabledOptions) + { + IObjectSafety * pIObjectSafety = getIObjectSafety(); + dbgprintf(TEXT("IObjectSafety::GetInterfaceSafetyOptions(%ls, %p, %p)"), UUIDToString(riid).c_str(), pdwSupportedOptions, pdwEnabledOptions); + HRESULT hr = pIObjectSafety->GetInterfaceSafetyOptions(riid, pdwSupportedOptions, pdwEnabledOptions); + dbgprintf(TEXT("IObjectSafety::GetInterfaceSafetyOptions -> %08X, dwSupportedOptions = %08X, dwEnabledOptions = %08X"), hr, *pdwSupportedOptions, *pdwEnabledOptions); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IObjectSafety::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) + { + IObjectSafety * pIObjectSafety = getIObjectSafety(); + dbgprintf(TEXT("IObjectSafety::SetInterfaceSafetyOptions(%ls, %08X, %08X)"), UUIDToString(riid).c_str(), dwOptionSetMask, dwEnabledOptions); + HRESULT hr = pIObjectSafety->SetInterfaceSafetyOptions(riid, dwOptionSetMask, dwEnabledOptions); + dbgprintf(TEXT("IObjectSafety::SetInterfaceSafetyOptions -> %08X"), hr); + return hr; + } + + /* IOleControl */ + private: + std::basic_string ControlInfoToString(const CONTROLINFO& ci) + { + std::basic_ostringstream o; + + int firstdone = 0; + + o << "{ "; + + if(ci.cAccel && ci.hAccel) + { + LPACCEL pAccel = static_cast(GlobalLock(ci.hAccel)); + + if(pAccel) + { + for(USHORT i = 0; i < ci.cAccel; ++ i) + { + if(i) + o << ", "; + + if(pAccel[i].fVirt & FSHIFT) + o << "SHIFT + "; + + if(pAccel[i].fVirt & FCONTROL) + o << "CONTROL + "; + + if(pAccel[i].fVirt & FALT) + o << "ALT + "; + + if(pAccel[i].fVirt & FVIRTKEY) + o << ""; + else + o << wchar_t(pAccel[i].key); + + o << " " << std::hex << pAccel[i].cmd << std::dec; + } + + firstdone = ci.cAccel; + + GlobalUnlock(pAccel); + } + } + + if(ci.dwFlags & CTRLINFO_EATS_RETURN) + { + if(!firstdone) + { + o << ", "; + ++ firstdone; + } + + o << "ENTER"; + } + + if(ci.dwFlags & CTRLINFO_EATS_ESCAPE) + { + if(!firstdone) + { + o << ", "; + ++ firstdone; + } + + o << "ESC"; + } + + if(firstdone) + o << " "; + + o << "}"; + + return o.str(); + } + + std::basic_string MnemonicToString(const MSG& msg) + { + std::basic_ostringstream o; + + o << "["; + + switch(msg.message) + { + case WM_SYSKEYDOWN: + o << "ALT + "; + + case WM_KEYDOWN: + TCHAR sz[1024]; + GetKeyNameText(LONG(msg.lParam), sz, ARRAYSIZE(sz)); + o << sz; + + default: + o << ""; + } + + o << "]"; + + return o.str(); + } + + public: + virtual HRESULT STDMETHODCALLTYPE GetControlInfo(CONTROLINFO * pCI) + { + IOleControl * pIOleControl = getIOleControl(); + dbgprintf(TEXT("IOleControl::GetControlInfo(%p)"), pCI); + HRESULT hr = pIOleControl->GetControlInfo(pCI); + dbgprintf(TEXT("IOleControl::GetControlInfo -> %08X, %s"), hr, ControlInfoToString(*pCI).c_str()); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE OnMnemonic(MSG * pMsg) + { + IOleControl * pIOleControl = getIOleControl(); + dbgprintf(TEXT("IOleControl::OnMnemonic(%s)"), MnemonicToString(*pMsg).c_str()); + HRESULT hr = pIOleControl->OnMnemonic(pMsg); + dbgprintf(TEXT("IOleControl::OnMnemonic -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE OnAmbientPropertyChange(DISPID dispID) + { + IOleControl * pIOleControl = getIOleControl(); + dbgprintf(TEXT("IOleControl::OnAmbientPropertyChange(%08X)"), dispID); + HRESULT hr = pIOleControl->OnAmbientPropertyChange(dispID); + dbgprintf(TEXT("IOleControl::OnAmbientPropertyChange -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE FreezeEvents(BOOL bFreeze) + { + IOleControl * pIOleControl = getIOleControl(); + dbgprintf(TEXT("IOleControl::FreezeEvents(%s)"), BooleanToString(bFreeze)); + HRESULT hr = pIOleControl->FreezeEvents(bFreeze); + dbgprintf(TEXT("IOleControl::FreezeEvents -> %08X"), hr); + return hr; + } + + /* IOleInPlaceActiveObject */ + public: + virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG lpmsg) + { + IOleInPlaceActiveObject * pIOleInPlaceActiveObject = getIOleInPlaceActiveObject(); + dbgprintf(TEXT("IOleInPlaceActiveObject::TranslateAccelerator(%s)"), MnemonicToString(*lpmsg).c_str()); + HRESULT hr = pIOleInPlaceActiveObject->TranslateAccelerator(lpmsg); + dbgprintf(TEXT("IOleInPlaceActiveObject::TranslateAccelerator -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(BOOL fActivate) + { + IOleInPlaceActiveObject * pIOleInPlaceActiveObject = getIOleInPlaceActiveObject(); + dbgprintf(TEXT("IOleInPlaceActiveObject::OnFrameWindowActivate(%s)"), BooleanToString(fActivate)); + HRESULT hr = pIOleInPlaceActiveObject->OnFrameWindowActivate(fActivate); + dbgprintf(TEXT("IOleInPlaceActiveObject::OnFrameWindowActivate -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate(BOOL fActivate) + { + IOleInPlaceActiveObject * pIOleInPlaceActiveObject = getIOleInPlaceActiveObject(); + dbgprintf(TEXT("IOleInPlaceActiveObject::OnDocWindowActivate(%s)"), BooleanToString(fActivate)); + HRESULT hr = pIOleInPlaceActiveObject->OnDocWindowActivate(fActivate); + dbgprintf(TEXT("IOleInPlaceActiveObject::OnDocWindowActivate -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow * pUIWindow, BOOL fFrameWindow) + { + // TODO: hook pUIWindow + IOleInPlaceActiveObject * pIOleInPlaceActiveObject = getIOleInPlaceActiveObject(); + dbgprintf(TEXT("IOleInPlaceActiveObject::ResizeBorder(%s)"), RectToString(*prcBorder).c_str(), pUIWindow, BooleanToString(fFrameWindow)); + HRESULT hr = pIOleInPlaceActiveObject->ResizeBorder(prcBorder, pUIWindow, fFrameWindow); + dbgprintf(TEXT("IOleInPlaceActiveObject::ResizeBorder -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL fEnable) + { + IOleInPlaceActiveObject * pIOleInPlaceActiveObject = getIOleInPlaceActiveObject(); + dbgprintf(TEXT("IOleInPlaceActiveObject::EnableModeless(%s)"), BooleanToString(fEnable)); + HRESULT hr = pIOleInPlaceActiveObject->EnableModeless(fEnable); + dbgprintf(TEXT("IOleInPlaceActiveObject::EnableModeless -> %08X"), hr); + return hr; + } + + /* IOleInPlaceObject */ + public: + virtual HRESULT STDMETHODCALLTYPE InPlaceDeactivate(void) + { + IOleInPlaceObject * pIOleInPlaceObject = getIOleInPlaceObject(); + dbgprintf(TEXT("IOleInPlaceObject::InPlaceDeactivate()")); + HRESULT hr = pIOleInPlaceObject->InPlaceDeactivate(); + dbgprintf(TEXT("IOleInPlaceObject::InPlaceDeactivate -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE UIDeactivate(void) + { + IOleInPlaceObject * pIOleInPlaceObject = getIOleInPlaceObject(); + dbgprintf(TEXT("IOleInPlaceObject::UIDeactivate()")); + HRESULT hr = pIOleInPlaceObject->UIDeactivate(); + dbgprintf(TEXT("IOleInPlaceObject::UIDeactivate -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect) + { + IOleInPlaceObject * pIOleInPlaceObject = getIOleInPlaceObject(); + dbgprintf(TEXT("IOleInPlaceObject::SetObjectRects(%s, %s)"), RectToString(*lprcPosRect).c_str(), RectToString(*lprcClipRect).c_str()); + HRESULT hr = pIOleInPlaceObject->SetObjectRects(lprcPosRect, lprcClipRect); + dbgprintf(TEXT("IOleInPlaceObject::SetObjectRects -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE ReactivateAndUndo(void) + { + IOleInPlaceObject * pIOleInPlaceObject = getIOleInPlaceObject(); + dbgprintf(TEXT("IOleInPlaceObject::ReactivateAndUndo()")); + HRESULT hr = pIOleInPlaceObject->ReactivateAndUndo(); + dbgprintf(TEXT("IOleInPlaceObject::ReactivateAndUndo -> %08X"), hr); + return hr; + } + + /* IOleWindow */ + public: + virtual HRESULT STDMETHODCALLTYPE GetWindow(HWND * phwnd) + { + IOleWindow * pIOleWindow = getIOleWindow(); + dbgprintf(TEXT("IOleWindow::GetWindow(%p)"), phwnd); + HRESULT hr = pIOleWindow->GetWindow(phwnd); + dbgprintf(TEXT("IOleWindow::GetWindow -> %08X, hwnd = %X"), hr, *phwnd); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode) + { + IOleWindow * pIOleWindow = getIOleWindow(); + dbgprintf(TEXT("IOleWindow::ContextSensitiveHelp(%s)"), BooleanToString(fEnterMode)); + HRESULT hr = pIOleWindow->ContextSensitiveHelp(fEnterMode); + dbgprintf(TEXT("IOleWindow::ContextSensitiveHelp -> %08X"), hr); + return hr; + } + + /* IOleObject */ + public: + virtual HRESULT STDMETHODCALLTYPE SetClientSite(IOleClientSite * pClientSite) + { + // TODO: hook pClientSite + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::SetClientSite(%p)"), pClientSite); + HRESULT hr = pIOleObject->SetClientSite(pClientSite); + dbgprintf(TEXT("IOleObject::SetClientSite -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetClientSite(IOleClientSite ** ppClientSite) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::GetClientSite(%s)"), ppClientSite); + HRESULT hr = pIOleObject->GetClientSite(ppClientSite); + dbgprintf(TEXT("IOleObject::GetClientSite -> %08X"), hr, ppClientSite); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::SetHostNames(%ls, %ls)"), szContainerApp, szContainerObj); + HRESULT hr = pIOleObject->SetHostNames(szContainerApp, szContainerObj); + dbgprintf(TEXT("IOleObject::SetHostNames -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Close(DWORD dwSaveOption) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::Close(%lu)"), dwSaveOption); + HRESULT hr = pIOleObject->Close(dwSaveOption); + dbgprintf(TEXT("IOleObject::Close -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE SetMoniker(DWORD dwWhichMoniker, IMoniker * pmk) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::SetMoniker(%lu, %p)"), dwWhichMoniker, MonikerToString(pmk).c_str()); + HRESULT hr = pIOleObject->SetMoniker(dwWhichMoniker, pmk); + dbgprintf(TEXT("IOleObject::SetMoniker -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::GetMoniker(%lu, %lu, %p)"), dwAssign, dwWhichMoniker, ppmk); + HRESULT hr = pIOleObject->GetMoniker(dwAssign, dwWhichMoniker, ppmk); + dbgprintf(TEXT("IOleObject::GetMoniker -> %08X, pmk = %s"), hr, SUCCEEDED(hr) ? MonikerToString(*ppmk).c_str() : TEXT("")); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE InitFromData(IDataObject * pDataObject, BOOL fCreation, DWORD dwReserved) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::InitFromData(%p, %s, %lu)"), pDataObject, BooleanToString(fCreation), dwReserved); + HRESULT hr = pIOleObject->InitFromData(pDataObject, fCreation, dwReserved); + dbgprintf(TEXT("IOleObject::InitFromData -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetClipboardData(DWORD dwReserved, IDataObject ** ppDataObject) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::GetClipboardData(%lu, %p)"), dwReserved, ppDataObject); + HRESULT hr = pIOleObject->GetClipboardData(dwReserved, ppDataObject); + dbgprintf(TEXT("IOleObject::GetClipboardData -> %08X, pDataObject = %p"), hr, *ppDataObject); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite * pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::DoVerb(%ld, %p, %p, %ld, %p, %s)"), iVerb, lpmsg, pActiveSite, lindex, hwndParent, RectToString(*lprcPosRect).c_str()); + HRESULT hr = pIOleObject->DoVerb(iVerb, lpmsg, pActiveSite, lindex, hwndParent, lprcPosRect); + dbgprintf(TEXT("IOleObject::DoVerb -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE EnumVerbs(IEnumOLEVERB ** ppEnumOleVerb) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::EnumVerbs(%p)"), ppEnumOleVerb); + HRESULT hr = pIOleObject->EnumVerbs(ppEnumOleVerb); + dbgprintf(TEXT("IOleObject::EnumVerbs -> %08X, pEnumOleVerb = %p"), hr, *ppEnumOleVerb); + // TODO: hook + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Update(void) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::Update(%s)")); + HRESULT hr = pIOleObject->Update(); + dbgprintf(TEXT("IOleObject::Update -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IsUpToDate(void) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::IsUpToDate(%s)")); + HRESULT hr = pIOleObject->IsUpToDate(); + dbgprintf(TEXT("IOleObject::IsUpToDate -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetUserClassID(CLSID * pClsid) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::GetUserClassID(%p)"), pClsid); + HRESULT hr = pIOleObject->GetUserClassID(pClsid); + dbgprintf(TEXT("IOleObject::GetUserClassID -> %08X, Clsid = %ls"), hr, UUIDToString(*pClsid).c_str()); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetUserType(DWORD dwFormOfType, LPOLESTR * pszUserType) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::GetUserType(%lu, %p)"), dwFormOfType, pszUserType); + HRESULT hr = pIOleObject->GetUserType(dwFormOfType, pszUserType); + dbgprintf(TEXT("IOleObject::GetUserType -> %08X, szUserType = %s"), hr, *pszUserType); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE SetExtent(DWORD dwDrawAspect, SIZEL * psizel) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::SetExtent(%lu, %s)"), dwDrawAspect, SizeToString(*psizel).c_str()); + HRESULT hr = pIOleObject->SetExtent(dwDrawAspect, psizel); + dbgprintf(TEXT("IOleObject::SetExtent -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetExtent(DWORD dwDrawAspect, SIZEL * psizel) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::GetExtent(%lu, %p)"), dwDrawAspect, psizel); + HRESULT hr = pIOleObject->GetExtent(dwDrawAspect, psizel); + dbgprintf(TEXT("IOleObject::GetExtent -> %08X"), hr, SizeToString(*psizel).c_str()); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Advise(IAdviseSink * pAdvSink, DWORD * pdwConnection) + { + // TODO: hook pAdvSink + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::Advise(%p, %p)"), pAdvSink, pdwConnection); + HRESULT hr = pIOleObject->Advise(pAdvSink, pdwConnection); + dbgprintf(TEXT("IOleObject::Advise -> %08X, dwConnection = %lu"), hr, *pdwConnection); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Unadvise(DWORD dwConnection) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::Unadvise(%lu)"), dwConnection); + HRESULT hr = pIOleObject->Unadvise(dwConnection); + dbgprintf(TEXT("IOleObject::Unadvise -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE EnumAdvise(IEnumSTATDATA ** ppenumAdvise) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::EnumAdvise(%p)"), ppenumAdvise); + HRESULT hr = pIOleObject->EnumAdvise(ppenumAdvise); + dbgprintf(TEXT("IOleObject::EnumAdvise -> %08X, penumAdvise = %p"), hr, *ppenumAdvise); + // TODO: hook + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE GetMiscStatus(DWORD dwAspect, DWORD * pdwStatus) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::GetMiscStatus(%lu, %p)"), dwAspect, pdwStatus); + HRESULT hr = pIOleObject->GetMiscStatus(dwAspect, pdwStatus); + dbgprintf(TEXT("IOleObject::GetMiscStatus -> %08X, dwStatus = %08X"), hr, *pdwStatus); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE SetColorScheme(LOGPALETTE * pLogpal) + { + IOleObject * pIOleObject = getIOleObject(); + dbgprintf(TEXT("IOleObject::SetColorScheme(%p)"), pLogpal); + HRESULT hr = pIOleObject->SetColorScheme(pLogpal); + dbgprintf(TEXT("IOleObject::SetColorScheme -> %08X"), hr); + return hr; + } + + /* IPersist */ + public: + virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID * pClassID) + { + IPersist * pIPersist = getIPersist(); + dbgprintf(TEXT("IPersist::GetClassID(%p)"), pClassID); + HRESULT hr = pIPersist->GetClassID(pClassID); + dbgprintf(TEXT("IPersist::GetClassID -> %08X, ClassId = %ls"), hr, UUIDToString(*pClassID).c_str()); + return hr; + } + + /* IPersistPropertyBag */ + public: + virtual HRESULT STDMETHODCALLTYPE InitNew(void) + { + IPersistPropertyBag * pIPersistPropertyBag = getIPersistPropertyBag(); + dbgprintf(TEXT("IPersistPropertyBag::InitNew()")); + HRESULT hr = pIPersistPropertyBag->InitNew(); + dbgprintf(TEXT("IPersistPropertyBag::InitNew -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Load(IPropertyBag * pPropBag, IErrorLog * pErrorLog) + { + // TODO: hook pPropBag, pErrorLog + IPersistPropertyBag * pIPersistPropertyBag = getIPersistPropertyBag(); + dbgprintf(TEXT("IPersistPropertyBag::Load(%p, %p)"), pPropBag, pErrorLog); + HRESULT hr = pIPersistPropertyBag->Load(pPropBag, pErrorLog); + dbgprintf(TEXT("IPersistPropertyBag::Load -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Save(IPropertyBag * pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties) + { + // TODO: hook pPropBag + IPersistPropertyBag * pIPersistPropertyBag = getIPersistPropertyBag(); + dbgprintf(TEXT("IPersistPropertyBag::Save(%p, %s, %s)"), pPropBag, BooleanToString(fClearDirty), BooleanToString(fSaveAllProperties)); + HRESULT hr = pIPersistPropertyBag->Save(pPropBag, fClearDirty, fSaveAllProperties); + dbgprintf(TEXT("IPersistPropertyBag::Save -> %08X"), hr); + return hr; + } + + /* IPersistStorage */ + public: + virtual HRESULT STDMETHODCALLTYPE IPersistStorage::IsDirty(void) + { + IPersistStorage * pIPersistStorage = getIPersistStorage(); + dbgprintf(TEXT("IPersistStorage::IsDirty()")); + HRESULT hr = pIPersistStorage->IsDirty(); + dbgprintf(TEXT("IPersistStorage::IsDirty -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IPersistStorage::InitNew(IStorage * pStg) + { + IPersistStorage * pIPersistStorage = getIPersistStorage(); + dbgprintf(TEXT("IPersistStorage::InitNew(%p)"), pStg); + HRESULT hr = pIPersistStorage->InitNew(pStg); + dbgprintf(TEXT("IPersistStorage::InitNew -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IPersistStorage::Load(IStorage * pStg) + { + IPersistStorage * pIPersistStorage = getIPersistStorage(); + dbgprintf(TEXT("IPersistStorage::Load(%p)"), pStg); + HRESULT hr = pIPersistStorage->Load(pStg); + dbgprintf(TEXT("IPersistStorage::Load -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IPersistStorage::Save(IStorage * pStgSave, BOOL fSameAsLoad) + { + IPersistStorage * pIPersistStorage = getIPersistStorage(); + dbgprintf(TEXT("IPersistStorage::Save(%p, %s)"), pStgSave, BooleanToString(fSameAsLoad)); + HRESULT hr = pIPersistStorage->Save(pStgSave, fSameAsLoad); + dbgprintf(TEXT("IPersistStorage::Save -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE SaveCompleted(IStorage * pStgNew) + { + IPersistStorage * pIPersistStorage = getIPersistStorage(); + dbgprintf(TEXT("IPersistStorage::SaveCompleted(%p)"), pStgNew); + HRESULT hr = pIPersistStorage->SaveCompleted(pStgNew); + dbgprintf(TEXT("IPersistStorage::SaveCompleted -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE HandsOffStorage(void) + { + IPersistStorage * pIPersistStorage = getIPersistStorage(); + dbgprintf(TEXT("IPersistStorage::HandsOffStorage()")); + HRESULT hr = pIPersistStorage->HandsOffStorage(); + dbgprintf(TEXT("IPersistStorage::HandsOffStorage -> %08X"), hr); + return hr; + } + + /* IPersistStreamInit */ + public: + virtual HRESULT STDMETHODCALLTYPE IPersistStreamInit::IsDirty(void) + { + IPersistStreamInit * pIPersistStreamInit = getIPersistStreamInit(); + dbgprintf(TEXT("IPersistStreamInit::IsDirty()")); + HRESULT hr = pIPersistStreamInit->IsDirty(); + dbgprintf(TEXT("IPersistStreamInit::IsDirty -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IPersistStreamInit::Load(LPSTREAM pStm) + { + IPersistStreamInit * pIPersistStreamInit = getIPersistStreamInit(); + dbgprintf(TEXT("IPersistStreamInit::Load(%p)"), pStm); + HRESULT hr = pIPersistStreamInit->Load(pStm); + dbgprintf(TEXT("IPersistStreamInit::Load -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IPersistStreamInit::Save(LPSTREAM pStm, BOOL fClearDirty) + { + IPersistStreamInit * pIPersistStreamInit = getIPersistStreamInit(); + dbgprintf(TEXT("IPersistStreamInit::Save(%p, %s)"), pStm, BooleanToString(fClearDirty)); + HRESULT hr = pIPersistStreamInit->Save(pStm, fClearDirty); + dbgprintf(TEXT("IPersistStreamInit::Save -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IPersistStreamInit::GetSizeMax(ULARGE_INTEGER * pCbSize) + { + IPersistStreamInit * pIPersistStreamInit = getIPersistStreamInit(); + dbgprintf(TEXT("IPersistStreamInit::GetSizeMax(%p)"), pCbSize); + HRESULT hr = pIPersistStreamInit->GetSizeMax(pCbSize); + dbgprintf(TEXT("IPersistStreamInit::GetSizeMax -> %08X, CbSize = %llu"), hr, pCbSize->QuadPart); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IPersistStreamInit::InitNew(void) + { + IPersistStreamInit * pIPersistStreamInit = getIPersistStreamInit(); + dbgprintf(TEXT("IPersistStreamInit::InitNew()")); + HRESULT hr = pIPersistStreamInit->InitNew(); + dbgprintf(TEXT("IPersistStreamInit::InitNew -> %08X"), hr); + return hr; + } + + /* IProvideClassInfo */ + public: + virtual HRESULT STDMETHODCALLTYPE GetClassInfo(ITypeInfo ** ppTI) + { + IProvideClassInfo * pIProvideClassInfo = getIProvideClassInfo(); + dbgprintf(TEXT("IProvideClassInfo::GetClassInfo(%p)"), ppTI); + HRESULT hr = pIProvideClassInfo->GetClassInfo(ppTI); + dbgprintf(TEXT("IProvideClassInfo::GetClassInfo -> %08X, pTI = %p"), hr, *ppTI); + return hr; + } + + /* IProvideClassInfo2 */ + public: + virtual HRESULT STDMETHODCALLTYPE IProvideClassInfo2::GetGUID(DWORD dwGuidKind, GUID * pGUID) + { + IProvideClassInfo2 * pIProvideClassInfo2 = getIProvideClassInfo2(); + dbgprintf(TEXT("IProvideClassInfo2::GetGUID(%lu, %p)"), dwGuidKind, pGUID); + HRESULT hr = pIProvideClassInfo2->GetGUID(dwGuidKind, pGUID); + dbgprintf(TEXT("IProvideClassInfo2::GetGUID -> %08X, GUID = %ls"), hr, UUIDToString(*pGUID).c_str()); + return hr; + } + + /* IQuickActivate */ + public: + virtual HRESULT STDMETHODCALLTYPE IQuickActivate::QuickActivate(QACONTAINER * pQaContainer, QACONTROL * pQaControl) // TODO + { + IQuickActivate * pIQuickActivate = getIQuickActivate(); + + std::basic_stringstream o1; + + o1 << "{ "; + o1 << "pClientSite = " << (void *)pQaContainer->pClientSite << ", "; + o1 << "pAdviseSink = " << (void *)pQaContainer->pAdviseSink << ", "; + o1 << "pPropertyNotifySink = " << (void *)pQaContainer->pPropertyNotifySink << ", "; + o1 << "pUnkEventSink = " << (void *)pQaContainer->pUnkEventSink << ", "; + + o1 << std::hex; + o1 << "dwAmbientFlags = " << pQaContainer->dwAmbientFlags << ", "; + o1 << "colorFore = " << pQaContainer->colorFore << ", "; + o1 << "colorBack = " << pQaContainer->colorBack << ", "; + o1 << std::dec; + + o1 << "pFont = " << (void *)pQaContainer->pFont << ", "; + o1 << "pUndoMgr = " << (void *)pQaContainer->pUndoMgr << ", "; + + o1 << std::hex; + o1 << "dwAppearance = " << pQaContainer->dwAppearance << ", "; + o1 << "lcid = " << pQaContainer->lcid << ", "; + o1 << std::dec; + + o1 << "hpal = " << (void *)pQaContainer->hpal << ", "; + o1 << "pBindHost = " << (void *)pQaContainer->pBindHost << ", "; + o1 << "pOleControlSite = " << (void *)pQaContainer->pOleControlSite << ", "; + o1 << "pServiceProvider = " << (void *)pQaContainer->pServiceProvider << ", "; + o1 << "}"; + + dbgprintf(TEXT("IQuickActivate::QuickActivate(%s, %p)"), o1.str().c_str(), pQaControl); + + HRESULT hr = pIQuickActivate->QuickActivate(pQaContainer, pQaControl); + + std::basic_stringstream o2; + + o2 << "{ "; + o2 << std::hex; + o2 << "dwMiscStatus = " << pQaControl->dwMiscStatus << ", "; + o2 << "dwViewStatus = " << pQaControl->dwViewStatus << ", "; + o2 << "dwEventCookie = " << pQaControl->dwEventCookie << ", "; + o2 << "dwPropNotifyCookie = " << pQaControl->dwPropNotifyCookie << ", "; + o2 << "dwPointerActivationPolicy = " << pQaControl->dwPointerActivationPolicy << ", "; + o2 << std::dec; + o2 << "}"; + + dbgprintf(TEXT("IQuickActivate::QuickActivate -> %08X, QaControl = %s"), hr, o2.str().c_str()); + + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IQuickActivate::SetContentExtent(LPSIZEL pSizel) + { + IQuickActivate * pIQuickActivate = getIQuickActivate(); + dbgprintf(TEXT("IQuickActivate::SetContentExtent(%s)"), SizeToString(*pSizel).c_str()); + HRESULT hr = pIQuickActivate->SetContentExtent(pSizel); + dbgprintf(TEXT("IQuickActivate::SetContentExtent -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IQuickActivate::GetContentExtent(LPSIZEL pSizel) + { + IQuickActivate * pIQuickActivate = getIQuickActivate(); + dbgprintf(TEXT("IQuickActivate::GetContentExtent(%p)"), pSizel); + HRESULT hr = pIQuickActivate->GetContentExtent(pSizel); + dbgprintf(TEXT("IQuickActivate::GetContentExtent -> %08X, Sizel = %s"), hr, SizeToString(*pSizel).c_str()); + return hr; + } + + /* ISpecifyPropertyPages */ + private: + std::basic_string CauuidToString(const CAUUID& cauuid) + { + std::basic_ostringstream o; + + o << "{"; + + for(ULONG i = 0; i < cauuid.cElems; ++ i) + { + if(i) + o << ", "; + else + o << " "; + + o << UUIDToString(cauuid.pElems[i]); + } + + o << " }"; + + return o.str(); + } + + public: + virtual HRESULT STDMETHODCALLTYPE ISpecifyPropertyPages::GetPages(CAUUID * pPages) + { + ISpecifyPropertyPages * pISpecifyPropertyPages = getISpecifyPropertyPages(); + dbgprintf(TEXT("ISpecifyPropertyPages::GetPages(%p)"), pPages); + HRESULT hr = pISpecifyPropertyPages->GetPages(pPages); + dbgprintf(TEXT("ISpecifyPropertyPages::GetPages -> %08X, Pages = %s"), hr, CauuidToString(*pPages).c_str()); + return hr; + } + + /* IViewObject */ + public: + virtual HRESULT STDMETHODCALLTYPE IViewObject::Draw(DWORD dwDrawAspect, LONG lindex, void * pvAspect, DVTARGETDEVICE * ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL (STDMETHODCALLTYPE * pfnContinue)(ULONG_PTR dwContinue), ULONG_PTR dwContinue) + { + IViewObject * pIViewObject = getIViewObject(); + dbgprintf(TEXT("IViewObject::Draw(%s, %ld, %p, %s, %p, %p, %s, %s, %p, %p)"), AspectToString(dwDrawAspect), lindex, pvAspect, TargetDeviceToString(*ptd).c_str(), hdcTargetDev, hdcDraw, RectToString(*lprcBounds).c_str(), RectToString(*lprcWBounds).c_str(), pfnContinue, dwContinue); + HRESULT hr = pIViewObject->Draw(dwDrawAspect, lindex, pvAspect, ptd, hdcTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue); + dbgprintf(TEXT("IViewObject::Draw -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IViewObject::GetColorSet(DWORD dwDrawAspect, LONG lindex, void * pvAspect, DVTARGETDEVICE * ptd, HDC hicTargetDev, LOGPALETTE ** ppColorSet) + { + IViewObject * pIViewObject = getIViewObject(); + dbgprintf(TEXT("IViewObject::GetColorSet(%s, %ld, %p, %s, %p, %p)"), AspectToString(dwDrawAspect), lindex, pvAspect, TargetDeviceToString(*ptd).c_str(), hicTargetDev, ppColorSet); + HRESULT hr = pIViewObject->GetColorSet(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, ppColorSet); + dbgprintf(TEXT("IViewObject::GetColorSet -> %08X, pColorSet = %p"), hr, *ppColorSet); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IViewObject::Freeze(DWORD dwDrawAspect, LONG lindex, void * pvAspect, DWORD * pdwFreeze) + { + IViewObject * pIViewObject = getIViewObject(); + dbgprintf(TEXT("IViewObject::Freeze(%s, %ld, %p, %p)"), AspectToString(dwDrawAspect), lindex, pvAspect, pdwFreeze); + HRESULT hr = pIViewObject->Freeze(dwDrawAspect, lindex, pvAspect, pdwFreeze); + dbgprintf(TEXT("IViewObject::Freeze -> %08X, dwFreeze = %08X"), hr, *pdwFreeze); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IViewObject::Unfreeze(DWORD dwFreeze) + { + IViewObject * pIViewObject = getIViewObject(); + dbgprintf(TEXT("IViewObject::Unfreeze(%08X)"), dwFreeze); + HRESULT hr = pIViewObject->Unfreeze(dwFreeze); + dbgprintf(TEXT("IViewObject::Unfreeze -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IViewObject::SetAdvise(DWORD aspects, DWORD advf, IAdviseSink * pAdvSink) + { + IViewObject * pIViewObject = getIViewObject(); + dbgprintf(TEXT("IViewObject::SetAdvise(%s, %08X, %p)"), AspectToString(aspects), advf, pAdvSink); + HRESULT hr = pIViewObject->SetAdvise(aspects, advf, pAdvSink); + dbgprintf(TEXT("IViewObject::SetAdvise -> %08X"), hr); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE IViewObject::GetAdvise(DWORD * pAspects, DWORD * pAdvf, IAdviseSink ** ppAdvSink) + { + IViewObject * pIViewObject = getIViewObject(); + dbgprintf(TEXT("IViewObject::GetAdvise(%p, %p, %p)"), pAspects, pAdvf, ppAdvSink); + HRESULT hr = pIViewObject->GetAdvise(pAspects, pAdvf, ppAdvSink); + dbgprintf(TEXT("IViewObject::GetAdvise -> %08X, aspects = %s, advf = %08X, pAdvSink %p"), hr, AspectToString(*pAspects), *pAdvf, *ppAdvSink); + return hr; + } + + /* IViewObject2 */ + public: + virtual HRESULT STDMETHODCALLTYPE IViewObject2::GetExtent(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE * ptd, LPSIZEL lpsizel) + { + IViewObject2 * pIViewObject2 = getIViewObject2(); + dbgprintf(TEXT("IViewObject2::GetExtent(%s, %ld, %s, %p)"), AspectToString(dwDrawAspect), lindex, TargetDeviceToString(*ptd).c_str(), lpsizel); + HRESULT hr = pIViewObject2->GetExtent(dwDrawAspect, lindex, ptd, lpsizel); + dbgprintf(TEXT("IViewObject2::GetExtent -> %08X, sizel = %s"), hr, SizeToString(*lpsizel).c_str()); + return hr; + } + + /* IMsTscAx */ + public: + virtual HRESULT __stdcall put_Server(BSTR pServer) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_Server(%ls)"), pServer); + HRESULT hr = pIMsTscAx->put_Server(pServer); + dbgprintf(TEXT("IMsTscAx::put_Server -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_Server(BSTR * pServer) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_Server()"), pServer); + HRESULT hr = pIMsTscAx->get_Server(pServer); + dbgprintf(TEXT("IMsTscAx::get_Server -> %08X, server = %ls"), hr, *pServer); + return hr; + } + + virtual HRESULT __stdcall put_Domain(BSTR pDomain) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_Domain(%ls)"), pDomain); + HRESULT hr = pIMsTscAx->put_Domain(pDomain); + dbgprintf(TEXT("IMsTscAx::put_Domain -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_Domain(BSTR * pDomain) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_Domain(%p)"), pDomain); + HRESULT hr = pIMsTscAx->get_Domain(pDomain); + dbgprintf(TEXT("IMsTscAx::get_Domain -> %08X, Domain = %ls"), hr, *pDomain); + return hr; + } + + virtual HRESULT __stdcall put_UserName(BSTR pUserName) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_UserName(%ls)"), pUserName); + HRESULT hr = pIMsTscAx->put_UserName(pUserName); + dbgprintf(TEXT("IMsTscAx::put_UserName -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_UserName(BSTR * pUserName) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_UserName(%p)"), pUserName); + HRESULT hr = pIMsTscAx->get_UserName(pUserName); + dbgprintf(TEXT("IMsTscAx::get_UserName -> %08X, UserName = %ls"), hr, *pUserName); + return hr; + } + + virtual HRESULT __stdcall put_DisconnectedText(BSTR pDisconnectedText) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_DisconnectedText(%ls)"), pDisconnectedText); + HRESULT hr = pIMsTscAx->put_DisconnectedText(pDisconnectedText); + dbgprintf(TEXT("IMsTscAx::put_DisconnectedText -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_DisconnectedText(BSTR * pDisconnectedText) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_DisconnectedText(%p)"), pDisconnectedText); + HRESULT hr = pIMsTscAx->get_DisconnectedText(pDisconnectedText); + dbgprintf(TEXT("IMsTscAx::get_DisconnectedText -> %08X, DisconnectedText = %ls"), hr, *pDisconnectedText); + return hr; + } + + virtual HRESULT __stdcall put_ConnectingText(BSTR pConnectingText) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_ConnectingText(%ls)"), pConnectingText); + HRESULT hr = pIMsTscAx->put_ConnectingText(pConnectingText); + dbgprintf(TEXT("IMsTscAx::put_ConnectingText -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_ConnectingText(BSTR * pConnectingText) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_ConnectingText(%p)"), pConnectingText); + HRESULT hr = pIMsTscAx->get_ConnectingText(pConnectingText); + dbgprintf(TEXT("IMsTscAx::get_ConnectingText -> %08X, ConnectingText = %ls"), hr, *pConnectingText); + return hr; + } + + virtual HRESULT __stdcall get_Connected(short * pIsConnected) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_Connected(%p)"), pIsConnected); + HRESULT hr = pIMsTscAx->get_Connected(pIsConnected); + dbgprintf(TEXT("IMsTscAx::get_Connected -> %08X, IsConnected = %s"), hr, BooleanToString(*pIsConnected)); + return hr; + } + + virtual HRESULT __stdcall put_DesktopWidth(long pVal) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_DesktopWidth(%ld)"), pVal); + HRESULT hr = pIMsTscAx->put_DesktopWidth(pVal); + dbgprintf(TEXT("IMsTscAx::put_DesktopWidth -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_DesktopWidth(long * pVal) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_DesktopWidth(%p)"), pVal); + HRESULT hr = pIMsTscAx->get_DesktopWidth(pVal); + dbgprintf(TEXT("IMsTscAx::get_DesktopWidth -> %08X, Val = %lu"), hr, *pVal); + return hr; + } + + virtual HRESULT __stdcall put_DesktopHeight(long pVal) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_DesktopHeight(%ld)"), pVal); + HRESULT hr = pIMsTscAx->put_DesktopHeight(pVal); + dbgprintf(TEXT("IMsTscAx::put_DesktopHeight -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_DesktopHeight(long * pVal) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_DesktopHeight(%p)"), pVal); + HRESULT hr = pIMsTscAx->get_DesktopHeight(pVal); + dbgprintf(TEXT("IMsTscAx::get_DesktopHeight -> %08X, Val = %lu"), hr, *pVal); + return hr; + } + + virtual HRESULT __stdcall put_StartConnected(long pfStartConnected) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_StartConnected(%s)"), BooleanToString(pfStartConnected)); + HRESULT hr = pIMsTscAx->put_StartConnected(pfStartConnected); + dbgprintf(TEXT("IMsTscAx::put_StartConnected -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_StartConnected(long * pfStartConnected) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_StartConnected(%p)"), pfStartConnected); + HRESULT hr = pIMsTscAx->get_StartConnected(pfStartConnected); + dbgprintf(TEXT("IMsTscAx::get_StartConnected -> %08X, fStartConnected = %s"), hr, BooleanToString(*pfStartConnected)); + return hr; + } + + virtual HRESULT __stdcall get_HorizontalScrollBarVisible(long * pfHScrollVisible) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_HorizontalScrollBarVisible(%p)"), pfHScrollVisible); + HRESULT hr = pIMsTscAx->get_HorizontalScrollBarVisible(pfHScrollVisible); + dbgprintf(TEXT("IMsTscAx::get_HorizontalScrollBarVisible -> %08X, fHScrollVisible = %s"), hr, BooleanToString(*pfHScrollVisible)); + return hr; + } + + virtual HRESULT __stdcall get_VerticalScrollBarVisible(long * pfVScrollVisible) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_VerticalScrollBarVisible(%p)"), pfVScrollVisible); + HRESULT hr = pIMsTscAx->get_VerticalScrollBarVisible(pfVScrollVisible); + dbgprintf(TEXT("IMsTscAx::get_VerticalScrollBarVisible -> %08X, fVScrollVisible"), hr, *pfVScrollVisible); + return hr; + } + + virtual HRESULT __stdcall put_FullScreenTitle(BSTR _arg1) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::put_FullScreenTitle(%ls)"), _arg1); + HRESULT hr = pIMsTscAx->put_FullScreenTitle(_arg1); + dbgprintf(TEXT("IMsTscAx::put_FullScreenTitle -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_CipherStrength(long * pCipherStrength) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_CipherStrength(%p)"), pCipherStrength); + HRESULT hr = pIMsTscAx->get_CipherStrength(pCipherStrength); + dbgprintf(TEXT("IMsTscAx::get_CipherStrength -> %08X, CipherStrength = %ld"), hr, *pCipherStrength); + return hr; + } + + virtual HRESULT __stdcall get_Version(BSTR * pVersion) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_Version(%p)"), pVersion); + HRESULT hr = pIMsTscAx->get_Version(pVersion); + dbgprintf(TEXT("IMsTscAx::get_Version -> %08X, Version = %ls"), hr, *pVersion); + return hr; + } + + virtual HRESULT __stdcall get_SecuredSettingsEnabled(long * pSecuredSettingsEnabled) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_SecuredSettingsEnabled(%p)"), pSecuredSettingsEnabled); + HRESULT hr = pIMsTscAx->get_SecuredSettingsEnabled(pSecuredSettingsEnabled); + dbgprintf(TEXT("IMsTscAx::get_SecuredSettingsEnabled -> %08X, SecuredSettingsEnabled = %s"), hr, BooleanToString(*pSecuredSettingsEnabled)); + return hr; + } + + virtual HRESULT __stdcall get_SecuredSettings(IMsTscSecuredSettings ** ppSecuredSettings) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_SecuredSettings(%p)"), ppSecuredSettings); + HRESULT hr = pIMsTscAx->get_SecuredSettings(ppSecuredSettings); + dbgprintf(TEXT("IMsTscAx::get_SecuredSettings -> %08X, pSecuredSettings = %p"), hr, *ppSecuredSettings); + return hr; + } + + virtual HRESULT __stdcall get_AdvancedSettings(IMsTscAdvancedSettings ** ppAdvSettings) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_AdvancedSettings(%p)"), ppAdvSettings); + HRESULT hr = pIMsTscAx->get_AdvancedSettings(ppAdvSettings); + dbgprintf(TEXT("IMsTscAx::get_AdvancedSettings -> %08X, pAdvSettings = %p"), hr, *ppAdvSettings); + + if(SUCCEEDED(hr)) + *ppAdvSettings = new CAdvancedSettings(*ppAdvSettings); + + return hr; + } + + virtual HRESULT __stdcall get_Debugger(IMsTscDebug ** ppDebugger) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::get_Debugger(%p)"), ppDebugger); + HRESULT hr = pIMsTscAx->get_Debugger(ppDebugger); + dbgprintf(TEXT("IMsTscAx::get_Debugger -> %08X, pDebugger = %p"), hr, *ppDebugger); + return hr; + } + + virtual HRESULT __stdcall Connect() + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::Connect()")); + HRESULT hr = pIMsTscAx->Connect(); + dbgprintf(TEXT("IMsTscAx::Connect -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall Disconnect() + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::Disconnect()")); + HRESULT hr = pIMsTscAx->Disconnect(); + dbgprintf(TEXT("IMsTscAx::Disconnect -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall CreateVirtualChannels(BSTR newVal) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::CreateVirtualChannels(%ls)"), newVal); + HRESULT hr = pIMsTscAx->CreateVirtualChannels(newVal); + dbgprintf(TEXT("IMsTscAx::CreateVirtualChannels -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall SendOnVirtualChannel(BSTR chanName, BSTR ChanData) + { + IMsTscAx * pIMsTscAx = getIMsTscAx(); + dbgprintf(TEXT("IMsTscAx::SendOnVirtualChannel(%ls, %p)"), chanName, ChanData); + HRESULT hr = pIMsTscAx->SendOnVirtualChannel(chanName, ChanData); + dbgprintf(TEXT("IMsTscAx::SendOnVirtualChannel -> %08X"), hr); + return hr; + } + + /* IMsRdpClient */ + public: + virtual HRESULT __stdcall put_ColorDepth(long pcolorDepth) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::put_ColorDepth(%ld)"), pcolorDepth); + HRESULT hr = pIMsRdpClient->put_ColorDepth(pcolorDepth); + dbgprintf(TEXT("IMsRdpClient::put_ColorDepth -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_ColorDepth(long * pcolorDepth) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::get_ColorDepth(%p)"), pcolorDepth); + HRESULT hr = pIMsRdpClient->get_ColorDepth(pcolorDepth); + dbgprintf(TEXT("IMsRdpClient::get_ColorDepth -> %08X, colorDepth = %ld"), hr, *pcolorDepth); + return hr; + } + + virtual HRESULT __stdcall get_AdvancedSettings2(IMsRdpClientAdvancedSettings ** ppAdvSettings) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::get_AdvancedSettings2(%p)"), ppAdvSettings); + HRESULT hr = pIMsRdpClient->get_AdvancedSettings2(ppAdvSettings); + dbgprintf(TEXT("IMsRdpClient::get_AdvancedSettings2 -> %08X, pAdvSettings = %p"), hr, *ppAdvSettings); + + if(SUCCEEDED(hr)) + *ppAdvSettings = new CAdvancedSettings(*ppAdvSettings); + + return hr; + } + + virtual HRESULT __stdcall get_SecuredSettings2(IMsRdpClientSecuredSettings ** ppSecuredSettings) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::get_SecuredSettings2(%p)"), ppSecuredSettings); + HRESULT hr = pIMsRdpClient->get_SecuredSettings2(ppSecuredSettings); + dbgprintf(TEXT("IMsRdpClient::get_SecuredSettings2 -> %08X, pSecuredSettings = %p"), hr, *ppSecuredSettings); + return hr; + } + + virtual HRESULT __stdcall get_ExtendedDisconnectReason(ExtendedDisconnectReasonCode * pExtendedDisconnectReason) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::get_ExtendedDisconnectReason(%p)"), pExtendedDisconnectReason); + HRESULT hr = pIMsRdpClient->get_ExtendedDisconnectReason(pExtendedDisconnectReason); + dbgprintf(TEXT("IMsRdpClient::get_ExtendedDisconnectReason -> %08X, ExtendedDisconnectReason = %u"), hr, *pExtendedDisconnectReason); + return hr; + } + + virtual HRESULT __stdcall put_FullScreen(VARIANT_BOOL pfFullScreen) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::put_FullScreen(%s)"), BooleanToString(pfFullScreen)); + HRESULT hr = pIMsRdpClient->put_FullScreen(pfFullScreen); + dbgprintf(TEXT("IMsRdpClient::put_FullScreen -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_FullScreen(VARIANT_BOOL * pfFullScreen) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::get_FullScreen(%p)"), pfFullScreen); + HRESULT hr = pIMsRdpClient->get_FullScreen(pfFullScreen); + dbgprintf(TEXT("IMsRdpClient::get_FullScreen -> %08X, pfFullScreen = %s"), hr, BooleanToString(*pfFullScreen)); + return hr; + } + + virtual HRESULT __stdcall SetVirtualChannelOptions(BSTR chanName, long chanOptions) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::SetVirtualChannelOptions(%ls, %08X)"), chanName, chanOptions); + HRESULT hr = pIMsRdpClient->SetVirtualChannelOptions(chanName, chanOptions); + dbgprintf(TEXT("IMsRdpClient::SetVirtualChannelOptions -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall GetVirtualChannelOptions(BSTR chanName, long * pChanOptions) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::GetVirtualChannelOptions(%ls, %p)"), chanName, pChanOptions); + HRESULT hr = pIMsRdpClient->GetVirtualChannelOptions(chanName, pChanOptions); + dbgprintf(TEXT("IMsRdpClient::GetVirtualChannelOptions -> %08X, ChanOptions = %08X"), hr, *pChanOptions); + return hr; + } + + virtual HRESULT __stdcall RequestClose(ControlCloseStatus * pCloseStatus) + { + IMsRdpClient * pIMsRdpClient = getIMsRdpClient(); + dbgprintf(TEXT("IMsRdpClient::RequestClose(%p)"), pCloseStatus); + HRESULT hr = pIMsRdpClient->RequestClose(pCloseStatus); + dbgprintf(TEXT("IMsRdpClient::RequestClose -> %08X, CloseStatus = %ld"), hr, *pCloseStatus); + return hr; + } + + /* IMsRdpClient2 */ + public: + virtual HRESULT __stdcall get_AdvancedSettings3(IMsRdpClientAdvancedSettings2 ** ppAdvSettings) + { + IMsRdpClient2 * pIMsRdpClient2 = getIMsRdpClient2(); + dbgprintf(TEXT("IMsRdpClient2::get_AdvancedSettings3(%p)"), ppAdvSettings); + HRESULT hr = pIMsRdpClient2->get_AdvancedSettings3(ppAdvSettings); + dbgprintf(TEXT("IMsRdpClient2::get_AdvancedSettings3 -> %08X, pAdvSettings = %p"), hr, *ppAdvSettings); + + if(SUCCEEDED(hr)) + *ppAdvSettings = new CAdvancedSettings(*ppAdvSettings); + + return hr; + } + + virtual HRESULT __stdcall put_ConnectedStatusText(BSTR pConnectedStatusText) + { + IMsRdpClient2 * pIMsRdpClient2 = getIMsRdpClient2(); + dbgprintf(TEXT("IMsRdpClient2::put_ConnectedStatusText(%ls)"), pConnectedStatusText); + HRESULT hr = pIMsRdpClient2->put_ConnectedStatusText(pConnectedStatusText); + dbgprintf(TEXT("IMsRdpClient2::put_ConnectedStatusText -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_ConnectedStatusText(BSTR * pConnectedStatusText) + { + IMsRdpClient2 * pIMsRdpClient2 = getIMsRdpClient2(); + dbgprintf(TEXT("IMsRdpClient2::get_ConnectedStatusText(%p)"), pConnectedStatusText); + HRESULT hr = pIMsRdpClient2->get_ConnectedStatusText(pConnectedStatusText); + dbgprintf(TEXT("IMsRdpClient2::get_ConnectedStatusText -> %08X, ConnectedStatusText = %ls"), hr, *pConnectedStatusText); + return hr; + } + + /* IMsRdpClient3 */ + public: + virtual HRESULT __stdcall get_AdvancedSettings4(IMsRdpClientAdvancedSettings3 ** ppAdvSettings) + { + IMsRdpClient3 * pIMsRdpClient3 = getIMsRdpClient3(); + dbgprintf(TEXT("IMsRdpClient3::get_AdvancedSettings4(%p)"), ppAdvSettings); + HRESULT hr = pIMsRdpClient3->get_AdvancedSettings4(ppAdvSettings); + dbgprintf(TEXT("IMsRdpClient3::get_AdvancedSettings4 -> %08X, pAdvSettings = %p"), hr, *ppAdvSettings); + + if(SUCCEEDED(hr)) + *ppAdvSettings = new CAdvancedSettings(*ppAdvSettings); + + return hr; + } + + /* IMsRdpClient4 */ + public: + virtual HRESULT __stdcall get_AdvancedSettings5(IMsRdpClientAdvancedSettings4 ** ppAdvSettings5) + { + IMsRdpClient4 * pIMsRdpClient4 = getIMsRdpClient4(); + dbgprintf(TEXT("IMsRdpClient4::get_AdvancedSettings5(%p)"), ppAdvSettings5); + HRESULT hr = pIMsRdpClient4->get_AdvancedSettings5(ppAdvSettings5); + dbgprintf(TEXT("IMsRdpClient4::get_AdvancedSettings5 -> %08X, pAdvSettings5 = %p"), hr, *ppAdvSettings5); + + if(SUCCEEDED(hr)) + *ppAdvSettings5 = new CAdvancedSettings(*ppAdvSettings5); + + return hr; + } + + /* IMsTscNonScriptable */ + public: + virtual HRESULT __stdcall put_ClearTextPassword(BSTR _arg1) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::put_ClearTextPassword(%ls)"), _arg1); + HRESULT hr = pIMsTscNonScriptable->put_ClearTextPassword(_arg1); + dbgprintf(TEXT("IMsTscNonScriptable::put_ClearTextPassword -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall put_PortablePassword(BSTR pPortablePass) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::put_PortablePassword(%ls)"), pPortablePass); + HRESULT hr = pIMsTscNonScriptable->put_PortablePassword(pPortablePass); + dbgprintf(TEXT("IMsTscNonScriptable::put_PortablePassword -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_PortablePassword(BSTR * pPortablePass) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::get_PortablePassword(%p)"), pPortablePass); + HRESULT hr = pIMsTscNonScriptable->get_PortablePassword(pPortablePass); + dbgprintf(TEXT("IMsTscNonScriptable::get_PortablePassword -> %08X, PortablePass = %ls"), hr, *pPortablePass); + return hr; + } + + virtual HRESULT __stdcall put_PortableSalt(BSTR pPortableSalt) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::put_PortableSalt(%ls)"), pPortableSalt); + HRESULT hr = pIMsTscNonScriptable->put_PortableSalt(pPortableSalt); + dbgprintf(TEXT("IMsTscNonScriptable::put_PortableSalt -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_PortableSalt(BSTR * pPortableSalt) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::get_PortableSalt()"), pPortableSalt); + HRESULT hr = pIMsTscNonScriptable->get_PortableSalt(pPortableSalt); + dbgprintf(TEXT("IMsTscNonScriptable::get_PortableSalt -> %08X, PortableSalt = %ls"), hr, *pPortableSalt); + return hr; + } + + virtual HRESULT __stdcall put_BinaryPassword(BSTR pBinaryPassword) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::put_BinaryPassword(%p)"), pBinaryPassword); + HRESULT hr = pIMsTscNonScriptable->put_BinaryPassword(pBinaryPassword); + dbgprintf(TEXT("IMsTscNonScriptable::put_BinaryPassword -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_BinaryPassword(BSTR * pBinaryPassword) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::get_BinaryPassword()"), pBinaryPassword); + HRESULT hr = pIMsTscNonScriptable->get_BinaryPassword(pBinaryPassword); + dbgprintf(TEXT("IMsTscNonScriptable::get_BinaryPassword -> %08X, BinaryPassword = %ls"), hr, *pBinaryPassword); + return hr; + } + + virtual HRESULT __stdcall put_BinarySalt(BSTR pSalt) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::put_BinarySalt(%p)"), pSalt); + HRESULT hr = pIMsTscNonScriptable->put_BinarySalt(pSalt); + dbgprintf(TEXT("IMsTscNonScriptable::put_BinarySalt -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall get_BinarySalt(BSTR * pSalt) + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::get_BinarySalt()"), pSalt); + HRESULT hr = pIMsTscNonScriptable->get_BinarySalt(pSalt); + dbgprintf(TEXT("IMsTscNonScriptable::get_BinarySalt -> %08X, pSalt = %ls"), hr, *pSalt); + return hr; + } + + virtual HRESULT __stdcall ResetPassword() + { + IMsTscNonScriptable * pIMsTscNonScriptable = getIMsTscNonScriptable(); + dbgprintf(TEXT("IMsTscNonScriptable::ResetPassword()")); + HRESULT hr = pIMsTscNonScriptable->ResetPassword(); + dbgprintf(TEXT("IMsTscNonScriptable::ResetPassword -> %08X"), hr); + return hr; + } + + + /* IMsRdpClientNonScriptable */ + public: + virtual HRESULT __stdcall IMsRdpClientNonScriptable::NotifyRedirectDeviceChange(UINT_PTR wParam, LONG_PTR lParam) + { + IMsRdpClientNonScriptable * pIMsRdpClientNonScriptable = getIMsRdpClientNonScriptable(); + dbgprintf(TEXT("IMsRdpClientNonScriptable::NotifyRedirectDeviceChange(%p, %p)"), wParam, lParam); + HRESULT hr = pIMsRdpClientNonScriptable->NotifyRedirectDeviceChange(wParam, lParam); + dbgprintf(TEXT("IMsRdpClientNonScriptable::NotifyRedirectDeviceChange -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall IMsRdpClientNonScriptable::SendKeys(long numKeys, VARIANT_BOOL * pbArrayKeyUp, long * plKeyData) // TBD + { + IMsRdpClientNonScriptable * pIMsRdpClientNonScriptable = getIMsRdpClientNonScriptable(); + dbgprintf(TEXT("IMsRdpClientNonScriptable::SendKeys(%ld, %p, %p)"), numKeys, pbArrayKeyUp, plKeyData); + HRESULT hr = pIMsRdpClientNonScriptable->SendKeys(numKeys, pbArrayKeyUp, plKeyData); + dbgprintf(TEXT("IMsRdpClientNonScriptable::SendKeys -> %08X"), hr); + return hr; + } + + /* IMsRdpClientNonScriptable2 */ + public: + virtual HRESULT __stdcall IMsRdpClientNonScriptable2::put_UIParentWindowHandle(wireHWND phwndUIParentWindowHandle) + { + IMsRdpClientNonScriptable2 * pIMsRdpClientNonScriptable2 = getIMsRdpClientNonScriptable2(); + dbgprintf(TEXT("IMsRdpClientNonScriptable2::put_UIParentWindowHandle(%p)"), phwndUIParentWindowHandle); + HRESULT hr = pIMsRdpClientNonScriptable2->put_UIParentWindowHandle(phwndUIParentWindowHandle); + dbgprintf(TEXT("IMsRdpClientNonScriptable2::put_UIParentWindowHandle -> %08X"), hr); + return hr; + } + + virtual HRESULT __stdcall IMsRdpClientNonScriptable2::get_UIParentWindowHandle(wireHWND * phwndUIParentWindowHandle) + { + IMsRdpClientNonScriptable2 * pIMsRdpClientNonScriptable2 = getIMsRdpClientNonScriptable2(); + dbgprintf(TEXT("IMsRdpClientNonScriptable2::get_UIParentWindowHandle(%p)"), phwndUIParentWindowHandle); + HRESULT hr = pIMsRdpClientNonScriptable2->get_UIParentWindowHandle(phwndUIParentWindowHandle); + dbgprintf(TEXT("IMsRdpClientNonScriptable2::get_UIParentWindowHandle -> %08X, hwndUIParentWindowHandle = %p"), hr, *phwndUIParentWindowHandle); + return hr; + } + + /* + { + * p = m_; + dbgprintf(TEXT("::()"), ); + HRESULT hr = p->(); + dbgprintf(TEXT(":: -> %08X, "), hr, ); + return hr; + } + */ + }; + + class ClassFactory: public IClassFactory2 + { + private: + LONG m_refCount; + IUnknown * m_IUnknown; + IClassFactory * m_IClassFactory; + IClassFactory2 * m_IClassFactory2; + + IClassFactory * getIClassFactory() + { + if(m_IClassFactory) + return m_IClassFactory; + + if(m_IClassFactory2) + m_IClassFactory = m_IClassFactory2; + + if(m_IClassFactory) + { + m_IClassFactory->AddRef(); + return m_IClassFactory; + } + + m_IUnknown->QueryInterface(&m_IClassFactory); + return m_IClassFactory; + } + + IClassFactory2 * getIClassFactory2() + { + if(m_IClassFactory2) + return m_IClassFactory2; + + m_IUnknown->QueryInterface(&m_IClassFactory2); + return m_IClassFactory2; + } + + public: + ClassFactory(IUnknown * pUnknwn): + m_refCount(1), + m_IUnknown(pUnknwn), + m_IClassFactory(NULL), + m_IClassFactory2(NULL) + { + m_IUnknown->AddRef(); + } + + ~ClassFactory() + { + if(m_IUnknown) + m_IUnknown->Release(); + + if(m_IClassFactory) + m_IClassFactory->Release(); + + if(m_IClassFactory2) + m_IClassFactory2->Release(); + } + + /* IUnknown */ + public: + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) + { + HRESULT hr; + IUnknown * pvObject = NULL; + + dbgprintf(TEXT("IUnknown::QueryInterface(%ls, %p)"), UUIDToString(riid).c_str(), ppvObject); + +#define QIBEGIN() \ + if(riid == IID_IUnknown) \ + { \ + hr = S_OK; \ + pvObject = (IUnknown *)(this); \ + } + +#define QI(I) \ + else if(riid == IID_ ## I) \ + { \ + if(m_ ## I) \ + { \ + m_ ## I->AddRef(); \ + hr = S_OK; \ + } \ + else \ + { \ + hr = m_IUnknown->QueryInterface(&m_ ## I); \ + } \ + \ + if(SUCCEEDED(hr)) \ + pvObject = static_cast(this); \ + } + +#define QIEND() \ + else \ + { \ + hr = E_NOINTERFACE; \ + pvObject = NULL; \ + } + + QIBEGIN() + QI(IClassFactory) + QI(IClassFactory2) + QIEND() + +#undef QIBEGIN +#undef QIEND +#undef QI + + if(SUCCEEDED(hr)) + { + assert(pvObject); + pvObject->AddRef(); + } + else + { + assert(pvObject == NULL); + } + + *ppvObject = pvObject; + + dbgprintf(TEXT("IUnknown::QueryInterface -> %08X, ppvObject = %p"), hr, *ppvObject); + return hr; + } + + virtual ULONG STDMETHODCALLTYPE AddRef(void) + { + return InterlockedIncrement(&m_refCount); + } + + virtual ULONG STDMETHODCALLTYPE Release(void) + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + /* IClassFactory */ + public: + virtual HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown * pUnkOuter, REFIID riid, void ** ppvObject) + { + IClassFactory * pIClassFactory = getIClassFactory(); + dbgprintf(TEXT("IClassFactory::CreateInstance(%p, %ls, %p)"), pUnkOuter, UUIDToString(riid).c_str(), ppvObject); + HRESULT hr = pIClassFactory->CreateInstance(NULL, riid, ppvObject); + dbgprintf(TEXT("IClassFactory::CreateInstance -> %08X, pvObject = %p"), hr, *ppvObject); + return CoClass::CreateInstance((IUnknown *)*ppvObject, pUnkOuter, riid, ppvObject); + } + + virtual HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) + { + IClassFactory * pIClassFactory = getIClassFactory(); + dbgprintf(TEXT("IClassFactory::LockServer(%s)"), BooleanToString(fLock)); + HRESULT hr = pIClassFactory->LockServer(fLock); + dbgprintf(TEXT("IClassFactory::LockServer -> %08X"), hr); + return hr; + } + + /* IClassFactory2 */ + public: + virtual HRESULT STDMETHODCALLTYPE GetLicInfo(LICINFO * pLicInfo) + { + IClassFactory2 * pIClassFactory2 = getIClassFactory2(); + dbgprintf(TEXT("IClassFactory2::GetLicInfo(%p)"), pLicInfo); + HRESULT hr = pIClassFactory2->GetLicInfo(pLicInfo); + dbgprintf(TEXT("IClassFactory2::GetLicInfo -> %08X, LicInfo = %p"), hr, pLicInfo); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE RequestLicKey(DWORD dwReserved, BSTR * pBstrKey) + { + IClassFactory2 * pIClassFactory2 = getIClassFactory2(); + dbgprintf(TEXT("IClassFactory2::RequestLicKey(%lu, %p)"), dwReserved, pBstrKey); + HRESULT hr = pIClassFactory2->RequestLicKey(dwReserved, pBstrKey); + dbgprintf(TEXT("IClassFactory2::RequestLicKey -> %08X, bstrKey = %ls"), hr, *pBstrKey); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE CreateInstanceLic(IUnknown * pUnkOuter, IUnknown * pUnkReserved, REFIID riid, BSTR bstrKey, PVOID * ppvObj) + { + IClassFactory2 * pIClassFactory2 = getIClassFactory2(); + dbgprintf(TEXT("IClassFactory2::CreateInstanceLic(%p, %p, %ls, %ls, %p)"), pUnkOuter, pUnkReserved, UUIDToString(riid).c_str(), bstrKey, ppvObj); + HRESULT hr = pIClassFactory2->CreateInstanceLic(NULL, pUnkReserved, riid, bstrKey, ppvObj); + dbgprintf(TEXT("IClassFactory2::CreateInstanceLic -> %08X, pvObj = %p"), hr, *ppvObj); + return CoClass::CreateInstance((IUnknown *)*ppvObj, pUnkOuter, riid, ppvObj); + } + }; + + STDAPI DllGetClassObject(IN REFCLSID rclsid, IN REFIID riid, OUT LPVOID * ppv) + { + init(); + + dbgprintf(TEXT("DllGetClassObject(%ls, %ls, %p)"), UUIDToString(rclsid).c_str(), UUIDToString(riid).c_str(), ppv); + HRESULT hr = pfnDllGetClassObject(rclsid, IID_IUnknown, ppv); + dbgprintf(TEXT("DllGetClassObject -> %08X, pv = %p"), hr, *ppv); + + IUnknown * pv = NULL; + + if(SUCCEEDED(hr)) + { + IUnknown * punk = (IUnknown *)*ppv; + + if(rclsid == CLSID_MsTscAx || rclsid == CLSID_MsRdpClient || rclsid == CLSID_MsRdpClient2 || rclsid == CLSID_MsRdpClient3 || rclsid == CLSID_MsRdpClient4) + pv = new ClassFactory(punk); + else + hr = CLASS_E_CLASSNOTAVAILABLE; + + punk->Release(); + } + + if(pv) + { + hr = pv->QueryInterface(riid, ppv); + + if(FAILED(hr)) + pv->Release(); + } + + return hr; + } + + STDAPI DllCanUnloadNow(void) + { + init(); + + dbgprintf(TEXT("DllCanUnloadNow()")); + HRESULT hr = pfnDllCanUnloadNow(); + dbgprintf(TEXT("DllCanUnloadNow -> %08X"), hr); + + return hr; + } + + STDAPI_(ULONG) DllGetTscCtlVer(void) + { + init(); + + dbgprintf(TEXT("DllGetTscCtlVer()")); + ULONG ul = pfnDllGetTscCtlVer(); + dbgprintf(TEXT("DllGetTscCtlVer-> %08X"), ul); + + return ul; + } +} + +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.def b/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.def new file mode 100644 index 00000000000..5da85892a99 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.def @@ -0,0 +1,14 @@ +LIBRARY mstscax.dll + +EXPORTS + ; OLE inproc server + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + + ; OLE self-registration + ; TODO + + ; Private APIs + DllGetTscCtlVer + +; EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.sln b/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.sln new file mode 100644 index 00000000000..2abaf3db1b1 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C++ Express 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mstscax", "mstscax.vcproj", "{933B2293-F12F-4B01-98B4-BF635B8B4F36}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {933B2293-F12F-4B01-98B4-BF635B8B4F36}.Debug|Win32.ActiveCfg = Debug|Win32 + {933B2293-F12F-4B01-98B4-BF635B8B4F36}.Debug|Win32.Build.0 = Debug|Win32 + {933B2293-F12F-4B01-98B4-BF635B8B4F36}.Release|Win32.ActiveCfg = Release|Win32 + {933B2293-F12F-4B01-98B4-BF635B8B4F36}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.vcproj b/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.vcproj new file mode 100644 index 00000000000..7e3def8edf7 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/mstscax/mstscax.vcproj @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/applications/net/tsclient/porting-tools/mstscax/stdafx.cpp b/rosapps/applications/net/tsclient/porting-tools/mstscax/stdafx.cpp new file mode 100644 index 00000000000..fd4f341c7b2 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/mstscax/stdafx.cpp @@ -0,0 +1 @@ +#include "stdafx.h" diff --git a/rosapps/applications/net/tsclient/porting-tools/mstscax/stdafx.h b/rosapps/applications/net/tsclient/porting-tools/mstscax/stdafx.h new file mode 100644 index 00000000000..9c317402891 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/mstscax/stdafx.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN +#define STRICT +#define NOMINMAX + +#include +#include +#include + +#include + +#include + +#import "./rdesktop-core-tester.tlb" \ + exclude("LONG_PTR", "UINT_PTR", "wireHWND", "_RemotableHandle", "__MIDL_IWinTypes_0009") \ + named_guids \ + no_implementation \ + no_smart_pointers \ + raw_dispinterfaces \ + raw_interfaces_only \ + raw_native_types + +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/activex.cpp b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/activex.cpp new file mode 100644 index 00000000000..80a03b6a379 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/activex.cpp @@ -0,0 +1,6095 @@ +#include "stdafx.h" + +namespace MSTSCLib +{ +#include "mstsclib_h.h" +}; + +namespace MSTSCLib_Redist +{ +// extremely ew, but actually the cleanest way to import the alternate UUIDs +#include "mstsclib_redist_i.c" +}; + +#include "rdesktop/rdesktop.h" +#include "rdesktop/proto.h" + +namespace +{ +#ifdef _MSC_VER +extern "C" char __ImageBase; +#endif + +HMODULE GetCurrentModule() +{ + return reinterpret_cast(&__ImageBase); +} + +} + +namespace +{ + +LONG g_moduleRefCount = 0; + +void lockServer() +{ + InterlockedIncrement(&g_moduleRefCount); +} + +void unlockServer() +{ + InterlockedDecrement(&g_moduleRefCount); +} + +bool canUnloadServer() +{ + return g_moduleRefCount == 0; +} + +} + +namespace +{ + +void FreeLpsz(LPSTR lpsz) +{ + if(lpsz) + delete[] lpsz; +} + +LPSTR AllocLpsz(const CHAR * lpsz, size_t cb) +{ + LPSTR lpszNew = new CHAR[cb + 1]; + + if(lpszNew == NULL) + return NULL; + + CopyMemory(lpszNew, lpsz, cb); + lpszNew[cb] = 0; + + return lpszNew; +} + +LPSTR AllocLpsz(const WCHAR * lpwsz, int cchIn) +{ + int cch = WideCharToMultiByte(CP_ACP, 0, lpwsz, cchIn, NULL, 0, NULL, NULL); + + if(cch <= 0) + return NULL; + + LPSTR lpsz = new CHAR[cch]; + + if(lpsz == NULL) + return NULL; + + cch = WideCharToMultiByte(CP_ACP, 0, lpwsz, cchIn, lpsz, cch, NULL, NULL); + + if(cch <= 0) + { + FreeLpsz(lpsz); + return NULL; + } + + return lpsz; +} + +LPSTR BstrToLpsz(BSTR bstr) +{ + return AllocLpsz(bstr, SysStringLen(bstr)); +} + +BSTR LpszToBstr(LPSTR lpsz) +{ + int cch = MultiByteToWideChar(CP_ACP, 0, lpsz, -1, NULL, 0); + + if(cch <= 0) + return NULL; + + BSTR bstr = SysAllocStringLen(NULL, cch); + + if(bstr == NULL) + return NULL; + + cch = MultiByteToWideChar(CP_ACP, 0, lpsz, -1, bstr, cch); + + if(cch <= 0) + { + SysFreeString(bstr); + return NULL; + } + + return bstr; +} + +} + +namespace +{ + +template T aligndown(const T& X, const U& align) +{ + return X & ~(T(align) - 1); +} + +template T alignup(const T& X, const U& align) +{ + return aligndown(X + (align - 1), align); +} + +/* Convert between bitmap formats */ +uint8 * win32_convert_scanlines(int width, int height, int bitcount, int fromalign, int toalign, const uint8 * data, uint8 ** buffer) +{ + // TBD: profile & optimize the most common cases + assert(width > 0); + assert(height); + assert(bitcount && bitcount <= 32); + assert(fromalign <= toalign); + assert(data); + assert(buffer); + + bool flipped = height < 0; + + if(flipped) + height = - height; + + int bytesperrow = alignup(width * bitcount, 8) / 8; + int fromstride = alignup(bytesperrow, fromalign); + int tostride = alignup(bytesperrow, toalign); + assert(fromstride <= tostride); + + int datasize = tostride * height; + + uint8 * dibits = new uint8[datasize]; + + const uint8 * src = data; + uint8 * dest = dibits; + + const int pad = tostride - fromstride; + + assert(pad < 4); + __assume(pad < 4); + + if(flipped) + { + dest += (height - 1) * tostride; + tostride = - tostride; + } + + for(int i = 0; i < height; ++ i) + { + memcpy(dest, src, fromstride); + memset(dest + fromstride, 0, pad); + src += fromstride; + dest += tostride; + } + + *buffer = dibits; + return dibits; +} + +/* Creates bitmaps */ +HBITMAP win32_create_dib(LONG width, LONG height, WORD bitcount, const BYTE * data) +{ + struct b_ + { + BITMAPINFO bmi; + RGBQUAD colormap[256 - ARRAYSIZE(RTL_FIELD_TYPE(BITMAPINFO, bmiColors))]; + } + b; + + b.bmi.bmiHeader.biSize = sizeof(b.bmi.bmiHeader); + b.bmi.bmiHeader.biWidth = width; + b.bmi.bmiHeader.biHeight = height; + b.bmi.bmiHeader.biPlanes = 1; + b.bmi.bmiHeader.biBitCount = bitcount; + b.bmi.bmiHeader.biCompression = BI_RGB; + b.bmi.bmiHeader.biSizeImage = 0; + b.bmi.bmiHeader.biXPelsPerMeter = 0; + b.bmi.bmiHeader.biYPelsPerMeter = 0; + + if(bitcount > 8) + { + b.bmi.bmiHeader.biClrUsed = 0; + b.bmi.bmiHeader.biClrImportant = 0; + } + else + { + b.bmi.bmiHeader.biClrUsed = 2 << bitcount; + b.bmi.bmiHeader.biClrImportant = 2 << bitcount; + + // TODO: palette + } + + // FIXME: beyond ugly + HDC hdc = CreateCompatibleDC(NULL); + + if(hdc == NULL) + return NULL; + + HBITMAP hbm = CreateDIBitmap(hdc, &b.bmi.bmiHeader, CBM_INIT, data, &b.bmi, DIB_RGB_COLORS); + + if(hbm == NULL) + error("CreateDIBitmap %dx%dx%d failed\n", width, height, bitcount); + + DeleteDC(hdc); + return hbm; +} + +/* Creates brushes */ +HBRUSH win32_create_brush(BRUSH * brush, COLORREF fgcolour) +{ + if(brush == NULL) + return (HBRUSH)GetStockObject(NULL_BRUSH); + + switch(brush->style) + { + case BS_SOLID: + case BS_NULL: + case BS_HATCHED: + case BS_PATTERN: + case BS_PATTERN8X8: + break; + + default: + return NULL; + } + + switch(brush->style) + { + case BS_SOLID: + return CreateSolidBrush(fgcolour); + + case BS_HATCHED: + return CreateHatchBrush(brush->pattern[0], fgcolour); + + case BS_NULL: + return (HBRUSH)GetStockObject(NULL_BRUSH); + + case BS_PATTERN: + case BS_PATTERN8X8: + { + uint16 pattern[8]; + + for(size_t i = 0; i < 8; ++ i) + pattern[i] = brush->pattern[i]; + + HBITMAP hpattern = CreateBitmap(8, 8, 1, 1, pattern); + HBRUSH hbr = CreatePatternBrush(hpattern); + DeleteObject(hpattern); + return hbr; + } + + DEFAULT_UNREACHABLE; + } +} +}; + +/* + "sealed" can improve optimizations by asserting a class cannot be derived + from, optimizing out accesses to the v-table from inside the class +*/ +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#define SEALED_ sealed +#else +#define SEALED_ +#endif + + +/* Class that implements the RDP client GUI */ +class RdpClientUI +{ +public: + // TODO: pass the client settings relevant to the GUI here + HRESULT Initialize(HWND hwndParent) + { + // TODO: create the various windows + // TODO: create display window thread + // TODO: create input thread + return E_FAIL; + } + +public: + static BOOL Startup() + { + WNDCLASSEX wcexUI = { sizeof(wcexUI) }; + WNDCLASSEX wcexConsole = { sizeof(wcexConsole) }; + WNDCLASSEX wcexDisplay = { sizeof(wcexDisplay) }; + WNDCLASSEX wcexInput = { sizeof(wcexInput) }; + + HBRUSH nullBrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH); + + wcexUI.lpfnWndProc = NULL; // TODO + wcexUI.hInstance = GetCurrentModule(); + wcexUI.hCursor = LoadCursor(NULL, IDC_ARROW); + wcexUI.hbrBackground = nullBrush; + wcexUI.lpszClassName = TEXT("MissTosca_UI"); + + wcexConsole.style = CS_VREDRAW | CS_HREDRAW; + wcexConsole.lpfnWndProc = NULL; // TODO + wcexConsole.hInstance = GetCurrentModule(); + wcexConsole.hCursor = LoadCursor(NULL, IDC_ARROW); + wcexConsole.hbrBackground = nullBrush; + wcexConsole.lpszClassName = TEXT("MissTosca_Console"); + + wcexDisplay.style = CS_VREDRAW | CS_HREDRAW; + wcexDisplay.lpfnWndProc = NULL; // TODO + wcexDisplay.hInstance = GetCurrentModule(); + wcexDisplay.hCursor = LoadCursor(NULL, IDC_ARROW); + wcexDisplay.hbrBackground = nullBrush; + wcexDisplay.lpszClassName = TEXT("MissTosca_Display"); + + wcexInput.style = CS_VREDRAW | CS_HREDRAW; + wcexInput.lpfnWndProc = NULL; // TODO + wcexInput.hInstance = GetCurrentModule(); + wcexInput.hCursor = NULL; + wcexInput.hbrBackground = nullBrush; + wcexInput.lpszClassName = TEXT("MissTosca_Input"); + + return + RegisterClassEx(&wcexUI) && + RegisterClassEx(&wcexConsole) && + RegisterClassEx(&wcexDisplay) && + RegisterClassEx(&wcexInput); + } + + static void Shutdown() + { + // TODO + } + + /* + This is the main UI window. It's the direct child of the control + window, it fills its whole extent and it contains the scrollbars. + When activated, it will move keyboard focus to the input window + */ +private: + HWND m_uiWindow; + LONG m_scrollHPos; + LONG m_scrollVPos; + + LRESULT UIWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch(uMsg) + { + // Keep the keyboard focus on the input window + case WM_ACTIVATE: + switch(LOWORD(wParam)) + { + case WA_INACTIVE: + break; + + case WA_ACTIVE: + case WA_CLICKACTIVE: + if(!HIWORD(wParam)) + SetFocus(m_inputWindow); + } + + return 0; + + // Resized: rearrange children windows, adjust scrollbars + case WM_SIZE: + { + if(IsIconic(m_uiWindow)) + break; + + RECT rcClient; + GetWindowRect(m_uiWindow, &rcClient); + + if(m_smartSizing) + { + // we are not supposed to maintain aspect ratio. Container has to do that + m_consoleX = 0; + m_consoleY = 0; + m_consoleWidth = rcClient.right; + m_consoleHeight = rcClient.bottom; + } + else + { + // center horizontally, no horizontal scrollbar + if(rcClient.right >= m_consoleWidth) + m_consoleX = (m_consoleWidth - rcClient.right) / 2; + + // center vertically, no vertical scrollbar + if(rcClient.bottom >= m_consoleHeight) + m_consoleY = (m_consoleHeight - rcClient.right) / 2; + } + + SCROLLINFO scroll = { sizeof(scroll), SIF_ALL, 0 }; + + // update the horizontal scrollbar + scroll.nMax = m_consoleWidth; + scroll.nPage = rcClient.right; + scroll.nPos = 0 - m_consoleX; + SetScrollInfo(m_uiWindow, SB_HORZ, &scroll, TRUE); + + // update the vertical scrollbar + scroll.nMax = m_consoleHeight; + scroll.nPage = rcClient.bottom; + scroll.nPos = 0 - m_consoleY; + SetScrollInfo(m_uiWindow, SB_VERT, &scroll, TRUE); + + // move/resize the console window + MoveWindow(m_consoleWindow, m_consoleX, m_consoleY, m_consoleWidth, m_consoleHeight, TRUE); + } + + return 0; + + case WM_HSCROLL: + { + SCROLLINFO scroll = { sizeof(scroll), SIF_TRACKPOS }; + GetScrollInfo(m_uiWindow, SB_HORZ, &scroll); + m_consoleX = - scroll.nTrackPos; + MoveWindow(m_consoleWindow, m_consoleX, m_consoleY, m_consoleWidth, m_consoleHeight, TRUE); + } + + return 0; + + case WM_VSCROLL: + { + SCROLLINFO scroll = { sizeof(scroll), SIF_TRACKPOS }; + GetScrollInfo(m_uiWindow, SB_VERT, &scroll); + m_consoleY = - scroll.nTrackPos; + MoveWindow(m_consoleWindow, m_consoleX, m_consoleY, m_consoleWidth, m_consoleHeight, TRUE); + } + + return 0; + + default: + break; + } + + return DefWindowProc(m_uiWindow, uMsg, wParam, lParam); + } + + /* + This is the full-screen title bar. It's displayed at the top of the + main UI window while in full-screen mode, and it contains two toolbars + with the pin, minimize, restore and close buttons + */ + HWND m_fullScreenBarWindow; + + /* + This is the console window. It has the same extent as the display on + the remote computer, or it fills the UI window in smart resizing mode, + and it contains the input and display windows + */ +private: + HWND m_consoleWindow; + LONG m_consoleX; + LONG m_consoleY; + LONG m_consoleWidth; + LONG m_consoleHeight; + bool m_smartSizing; + + LRESULT ConsoleWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch(uMsg) + { + case WM_SIZE: + { + RECT rcClient; + GetClientRect(m_consoleWindow, &rcClient); + + MoveWindow(m_inputWindow, 0, 0, rcClient.right, rcClient.bottom, TRUE); + MoveWindow(m_displayWindow, 0, 0, rcClient.right, rcClient.bottom, TRUE); + } + + return 0; + + default: + break; + } + + return DefWindowProc(m_consoleWindow, uMsg, wParam, lParam); + } + + /* + This is the display window. It represents the virtual display of the + remote computer. It completely fills its parent, the console window, + and it runs in its own thread for performance reasons + */ +private: + HWND m_displayWindow; + LONG m_displayBufferWidth; + LONG m_displayBufferHeight; + HDC m_displayBuffer; + void * m_displayBufferRaw; + int m_displayBufferSave; + int m_displayBufferBitDepth; + int m_displayBufferByteDepth; + int m_displayBufferStride; + RECT m_displayBufferClip; + CRITICAL_SECTION m_displayBufferMutex; + + LRESULT DisplayWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch(uMsg) + { + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + case WM_PRINTCLIENT: + if(wParam == 0) + break; + + case WM_PAINT: + { + HDC hdc = (HDC)wParam; + + EnterCriticalSection(&m_displayBufferMutex); + + if(hdc) + { + RECT rc; + GetClientRect(m_displayWindow, &rc); + BitBlt(hdc, 0, 0, rc.right, rc.bottom, m_displayBuffer, 0, 0, SRCCOPY); + } + else + { + PAINTSTRUCT ps; + hdc = BeginPaint(m_displayWindow, &ps); + + if(!m_smartSizing) + { + BitBlt + ( + hdc, + ps.rcPaint.left, + ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, + ps.rcPaint.bottom - ps.rcPaint.top, + m_displayBuffer, + ps.rcPaint.left, + ps.rcPaint.top, + SRCCOPY + ); + } + else + { + // bleh. There has to be a better way + SetStretchBltMode(hdc, HALFTONE); + + StretchBlt + ( + hdc, + 0, + 0, + m_consoleWidth, + m_consoleHeight, + m_displayBuffer, + 0, + 0, + m_displayBufferWidth, + m_displayBufferHeight, + SRCCOPY + ); + } + + EndPaint(m_displayWindow, &ps); + } + + LeaveCriticalSection(&m_displayBufferMutex); + } + + return 0; + + default: + break; + } + + return DefWindowProc(m_displayWindow, uMsg, wParam, lParam); + } + + /* Screen repainting */ + void Display_RepaintRect(const RECT * lprc) + { + if(m_smartSizing) + return Display_RepaintAll(); + + RECT rcDamage; + IntersectRect(&rcDamage, lprc, &m_displayBufferClip); + InvalidateRect(m_displayWindow, &rcDamage, FALSE); + } + + void Display_RepaintArea(int x, int y, int cx, int cy) + { + if(m_smartSizing) + return Display_RepaintAll(); + + RECT rcDamage; + rcDamage.left = x; + rcDamage.top = y; + rcDamage.right = x + cx; + rcDamage.bottom = y + cy; + Display_RepaintRect(&rcDamage); + } + + void Display_RepaintPolygon(POINT * point, int npoints, int linewidth) + { + if(m_smartSizing) + return Display_RepaintAll(); + + RECT rcDamage; + + rcDamage.left = MAXLONG; + rcDamage.top = MAXLONG; + rcDamage.right = 0; + rcDamage.bottom = 0; + + for(int i = 0; i < npoints; ++ i) + { + if(point[i].x < rcDamage.left) + rcDamage.left = point[i].x; + + if(point[i].y < rcDamage.top) + rcDamage.top = point[i].y; + + if(point[i].x > rcDamage.right) + rcDamage.right = point[i].x; + + if(point[i].y > rcDamage.bottom) + rcDamage.bottom = point[i].y; + } + + InflateRect(&rcDamage, linewidth, linewidth); + Display_RepaintRect(&rcDamage); + } + + void Display_RepaintAll() + { + InvalidateRgn(m_displayWindow, NULL, FALSE); + } + +public: + void Display_SetClip(int x, int y, int cx, int cy) + { + m_displayBufferClip.left = x; + m_displayBufferClip.top = y; + m_displayBufferClip.right = x + cx + 1; + m_displayBufferClip.bottom = y + cy + 1; + + HRGN hrgn = CreateRectRgnIndirect(&m_displayBufferClip); + SelectClipRgn(m_displayBuffer, hrgn); + DeleteObject(hrgn); + } + + void Display_ResetClip() + { + m_displayBufferClip.left = 0; + m_displayBufferClip.top = 0; + m_displayBufferClip.right = m_displayBufferWidth; + m_displayBufferClip.bottom = m_displayBufferHeight; + SelectClipRgn(m_displayBuffer, NULL); + } + + void Display_PaintBitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data) + { + GdiFlush(); + + int fromstride = alignup(width * m_displayBufferByteDepth, 4); + int sizex = cx * m_displayBufferByteDepth; + + const uint8 * src = data; + + uint8 * dst = + (uint8 *)m_displayBufferRaw + + (m_displayBufferHeight - y - cy) * m_displayBufferStride + + x * m_displayBufferByteDepth; + + for(int i = 0; i < cy; ++ i) + { + memcpy(dst, src, sizex); + src += fromstride; + dst += m_displayBufferStride; + } + + Display_RepaintArea(x, y, cx, cy); + } + + void Display_DestBlt(uint8 opcode, int x, int y, int cx, int cy) + { + int dcsave = SaveDC(m_displayBuffer); + SelectObject(m_displayBuffer, GetStockObject(BLACK_BRUSH)); + PatBlt(m_displayBuffer, x, y, cx, cy, MAKELONG(0, opcode)); + RestoreDC(m_displayBuffer, dcsave); + Display_RepaintArea(x, y, cx, cy); + } + + void Display_PatBlt(uint8 opcode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour, int fgcolour) + { + HBRUSH hbr = win32_create_brush(brush, fgcolour); + + int dcsave = SaveDC(m_displayBuffer); + + SetBkColor(m_displayBuffer, bgcolour); + SetTextColor(m_displayBuffer, fgcolour); + SetBrushOrgEx(m_displayBuffer, brush->xorigin, brush->yorigin, NULL); + SelectObject(m_displayBuffer, hbr); + + PatBlt(m_displayBuffer, x, y, cx, cy, MAKELONG(0, opcode)); + + RestoreDC(m_displayBuffer, dcsave); + + DeleteObject(hbr); + + Display_RepaintArea(x, y, cx, cy); + } + + void Display_ScreenBlt(uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy) + { + BitBlt(m_displayBuffer, x, y, cx, cy, m_displayBuffer, srcx, srcy, MAKELONG(0, opcode)); + Display_RepaintArea(x, y, cx, cy); + } + + void Display_MemBlt(uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy) + { + HDC hdcSrc = CreateCompatibleDC(m_displayBuffer); + HGDIOBJ hOld = SelectObject(hdcSrc, src); + + BitBlt(m_displayBuffer, x, y, cx, cy, hdcSrc, srcx, srcy, MAKELONG(0, opcode)); + + SelectObject(hdcSrc, hOld); + DeleteDC(hdcSrc); + + Display_RepaintArea(x, y, cx, cy); + } + + void Display_TriBlt(uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy, BRUSH * brush, int bgcolour, int fgcolour) + { + // TODO + HDC hdcSrc = CreateCompatibleDC(m_displayBuffer); + HGDIOBJ hOld = SelectObject(hdcSrc, src); + + //SELECT_BRUSH(brush, bgcolour, fgcolour); + + BitBlt(m_displayBuffer, x, y, cx, cy, hdcSrc, srcx, srcy, MAKELONG(0, opcode)); + + //RESET_BRUSH(); + + SelectObject(hdcSrc, hOld); + DeleteDC(hdcSrc); + + Display_RepaintArea(x, y, cx, cy); + } + + void Display_Line(uint8 opcode, int startx, int starty, int endx, int endy, PEN * pen) + { + HPEN hpen = CreatePen(pen->style, pen->width, pen->colour); + + int dcsave = SaveDC(m_displayBuffer); + + SetROP2(m_displayBuffer, opcode); + SelectObject(m_displayBuffer, hpen); + MoveToEx(m_displayBuffer, startx, starty, NULL); + + LineTo(m_displayBuffer, endx, endy); + + RestoreDC(m_displayBuffer, dcsave); + + DeleteObject(hpen); + + RECT rcDamage; + + if(startx < endx) + { + rcDamage.left = startx; + rcDamage.right = endx; + } + else + { + rcDamage.left = endx; + rcDamage.right = startx; + } + + if(starty < endy) + { + rcDamage.top = starty; + rcDamage.bottom = endy; + } + else + { + rcDamage.top = endy; + rcDamage.bottom = starty; + } + + InflateRect(&rcDamage, pen->width, pen->width); + Display_RepaintRect(&rcDamage); + } + + void Display_Rect(int x, int y, int cx, int cy, int colour) + { + HBRUSH hbr = CreateSolidBrush(colour); + + int dcsave = SaveDC(m_displayBuffer); + + SelectObject(m_displayBuffer, hbr); + SelectObject(m_displayBuffer, GetStockObject(NULL_PEN)); + + Rectangle(m_displayBuffer, x, y, x + cx + 1, y + cy + 1); + + RestoreDC(m_displayBuffer, dcsave); + + DeleteObject(hbr); + + Display_RepaintArea(x, y, cx, cy); + } + + void Display_Polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints, BRUSH * brush, int bgcolour, int fgcolour) + { + HBRUSH hbr = win32_create_brush(brush, fgcolour); + + int dcsave = SaveDC(m_displayBuffer); + + SetBkColor(m_displayBuffer, bgcolour); + SetTextColor(m_displayBuffer, fgcolour); + SetPolyFillMode(m_displayBuffer, fillmode); + SelectObject(m_displayBuffer, hbr); + + Polygon(m_displayBuffer, point, npoints); + + RestoreDC(m_displayBuffer, dcsave); + + Display_RepaintPolygon(point, npoints, 0); + } + + void Display_Polyline(uint8 opcode, POINT * points, int npoints, PEN * pen) + { + POINT last = points[0]; + + for(int i = 1; i < npoints; ++ i) + { + points[i].x += last.x; + points[i].y += last.y; + last = points[i]; + } + + HPEN hpen = CreatePen(pen->style, pen->width, pen->colour); + + int dcsave = SaveDC(m_displayBuffer); + + SetROP2(m_displayBuffer, opcode); + SelectObject(m_displayBuffer, hpen); + + Polyline(m_displayBuffer, points, npoints); + + RestoreDC(m_displayBuffer, dcsave); + + DeleteObject(hpen); + + Display_RepaintPolygon(points, npoints, pen->width); + } + + void Display_Ellypse(uint8 opcode, uint8 fillmode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour, int fgcolour) + { + // TODO + + Display_RepaintArea(x, y, cx, cy); + } + + // TBD: optimize text drawing + void Display_DrawGlyph(int mixmode, int x, int y, int cx, int cy, HGLYPH glyph, int srcx, int srcy, int bgcolour, int fgcolour) + { + HBITMAP hbmGlyph = (HBITMAP)glyph; + HDC hdcGlyph = CreateCompatibleDC(m_displayBuffer); + HGDIOBJ hOld = SelectObject(hdcGlyph, hbmGlyph); + + int dcsave = SaveDC(m_displayBuffer); + + switch(mixmode) + { + case MIX_TRANSPARENT: + { + /* + ROP is DSPDxax: + - where the glyph (S) is white, D is set to the foreground color (P) + - where the glyph (S) is black, D is left untouched + + This paints a transparent glyph in the specified color + */ + HBRUSH hbr = CreateSolidBrush(fgcolour); + SelectObject(m_displayBuffer, hbr); + BitBlt(m_displayBuffer, x, y, cx, cy, hdcGlyph, srcx, srcy, MAKELONG(0, 0xe2)); + DeleteObject(hbr); + } + + break; + + case MIX_OPAQUE: + { + /* Curiously, glyphs are inverted (white-on-black) */ + SetBkColor(m_displayBuffer, fgcolour); + SetTextColor(m_displayBuffer, bgcolour); + BitBlt(m_displayBuffer, x, y, cx, cy, hdcGlyph, srcx, srcy, SRCCOPY); + } + + break; + } + + RestoreDC(m_displayBuffer, dcsave); + + SelectObject(hdcGlyph, hOld); + DeleteDC(hdcGlyph); + + Display_RepaintArea(x, y, cx, cy); + } + + void Display_DoGlyph(uint8 font, uint8 flags, int mixmode, int& x, int& y, int bgcolour, int fgcolour, const uint8 * ttext, int& idx) + { + FONTGLYPH * glyph; + + glyph = cache_get_font(/*This*/NULL, font, ttext[idx]); + + if(!(flags & TEXT2_IMPLICIT_X)) + { + int xyoffset = ttext[++ idx]; + + if((xyoffset & 0x80)) + { + if (flags & TEXT2_VERTICAL) + y += ttext[idx + 1] | (ttext[idx + 2] << 8); + else + x += ttext[idx + 1] | (ttext[idx + 2] << 8); + + idx += 2; + } + else + { + if (flags & TEXT2_VERTICAL) + y += xyoffset; + else + x += xyoffset; + } + } + + if(glyph) + { + Display_DrawGlyph + ( + mixmode, + x + (short)glyph->offset, + y + (short)glyph->baseline, + glyph->width, + glyph->height, + glyph->pixmap, + 0, + 0, + bgcolour, + fgcolour + ); + + if(flags & TEXT2_IMPLICIT_X) + x += glyph->width; + } + } + + void Display_DrawText + ( + uint8 font, + uint8 flags, + uint8 opcode, + int mixmode, + int x, + int y, + int clipx, + int clipy, + int clipcx, + int clipcy, + int boxx, + int boxy, + int boxcx, + int boxcy, + BRUSH * brush, + int bgcolour, + int fgcolour, + uint8 * text, + uint8 length + ) + { + int i, j; + DATABLOB *entry; + + HBRUSH hbr = CreateSolidBrush(bgcolour); + HGDIOBJ holdbrush = SelectObject(m_displayBuffer, hbr); + HGDIOBJ holdpen = SelectObject(m_displayBuffer, GetStockObject(NULL_PEN)); + + if (boxcx > 1) + Rectangle(m_displayBuffer, boxx, boxy, boxx + boxcx + 1, boxy + boxcy + 1); + else if (mixmode == MIX_OPAQUE) + Rectangle(m_displayBuffer, clipx, clipy, clipx + clipcx + 1, clipy + clipcy + 1); + + SelectObject(m_displayBuffer, holdpen); + SelectObject(m_displayBuffer, holdbrush); + + DeleteObject(hbr); + + if(boxcx > 1) + Display_RepaintArea(boxx, boxy, boxcx, boxcy); + else + Display_RepaintArea(clipx, clipy, clipcx, clipcy); + + /* Paint text, character by character */ + for (i = 0; i < length;) + { + switch (text[i]) + { + case 0xff: + /* At least two bytes needs to follow */ + if (i + 3 > length) + { + warning("Skipping short 0xff command:"); + for (j = 0; j < length; j++) + fprintf(stderr, "%02x ", text[j]); + fprintf(stderr, "\n"); + i = length = 0; + break; + } + cache_put_text(NULL /* TODO */, text[i + 1], text, text[i + 2]); + i += 3; + length -= i; + /* this will move pointer from start to first character after FF command */ + text = &(text[i]); + i = 0; + break; + + case 0xfe: + /* At least one byte needs to follow */ + if (i + 2 > length) + { + warning("Skipping short 0xfe command:"); + for (j = 0; j < length; j++) + fprintf(stderr, "%02x ", text[j]); + fprintf(stderr, "\n"); + i = length = 0; + break; + } + entry = cache_get_text(/*This*/NULL, text[i + 1]); + if (entry->data != NULL) + { + if ((((uint8 *) (entry->data))[1] == 0) + && (!(flags & TEXT2_IMPLICIT_X)) && (i + 2 < length)) + { + if (flags & TEXT2_VERTICAL) + y += text[i + 2]; + else + x += text[i + 2]; + } + for (j = 0; j < entry->size; j++) + Display_DoGlyph(font, flags, mixmode, x, y, bgcolour, fgcolour, ((uint8 *) (entry->data)), j); + } + if (i + 2 < length) + i += 3; + else + i += 2; + length -= i; + /* this will move pointer from start to first character after FE command */ + text = &(text[i]); + i = 0; + break; + + default: + Display_DoGlyph(font, flags, mixmode, x, y, bgcolour, fgcolour, text, i); + i++; + break; + } + } + } + + void Display_SaveDesktop(uint32 offset, int x, int y, int cx, int cy) + { + GdiFlush(); + + uint8 * data = + (uint8 *)m_displayBufferRaw + + x * m_displayBufferByteDepth + + (m_displayBufferHeight - y - cy) * m_displayBufferStride; + + cache_put_desktop + ( + /*This*/NULL, + offset * m_displayBufferByteDepth, + cx, + cy, + m_displayBufferStride, + m_displayBufferByteDepth, + data + ); + } + + void Display_RestoreDesktop(uint32 offset, int x, int y, int cx, int cy) + { + int fromstride = cx * m_displayBufferByteDepth; + + const uint8 * src = cache_get_desktop(/*This*/NULL, offset, cx, cy, m_displayBufferByteDepth); + + uint8 * dst = + (uint8 *)m_displayBufferRaw + + x * m_displayBufferByteDepth + + (m_displayBufferHeight - y - cy) * m_displayBufferStride; + + GdiFlush(); + + for(int i = 0; i < cy; ++ i) + { + memcpy(dst, src, fromstride); + src += fromstride; + dst += m_displayBufferStride; + } + + Display_RepaintArea(x, y, cx, cy); + } + + + void Display_BeginUpdate() + { + EnterCriticalSection(&m_displayBufferMutex); + m_displayBufferSave = SaveDC(m_displayBuffer); + } + + void Display_EndUpdate() + { + RestoreDC(m_displayBuffer, m_displayBufferSave); + LeaveCriticalSection(&m_displayBufferMutex); + } + + /* + This is the input window. It receives the keyboard and mouse input from + the user, and it's the only window that can receive the keyboard focus. + It completely fills its parent, the console window, and it runs in its + own thread for performance reasons and because of technical reasons + involving keyboard hooks in full-screen mode + */ + HWND m_inputWindow; + HCURSOR m_inputCursor; + + LRESULT InputWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch(uMsg) + { + case WM_DESTROY: + PostQuitMessage(0); + return 0; + + /* Keyboard stuff */ + // TODO: we need a good way to post output cross-thread + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_SCANCODE, RDP_KEYPRESS | (lparam & 0x1000000 ? KBD_FLAG_EXT : 0), LOBYTE(HIWORD(lparam)), 0); + break; + + case WM_SYSKEYUP: + case WM_KEYUP: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_SCANCODE, RDP_KEYRELEASE | (lparam & 0x1000000 ? KBD_FLAG_EXT : 0), LOBYTE(HIWORD(lparam)), 0); + break; + + /* Mouse stuff */ + // Cursor shape + case WM_SETCURSOR: + if(LOWORD(lParam) == HTCLIENT) + { + SetCursor(m_inputCursor); + return TRUE; + } + + break; + + // Movement + case WM_MOUSEMOVE: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, LOWORD(lparam), HIWORD(lparam)); + break; + + // Buttons + // TODO: X buttons + case WM_LBUTTONDOWN: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1 | MOUSE_FLAG_DOWN, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_RBUTTONDOWN: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2 | MOUSE_FLAG_DOWN, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_MBUTTONDOWN: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3 | MOUSE_FLAG_DOWN, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_LBUTTONUP: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_RBUTTONUP: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_MBUTTONUP: + //rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3, LOWORD(lparam), HIWORD(lparam)); + break; + + // Wheel + case WM_MOUSEWHEEL: + //mstsc_mousewheel(This, (SHORT)HIWORD(wparam), lparam); + break; + } + + return DefWindowProc(m_inputWindow, uMsg, wParam, lParam); + } + +public: +}; + +#pragma warning(push) +#pragma warning(disable: 4584) + +/* The ActiveX control */ +class RdpClient SEALED_: + /* COM basics */ + public IUnknown, + public IDispatch, + + /* ActiveX stuff */ + public IConnectionPointContainer, + public IDataObject, + public IObjectSafety, + public IOleControl, + public IOleInPlaceActiveObject, + public IOleInPlaceObject, + public IOleObject, + public IOleWindow, + public IPersist, + public IPersistPropertyBag, + public IPersistStorage, + public IPersistStreamInit, + public IProvideClassInfo, + public IProvideClassInfo2, + public IQuickActivate, + public IViewObject, + public IViewObject2, + + // NOTE: the original has a vestigial, non-functional implementation of this, which we omit + // ISpecifyPropertyPages + + // Hidden interfaces, not available through QueryInterface + public IConnectionPoint, + + /* RDP client interface */ + public MSTSCLib::IMsRdpClient4, + public MSTSCLib::IMsRdpClientNonScriptable2 + + // NOTE: implemented by inner classes due to requiring distinct IDispatch implementations + // IMsRdpClientAdvancedSettings4 + // IMsRdpClientSecuredSettings +{ +private: + /* An endless amount of COM glue */ + // Reference counting + LONG m_refCount; + +#ifdef _DEBUG + DWORD m_apartmentThreadId; + + bool InsideApartment() const + { + return GetCurrentThreadId() == m_apartmentThreadId; + } +#endif + + // Aggregation support + IUnknown * m_punkOuter; + + class RdpClientInner: public IUnknown + { + private: + RdpClient * Outer() + { + return InnerToOuter(this); + } + + public: + virtual STDMETHODIMP IUnknown::QueryInterface(REFIID riid, void ** ppvObject) + { + return Outer()->queryInterface(riid, ppvObject); + } + + virtual STDMETHODIMP_(ULONG) IUnknown::AddRef() + { + return Outer()->addRef(); + } + + virtual STDMETHODIMP_(ULONG) IUnknown::Release() + { + return Outer()->release(); + } + + } + m_inner; + + // Persistence support + CLSID m_classId; + + // Late binding support + unsigned m_typeLibIndex; + ITypeLib * m_typeLib; + ITypeInfo * m_dispTypeInfo; + + // Event sinks + size_t m_EventSinksCount; + + union + { + MSTSCLib::IMsTscAxEvents * m_EventSinksStatic[1]; + MSTSCLib::IMsTscAxEvents ** m_EventSinks; + }; + + // OLE control glue + HWND m_controlWindow; + IOleClientSite * m_clientSite; + IOleInPlaceSite * m_inPlaceSite; + IOleAdviseHolder * m_adviseHolder; + LONG m_freezeEvents; + bool m_uiActive; + + // UrlMon security + DWORD m_SafetyOptions; + + bool IsSafeForScripting() const + { + return m_SafetyOptions & INTERFACESAFE_FOR_UNTRUSTED_CALLER; + } + + /* Glue to interface to rdesktop-core */ + RdpClientUI * m_clientUI; + RDPCLIENT m_protocolState; + HANDLE m_protocolThread; + HANDLE m_protocolThreadWaitingReconnection; + bool m_reconnectAborted; + bool m_actuallyConnected; + bool m_loggedIn; + + /* Properties */ + // Storage fields + // NOTE: keep sorted by alignment (pointers and handles, integers, enumerations, booleans) + BSTR m_Domain; + BSTR m_UserName; + BSTR m_DisconnectedText; + BSTR m_ConnectingText; + BSTR m_FullScreenTitle; + BSTR m_StartProgram; + BSTR m_WorkDir; + BSTR m_ConnectedStatusText; + BSTR m_ClearTextPassword; // FIXME! dangerous, shouldn't store in cleartext! + BSTR m_RdpdrLocalPrintingDocName; + BSTR m_RdpdrClipCleanTempDirString; + BSTR m_RdpdrClipPasteInfoString; + BSTR m_KeyboardLayoutString; + LPSTR m_Server; + LPSTR m_LoadBalanceInfo; + // TODO: plugin DLLs + HWND m_UIParentWindowHandle; + long m_DesktopWidth; + long m_DesktopHeight; + long m_StartConnected; + long m_ColorDepth; + long m_KeyboardHookMode; + long m_AudioRedirectionMode; + long m_TransportType; + long m_SasSequence; + long m_RDPPort; + long m_HotKeyFullScreen; + long m_HotKeyAltEsc; + long m_HotKeyAltShiftTab; + long m_HotKeyAltSpace; + long m_HotKeyAltTab; + long m_HotKeyCtrlAltDel; + long m_HotKeyCtrlEsc; + long m_orderDrawThresold; + long m_BitmapCacheSize; + long m_BitmapVirtualCacheSize; + long m_NumBitmapCaches; + long m_brushSupportLevel; + long m_minInputSendInterval; + long m_InputEventsAtOnce; + long m_maxEventCount; + long m_keepAliveInternal; + long m_shutdownTimeout; + long m_overallConnectionTimeout; + long m_singleConnectionTimeout; + long m_MinutesToIdleTimeout; + long m_BitmapVirtualCache16BppSize; + long m_BitmapVirtualCache24BppSize; + long m_PerformanceFlags; + long m_MaxReconnectAttempts; + unsigned int m_AuthenticationLevel; + + MSTSCLib::ExtendedDisconnectReasonCode m_ExtendedDisconnectReason; + + bool m_Connected; + bool m_Compress; + bool m_BitmapPersistence; + bool m_allowBackgroundInput; + bool m_ContainerHandledFullScreen; + bool m_DisableRdpdr; + bool m_SecuredSettingsEnabled; + bool m_FullScreen; + bool m_AcceleratorPassthrough; + bool m_ShadowBitmap; + bool m_EncryptionEnabled; + bool m_DedicatedTerminal; + bool m_DisableCtrlAltDel; + bool m_EnableWindowsKey; + bool m_DoubleClickDetect; + bool m_MaximizeShell; + bool m_ScaleBitmapCachesByBpp; + bool m_CachePersistenceActive; + bool m_ConnectToServerConsole; + bool m_SmartSizing; // FIXME: this can be set while the control is connected + bool m_DisplayConnectionBar; + bool m_PinConnectionBar; + bool m_GrabFocusOnConnect; + bool m_RedirectDrives; + bool m_RedirectPrinters; + bool m_RedirectPorts; + bool m_RedirectSmartCards; + bool m_NotifyTSPublicKey; + bool m_CanAutoReconnect; + bool m_EnableAutoReconnect; + bool m_ConnectionBarShowMinimizeButton; + bool m_ConnectionBarShowRestoreButton; + + // Generic getters/setters + HRESULT GetProperty(BSTR& prop, BSTR * retVal) const + { + assert(InsideApartment()); + + if(retVal == NULL) + return E_POINTER; + + *retVal = SysAllocStringLen(prop, SysStringLen(prop)); + + if(*retVal == NULL) + return E_OUTOFMEMORY; + + return S_OK; + } + + HRESULT GetProperty(LPSTR& prop, BSTR * retVal) const + { + assert(InsideApartment()); + + if(retVal == NULL) + return E_POINTER; + + *retVal = LpszToBstr(prop); + + if(*retVal == NULL) + return E_OUTOFMEMORY; + + return S_OK; + } + + HRESULT SetProperty(BSTR& prop, BSTR newValue) + { + assert(InsideApartment()); + + if(m_Connected) + return E_FAIL; + + SysFreeString(prop); + + UINT len = SysStringLen(newValue); + + if(len) + { + // no embedded NULs, please + if(len != lstrlenW(newValue)) + return E_INVALIDARG; + + prop = SysAllocStringLen(newValue, len); + + if(prop == NULL) + return E_OUTOFMEMORY; + } + else + prop = NULL; + + return S_OK; + } + + HRESULT ReplaceProperty(BSTR& prop, BSTR newValue) + { + assert(InsideApartment()); + assert((prop == NULL && newValue == NULL) || prop != newValue); + + SysFreeString(prop); + prop = newValue; + return S_OK; + } + + HRESULT SetProperty(LPSTR& prop, BSTR newValue) + { + assert(InsideApartment()); + + if(m_Connected) + return E_FAIL; + + delete[] prop; + + if(SysStringLen(newValue)) + { + prop = BstrToLpsz(newValue); + + if(prop == NULL) + return E_OUTOFMEMORY; + } + else + prop = NULL; + + return S_OK; + } + + HRESULT ReplaceProperty(LPSTR& prop, LPSTR newValue) + { + assert(InsideApartment()); + assert((prop == NULL && newValue == NULL) || prop != newValue); + + if(prop) + delete[] prop; + + prop = newValue; + return S_OK; + } + + template HRESULT SetProperty(bool& prop, const Type& newValue) + { + assert(InsideApartment()); + + if(m_Connected) + return E_FAIL; + + prop = !!newValue; + return S_OK; + } + + template HRESULT SetProperty(Type& prop, const Type& newValue) + { + assert(InsideApartment()); + + if(m_Connected) + return E_FAIL; + + prop = newValue; + return S_OK; + } + + template HRESULT GetProperty(const bool& prop, Type * retVal) const + { + assert(InsideApartment()); + + if(retVal == NULL) + return E_POINTER; + + *retVal = prop ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; + } + + template HRESULT GetProperty(const Type& prop, Type * retVal) const + { + assert(InsideApartment()); + + if(retVal == NULL) + return E_POINTER; + + *retVal = prop; + return S_OK; + } + + /* Events */ + MSTSCLib::IMsTscAxEvents ** GetSinks() const + { + if(m_EventSinksCount > 1) + return m_EventSinks; + else + return const_cast(m_EventSinksStatic); + } + + // Event freezing + void UnfreezeEvents() + { + // Just in case + } + + // Generic event riser & helpers + void InvokeSinks(DISPID eventId, VARIANTARG rgvarg[], unsigned int cArgs, VARIANTARG * retval) + { + assert(InsideApartment()); + + DISPPARAMS params; + + params.rgvarg = rgvarg; + params.rgdispidNamedArgs = NULL; + params.cArgs = cArgs; + params.cNamedArgs = 0; + + MSTSCLib::IMsTscAxEvents ** sinks = GetSinks(); + + for(size_t i = 0; i < m_EventSinksCount; ++ i) + sinks[i]->Invoke(eventId, IID_NULL, 0, DISPATCH_METHOD, ¶ms, retval, NULL, NULL); + } + + typedef void (RdpClient::* AsyncEventCallback) + ( + DISPID eventId, + VARIANTARG * rgvarg, + unsigned int cArgs, + VARIANTARG * retVal + ); + + void CleanupEventArgumentsCallback + ( + DISPID eventId, + VARIANTARG * rgvarg, + unsigned int cArgs, + VARIANTARG * retVal + ) + { + assert((rgvarg == NULL) == (cArgs == 0)); + + for(unsigned int i = 0; i < cArgs; ++ i) + VariantClear(&rgvarg[i]); + + if(retVal) + VariantClear(retVal); + } + + // synchronous call from inside the apartment that owns the object + void FireEventInsideApartment + ( + DISPID eventId, + VARIANTARG * rgvarg = NULL, + unsigned int cArgs = 0, + VARIANTARG * retval = NULL, + AsyncEventCallback callback = NULL + ) + { + assert(InsideApartment()); + + if(retval == NULL && callback) + { + VARIANTARG localRetval = { }; + retval = &localRetval; + } + + InvokeSinks(eventId, rgvarg, cArgs, retval); + + if(callback) + (this->*callback)(eventId, rgvarg, cArgs, retval); + } + + struct EventArguments + { + DISPID eventId; + VARIANTARG * rgvarg; + unsigned int cArgs; + VARIANTARG * retval; + AsyncEventCallback callback; + }; + + struct RedirectArguments + { + uint32 flags; + uint32 server_len; + wchar_t * server; + uint32 cookie_len; + char * cookie; + uint32 username_len; + wchar_t * username; + uint32 domain_len; + wchar_t * domain; + uint32 password_len; + wchar_t * password; + }; + + enum + { + RDPC_WM_ = WM_USER, + RDPC_WM_SYNC_EVENT, + RDPC_WM_ASYNC_EVENT, + RDPC_WM_DISCONNECT, + RDPC_WM_REQUEST_CLOSE, + RDPC_WM_REDIRECT, + }; + + static VOID CALLBACK DisconnectAPC(ULONG_PTR) + { + // no need to do anything. The interruption will be enough + } + + bool HandleEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& result) + { + result = 0; + + switch(uMsg) + { + /* Regular event to be dispatched to the container's sink */ + case RDPC_WM_SYNC_EVENT: + assert(InSendMessage()); + + case RDPC_WM_ASYNC_EVENT: + { + const EventArguments * eventArgs = reinterpret_cast(lParam); + assert(eventArgs); + + FireEventInsideApartment + ( + eventArgs->eventId, + eventArgs->rgvarg, + eventArgs->cArgs, + eventArgs->retval, + eventArgs->callback + ); + + if(uMsg == RDPC_WM_ASYNC_EVENT) + delete eventArgs; + } + + break; + + /* The protocol thread is about to die: prepare for disconnection */ + case RDPC_WM_DISCONNECT: + { + assert(m_Connected); + assert(InsideApartment()); + assert(InSendMessage()); + + // Unblock the protocol thread and wait for it to terminate + ReplyMessage(0); + JoinProtocolThread(); + + // Finish disconnecting + PerformDisconnect(static_cast(wParam)); + } + + break; + + case RDPC_WM_REDIRECT: + { + assert(InSendMessage()); + assert(lParam); + assert(m_Connected); + assert(m_protocolState.redirect); + + RedirectArguments * redirectArgs = reinterpret_cast(lParam); + + // BUGBUG: this is extremely messy and more prone to out-of-memory than it should be + LPSTR lpszNewServer = NULL; + LPSTR lpszNewCookie = NULL; + BSTR strNewUsername = NULL; + BSTR strNewDomain = NULL; + BSTR strNewPassword = NULL; + HRESULT hr = S_OK; + + for(;;) + { + // Allocate the new properties + hr = E_OUTOFMEMORY; + + // FIXME: convert the hostname to Punycode, not the ANSI codepage + lpszNewServer = AllocLpsz(redirectArgs->server, redirectArgs->server_len / sizeof(OLECHAR)); + + if(lpszNewServer == NULL && redirectArgs->server_len) + break; + + lpszNewCookie = AllocLpsz(redirectArgs->cookie, redirectArgs->cookie_len); + + if(lpszNewCookie == NULL && redirectArgs->cookie_len) + break; + + strNewUsername = SysAllocStringLen(redirectArgs->username, redirectArgs->username_len / sizeof(OLECHAR)); + + if(strNewUsername == NULL && redirectArgs->username_len) + break; + + strNewDomain = SysAllocStringLen(redirectArgs->domain, redirectArgs->domain_len / sizeof(OLECHAR)); + + if(strNewDomain == NULL && redirectArgs->domain_len) + break; + + strNewPassword = SysAllocStringLen(redirectArgs->password, redirectArgs->password_len / sizeof(OLECHAR)); + + if(strNewPassword == NULL && redirectArgs->password_len) + break; + + hr = S_OK; + break; + } + + // Success + if(SUCCEEDED(hr)) + { + // set the new properties + ReplaceProperty(m_Server, lpszNewServer); + ReplaceProperty(m_LoadBalanceInfo, lpszNewCookie); + ReplaceProperty(m_UserName, strNewUsername); + ReplaceProperty(m_Domain, strNewDomain); + ReplaceProperty(m_ClearTextPassword, strNewPassword); + } + // Failure + else + { + // free the buffers + FreeLpsz(lpszNewServer); + FreeLpsz(lpszNewCookie); + SysFreeString(strNewUsername); + SysFreeString(strNewDomain); + SysFreeString(strNewPassword); + + // signal the error + m_protocolState.disconnect_reason = 262; + m_protocolState.redirect = False; + result = -1; + } + } + + break; + + // BUGBUG: this could potentially disconnect an unrelated connection established later... + case RDPC_WM_REQUEST_CLOSE: + { + assert(!InSendMessage()); + + if(m_Connected) + { + // Ask confirmation to the container in case we are logged in + if(m_loggedIn && !FireConfirmClose()) + break; + + // For reentrancy (OnConfirmClose could deviously call Disconnect) + if(m_protocolThread == NULL) + break; + + // Terminate the protocol thread. It will fire the Disconnected event on exit + TerminateProtocolThread(); + } + } + + break; + + default: + return false; + } + + // If the calling thread is blocked, unblock it ASAP + if(InSendMessage()) + ReplyMessage(result); + + return true; + } + + // synchronous call from outside the apartment + void FireEventOutsideApartment + ( + DISPID eventId, + VARIANTARG * rgvarg = NULL, + unsigned int cArgs = 0, + VARIANTARG * retval = NULL, + AsyncEventCallback callback = NULL + ) + { + assert(!InsideApartment()); + EventArguments syncEvent = { eventId, rgvarg, cArgs, retval, callback }; + SendMessage(m_controlWindow, RDPC_WM_SYNC_EVENT, 0, reinterpret_cast(&syncEvent)); + } + + // asynchronous call from outside the apartment + HRESULT FireEventOutsideApartmentAsync + ( + DISPID eventId, + VARIANTARG * rgvarg = NULL, + unsigned int cArgs = 0, + VARIANTARG * retval = NULL, + AsyncEventCallback callback = NULL + ) + { + assert(!InsideApartment()); + + EventArguments * asyncEvent = new EventArguments(); + + if(asyncEvent == NULL) + return E_OUTOFMEMORY; + + asyncEvent->eventId = eventId; + asyncEvent->rgvarg = rgvarg; + asyncEvent->cArgs = cArgs; + asyncEvent->retval = NULL; + + if(!PostMessage(m_controlWindow, RDPC_WM_ASYNC_EVENT, 0, reinterpret_cast(asyncEvent))) + { + delete asyncEvent; + return HRESULT_FROM_WIN32(GetLastError()); + } + + return S_OK; + } + + // Specific events + void FireConnecting() + { + // Source: protocol + FireEventOutsideApartment(1); + } + + void FireConnected() + { + // Source: protocol + FireEventOutsideApartment(2); + } + + void FireLoginComplete() + { + // Source: protocol + FireEventOutsideApartment(3); + } + + void FireDisconnected(long reason) + { + // Source: protocol. Special handling + SendMessage(m_controlWindow, RDPC_WM_DISCONNECT, reason, 0); + } + + void FireEnterFullScreenMode() + { + // Source: UI window + FireEventInsideApartment(5); + } + + void FireLeaveFullScreenMode() + { + // Source: UI window + FireEventInsideApartment(6); + } + + HRESULT FireChannelReceivedData(char (& chanName)[CHANNEL_NAME_LEN + 1], void * chanData, unsigned int chanDataSize) + { + // BUGBUG: what to do when we run out of memory? + + OLECHAR wchanName[ARRAYSIZE(chanName)]; + std::copy(chanName + 0, chanName + ARRAYSIZE(chanName), wchanName); + + BSTR bstrChanName = SysAllocString(wchanName); + + if(bstrChanName == NULL) + return E_OUTOFMEMORY; + + BSTR bstrChanData = SysAllocStringByteLen(NULL, chanDataSize); + + if(bstrChanData == NULL) + { + SysFreeString(bstrChanName); + return E_OUTOFMEMORY; + } + + CopyMemory(bstrChanData, chanData, chanDataSize); + + VARIANTARG args[2] = { }; + + args[1].vt = VT_BSTR; + args[1].bstrVal = bstrChanName; + + args[0].vt = VT_BSTR; + args[0].bstrVal = bstrChanData; + + // Source: protocol + HRESULT hr = FireEventOutsideApartmentAsync(7, args, ARRAYSIZE(args), NULL, &RdpClient::CleanupEventArgumentsCallback); + + if(FAILED(hr)) + CleanupEventArgumentsCallback(7, args, ARRAYSIZE(args), NULL); + + return hr; + } + + void FireRequestGoFullScreen() + { + // Source: UI window + FireEventInsideApartment(8); + } + + void FireRequestLeaveFullScreen() + { + // Source: UI window + FireEventInsideApartment(9); + } + + void FireFatalError(long errorCode) + { + VARIANTARG arg = { }; + + arg.vt = VT_I4; + arg.lVal = errorCode; + + // Source: protocol + FireEventOutsideApartment(10, &arg, 1); + } + + void FireFatalErrorFromApartment(long errorCode) + { + VARIANTARG arg = { }; + + arg.vt = VT_I4; + arg.lVal = errorCode; + + // Source: control + FireEventInsideApartment(10, &arg, 1); + } + + void FireWarning(long warningCode) + { + VARIANTARG arg = { }; + + arg.vt = VT_I4; + arg.lVal = warningCode; + + // Source: protocol + FireEventOutsideApartment(11, &arg, 1); + } + + void FireRemoteDesktopSizeChange(long width, long height) + { + VARIANTARG args[2] = { }; + + args[1].vt = VT_I4; + args[1].lVal = width; + + args[0].vt = VT_I4; + args[0].lVal = height; + + // Source: UI window + FireEventInsideApartment(12, args, ARRAYSIZE(args)); + } + + void FireIdleTimeoutNotification() + { + // Source: input thread + FireEventOutsideApartment(13); + } + + void FireRequestContainerMinimize() + { + // Source: UI window + FireEventInsideApartment(14); + } + + bool FireConfirmClose() + { + VARIANTARG retval = { }; + VARIANT_BOOL allowClose = VARIANT_TRUE; + + retval.vt = VT_BYREF | VT_BOOL; + retval.pboolVal = &allowClose; + + // Source: control + FireEventInsideApartment(15, NULL, 0, &retval); + + return allowClose != VARIANT_FALSE; + } + + HRESULT FireReceivedTSPublicKey(void * publicKey, unsigned int publicKeyLength) + { + assert(m_Connected); + + if(!m_NotifyTSPublicKey) + return S_OK; + + BSTR bstrPublicKey = SysAllocStringByteLen(NULL, publicKeyLength); + + if(bstrPublicKey == NULL) + return E_OUTOFMEMORY; + + CopyMemory(bstrPublicKey, publicKey, publicKeyLength); + + VARIANT_BOOL continueLogon = VARIANT_TRUE; + VARIANTARG arg = { }; + VARIANTARG retval = { }; + + arg.vt = VT_BSTR; + arg.bstrVal = bstrPublicKey; + + retval.vt = VT_BYREF | VT_BOOL; + retval.pboolVal = &continueLogon; + + // Source: protocol + FireEventOutsideApartment(16, &arg, 1, &retval); + + return continueLogon ? S_OK : S_FALSE; + } + + LONG FireAutoReconnecting(long disconnectReason, long attemptCount) + { + LONG continueStatus = MSTSCLib::autoReconnectContinueAutomatic; + VARIANTARG args[2] = { }; + VARIANTARG retval = { }; + + args[1].vt = VT_I4; + args[1].lVal = disconnectReason; + + args[0].vt = VT_I4; + args[0].lVal = attemptCount; + + retval.vt = VT_BYREF | VT_I4; + retval.plVal = &continueStatus; + + // Source: protocol + FireEventOutsideApartment(17, args, ARRAYSIZE(args), &retval); + + return continueStatus; + } + + void FireAuthenticationWarningDisplayed() + { + // Source: protocol + FireEventOutsideApartment(18); + } + + void FireAuthenticationWarningDismissed() + { + // Source: protocol + FireEventOutsideApartment(19); + } + + /* Actual IUnknown implementation */ + HRESULT queryInterface(REFIID riid, void ** ppvObject) + { + IUnknown * pvObject = NULL; + + using namespace MSTSCLib; + + if(riid == IID_IUnknown) + pvObject = static_cast(&m_inner); + else if(riid == IID_IConnectionPointContainer) + pvObject = static_cast(this); + else if(riid == IID_IDataObject) + pvObject = static_cast(this); + else if(riid == IID_IObjectSafety) + pvObject = static_cast(this); + else if(riid == IID_IOleControl) + pvObject = static_cast(this); + else if(riid == IID_IOleInPlaceActiveObject) + pvObject = static_cast(this); + else if(riid == IID_IOleInPlaceObject) + pvObject = static_cast(this); + else if(riid == IID_IOleObject) + pvObject = static_cast(this); + else if(riid == IID_IOleWindow) + pvObject = static_cast(this); + else if(riid == IID_IPersist) + pvObject = static_cast(this); + else if(riid == IID_IPersistPropertyBag) + pvObject = static_cast(this); + else if(riid == IID_IPersistStorage) + pvObject = static_cast(this); + else if(riid == IID_IPersistStreamInit) + pvObject = static_cast(this); + else if(riid == IID_IQuickActivate) + pvObject = static_cast(this); + else if(riid == IID_IViewObject) + pvObject = static_cast(this); + else if(riid == IID_IViewObject2) + pvObject = static_cast(this); + else if(riid == IID_IMsTscAx || riid == MSTSCLib_Redist::IID_IMsTscAx) + pvObject = static_cast(this); + else if(riid == IID_IMsRdpClient) + pvObject = static_cast(this); + else if(riid == IID_IMsRdpClient2) + pvObject = static_cast(this); + else if(riid == IID_IMsRdpClient3) + pvObject = static_cast(this); + else if(riid == IID_IMsRdpClient4) + pvObject = static_cast(this); + else if(riid == IID_IMsTscNonScriptable) + pvObject = static_cast(this); + else if(riid == IID_IMsRdpClientNonScriptable) + pvObject = static_cast(this); + else if(riid == IID_IMsRdpClientNonScriptable2) + pvObject = static_cast(this); + + *ppvObject = pvObject; + + if(pvObject) + { + pvObject->AddRef(); + return S_OK; + } + + return E_NOINTERFACE; + } + + ULONG addRef() + { + return InterlockedIncrement(&m_refCount); + } + + ULONG release() + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + /* Constructor */ + RdpClient(REFCLSID classId, unsigned libIndex, IUnknown * punkOuter): + // COM/OLE internals + m_refCount(0), + m_punkOuter(punkOuter), + m_classId(classId), + m_typeLibIndex(libIndex), + m_typeLib(), + m_dispTypeInfo(), + m_controlWindow(NULL), + m_clientSite(), + m_inPlaceSite(), + m_adviseHolder(), + m_freezeEvents(0), + m_uiActive(false), + m_SafetyOptions(), + +#ifdef _DEBUG + m_apartmentThreadId(GetCurrentThreadId()), +#endif + + // rdesktop-core interface + m_protocolState(), + m_protocolThread(), + + // Properties + m_Server(), + m_Domain(), + m_UserName(), + m_DisconnectedText(), + m_ConnectingText(), + m_FullScreenTitle(), + m_StartProgram(), + m_WorkDir(), + m_LoadBalanceInfo(), + m_ConnectedStatusText(), + m_ClearTextPassword(), + m_RdpdrLocalPrintingDocName(), + m_RdpdrClipCleanTempDirString(), + m_RdpdrClipPasteInfoString(), + m_UIParentWindowHandle(), + m_DesktopWidth(), + m_DesktopHeight(), + m_StartConnected(), + m_ColorDepth(16), + m_KeyboardHookMode(2), + m_AudioRedirectionMode(0), + m_TransportType(1), // BUGBUG: ??? what's this ??? + m_SasSequence(0xAA03), // BUGBUG: ??? what's this ??? + m_RDPPort(3389), + m_HotKeyFullScreen(VK_CANCEL), + m_HotKeyAltEsc(VK_INSERT), + m_HotKeyAltShiftTab(VK_NEXT), + m_HotKeyAltSpace(VK_DELETE), + m_HotKeyAltTab(VK_PRIOR), + m_HotKeyCtrlAltDel(VK_END), + m_HotKeyCtrlEsc(VK_HOME), + m_orderDrawThresold(0), + m_BitmapCacheSize(1500), + m_BitmapVirtualCacheSize(10), + m_brushSupportLevel(), + m_minInputSendInterval(), + m_InputEventsAtOnce(), + m_maxEventCount(), + m_keepAliveInternal(0), + m_shutdownTimeout(10), + m_overallConnectionTimeout(120), + m_singleConnectionTimeout(30), + m_MinutesToIdleTimeout(0), + m_BitmapVirtualCache16BppSize(20), + m_BitmapVirtualCache24BppSize(30), + m_PerformanceFlags(), + m_MaxReconnectAttempts(20), + m_AuthenticationLevel(0), + m_ExtendedDisconnectReason(MSTSCLib::exDiscReasonNoInfo), + m_Connected(false), + m_Compress(true), + m_BitmapPersistence(true), + m_allowBackgroundInput(false), + m_ContainerHandledFullScreen(false), + m_DisableRdpdr(false), + m_SecuredSettingsEnabled(true), + m_FullScreen(false), + m_AcceleratorPassthrough(true), + m_ShadowBitmap(true), + m_EncryptionEnabled(true), + m_DedicatedTerminal(false), + m_DisableCtrlAltDel(true), + m_EnableWindowsKey(true), + m_DoubleClickDetect(false), + m_MaximizeShell(true), + m_ScaleBitmapCachesByBpp(false), + m_CachePersistenceActive(false), + m_ConnectToServerConsole(false), + m_SmartSizing(false), + m_DisplayConnectionBar(true), + m_PinConnectionBar(true), + m_GrabFocusOnConnect(true), + m_RedirectDrives(false), + m_RedirectPrinters(false), + m_RedirectPorts(false), + m_RedirectSmartCards(false), + m_NotifyTSPublicKey(false), + m_CanAutoReconnect(false), + m_EnableAutoReconnect(true), + m_ConnectionBarShowMinimizeButton(true), + m_ConnectionBarShowRestoreButton(true) + { + if(m_punkOuter == NULL) + m_punkOuter = &m_inner; + } + + /* Destructor */ + ~RdpClient() + { + assert(m_refCount == 0); + + if(m_Connected) + { + // Terminate the protocol thread + TerminateProtocolThread(); + + // Dispatch the RDPC_WM_DISCONNECT message sent by the dying thread + MSG msg; + PeekMessage(&msg, m_controlWindow, 0, 0, PM_NOREMOVE); + + assert(!m_Connected); + } + + DestroyControlWindow(); + + if(m_typeLib) + m_typeLib->Release(); + + if(m_dispTypeInfo) + m_dispTypeInfo->Release(); + + MSTSCLib::IMsTscAxEvents ** sinks = GetSinks(); + + for(size_t i = 0; i < m_EventSinksCount; ++ i) + sinks[i]->Release(); + + if(m_EventSinksCount > 1) + delete[] m_EventSinks; + + if(m_clientSite) + m_clientSite->Release(); + + if(m_inPlaceSite) + m_inPlaceSite->Release(); + + if(m_adviseHolder) + m_adviseHolder->Release(); + + SysFreeString(m_Domain); + SysFreeString(m_UserName); + SysFreeString(m_DisconnectedText); + SysFreeString(m_DisconnectedText); + SysFreeString(m_FullScreenTitle); + SysFreeString(m_StartProgram); + SysFreeString(m_WorkDir); + SysFreeString(m_ConnectedStatusText); + SysFreeString(m_ClearTextPassword); + SysFreeString(m_RdpdrLocalPrintingDocName); + SysFreeString(m_RdpdrClipCleanTempDirString); + SysFreeString(m_RdpdrClipPasteInfoString); + + FreeLpsz(m_LoadBalanceInfo); + FreeLpsz(m_Server); + + unlockServer(); + } + + /* Advanced settings wrapper */ + friend class AdvancedSettings; + + class AdvancedSettings SEALED_: public MSTSCLib::IMsRdpClientAdvancedSettings4 + { + private: + RdpClient * Outer() + { + return InnerToOuter(this); + } + + const RdpClient * Outer() const + { + return InnerToOuter(this); + } + + /* IDispatch type information */ + ITypeInfo * m_dispTypeInfo; + + HRESULT LoadDispTypeInfo() + { + if(m_dispTypeInfo) + return S_OK; + + HRESULT hr = Outer()->LoadTypeLibrary(); + + if(FAILED(hr)) + return hr; + + assert(MSTSCLib::IID_IMsRdpClientAdvancedSettings4 == MSTSCLib_Redist::IID_IMsRdpClientAdvancedSettings4); + + hr = Outer()->m_typeLib->GetTypeInfoOfGuid(MSTSCLib::IID_IMsRdpClientAdvancedSettings4, &m_dispTypeInfo); + + if(FAILED(hr)) + return hr; + + assert(m_dispTypeInfo); + return S_OK; + } + + HRESULT AcquireDispTypeInfo(ITypeInfo ** ppTI) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + m_dispTypeInfo->AddRef(); + *ppTI = m_dispTypeInfo; + return S_OK; + } + + public: + ~AdvancedSettings() + { + if(m_dispTypeInfo) + m_dispTypeInfo->Release(); + } + + /* IUnknown */ + virtual STDMETHODIMP IUnknown::QueryInterface(REFIID riid, void ** ppvObject) + { + using namespace MSTSCLib; + + if + ( + riid == IID_IUnknown || + riid == IID_IDispatch || + riid == IID_IMsTscAdvancedSettings || + riid == IID_IMsRdpClientAdvancedSettings || + riid == IID_IMsRdpClientAdvancedSettings2 || + riid == IID_IMsRdpClientAdvancedSettings3 || + riid == IID_IMsRdpClientAdvancedSettings4 + ) + { + *ppvObject = this; + Outer()->addRef(); + return S_OK; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + } + + virtual STDMETHODIMP_(ULONG) IUnknown::AddRef() + { + return Outer()->addRef(); + } + + virtual STDMETHODIMP_(ULONG) IUnknown::Release() + { + return Outer()->release(); + } + + /* IDispatch */ + virtual STDMETHODIMP IDispatch::GetTypeInfoCount(UINT * pctinfo) + { + *pctinfo = 1; + return S_OK; + } + + virtual STDMETHODIMP IDispatch::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) + { + if(iTInfo != 0) + return DISP_E_BADINDEX; + + return AcquireDispTypeInfo(ppTInfo); + } + + virtual STDMETHODIMP IDispatch::GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + return m_dispTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId); + } + + virtual STDMETHODIMP IDispatch::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) + { + return m_dispTypeInfo->Invoke + ( + static_cast(this), + dispIdMember, + wFlags, + pDispParams, + pVarResult, + pExcepInfo, + puArgErr + ); + } + + /* IMsTscAdvancedSettings */ + virtual STDMETHODIMP IMsTscAdvancedSettings::put_Compress(long pcompress) + { + return Outer()->SetProperty(Outer()->m_Compress, pcompress); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_Compress(long * pcompress) const + { + return Outer()->GetProperty(Outer()->m_Compress, pcompress); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_BitmapPeristence(long pbitmapPeristence) + { + return Outer()->SetProperty(Outer()->m_BitmapPersistence, pbitmapPeristence); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_BitmapPeristence(long * pbitmapPeristence) const + { + return Outer()->GetProperty(Outer()->m_BitmapPersistence, pbitmapPeristence); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_allowBackgroundInput(long pallowBackgroundInput) + { + if(Outer()->IsSafeForScripting()) + return S_FALSE; + + return Outer()->SetProperty(Outer()->m_allowBackgroundInput, pallowBackgroundInput); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_allowBackgroundInput(long * pallowBackgroundInput) const + { + return Outer()->GetProperty(Outer()->m_allowBackgroundInput, pallowBackgroundInput); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_KeyBoardLayoutStr(BSTR rhs) + { + return Outer()->SetProperty(Outer()->m_KeyboardLayoutString, rhs); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_PluginDlls(BSTR rhs) + { + // TODO: split rhs into an array + + // Control marked safe for scripting: only allow filenames + if(Outer()->IsSafeForScripting()) + { + // TODO: validate entries + // TODO: replace each entry with a full path based on the Virtual Channel DLL path + } + + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_IconFile(BSTR rhs) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_IconIndex(long rhs) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_ContainerHandledFullScreen(long pContainerHandledFullScreen) + { + if(Outer()->IsSafeForScripting()) + return S_FALSE; + + return Outer()->SetProperty(Outer()->m_ContainerHandledFullScreen, pContainerHandledFullScreen); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_ContainerHandledFullScreen(long * pContainerHandledFullScreen) const + { + return Outer()->GetProperty(Outer()->m_ContainerHandledFullScreen, pContainerHandledFullScreen); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::put_DisableRdpdr(long pDisableRdpdr) + { + return Outer()->SetProperty(Outer()->m_DisableRdpdr, pDisableRdpdr); + } + + virtual STDMETHODIMP IMsTscAdvancedSettings::get_DisableRdpdr(long * pDisableRdpdr) const + { + return Outer()->GetProperty(Outer()->m_DisableRdpdr, pDisableRdpdr); + } + + /* IMsRdpClientAdvancedSettings */ + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_SmoothScroll(long psmoothScroll) + { + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_SmoothScroll(long * psmoothScroll) const + { + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_AcceleratorPassthrough(long pacceleratorPassthrough) + { + return Outer()->SetProperty(Outer()->m_AcceleratorPassthrough, pacceleratorPassthrough); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_AcceleratorPassthrough(long * pacceleratorPassthrough) const + { + return Outer()->GetProperty(Outer()->m_AcceleratorPassthrough, pacceleratorPassthrough); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ShadowBitmap(long pshadowBitmap) + { + return Outer()->SetProperty(Outer()->m_ShadowBitmap, pshadowBitmap); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_ShadowBitmap(long * pshadowBitmap) const + { + return Outer()->GetProperty(Outer()->m_ShadowBitmap, pshadowBitmap); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_TransportType(long ptransportType) + { + // Reserved + return Outer()->SetProperty(Outer()->m_TransportType, ptransportType); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_TransportType(long * ptransportType) const + { + // Reserved + return Outer()->GetProperty(Outer()->m_TransportType, ptransportType); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_SasSequence(long psasSequence) + { + // Reserved + return Outer()->SetProperty(Outer()->m_SasSequence, psasSequence); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_SasSequence(long * psasSequence) const + { + // Reserved + return Outer()->GetProperty(Outer()->m_SasSequence, psasSequence); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_EncryptionEnabled(long pencryptionEnabled) + { + return Outer()->SetProperty(Outer()->m_EncryptionEnabled, pencryptionEnabled); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_EncryptionEnabled(long * pencryptionEnabled) const + { + return Outer()->GetProperty(Outer()->m_EncryptionEnabled, pencryptionEnabled); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_DedicatedTerminal(long pdedicatedTerminal) + { + return Outer()->SetProperty(Outer()->m_DedicatedTerminal, pdedicatedTerminal); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_DedicatedTerminal(long * pdedicatedTerminal) const + { + return Outer()->GetProperty(Outer()->m_DedicatedTerminal, pdedicatedTerminal); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RDPPort(long prdpPort) + { + if(prdpPort == 0 || prdpPort > 65535) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_RDPPort, prdpPort); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RDPPort(long * prdpPort) const + { + return Outer()->GetProperty(Outer()->m_RDPPort, prdpPort); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_EnableMouse(long penableMouse) + { + return S_FALSE; // TBD? implement? + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_EnableMouse(long * penableMouse) const + { + return S_FALSE; // TBD? implement? + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_DisableCtrlAltDel(long pdisableCtrlAltDel) + { + return Outer()->SetProperty(Outer()->m_DisableCtrlAltDel, pdisableCtrlAltDel); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_DisableCtrlAltDel(long * pdisableCtrlAltDel) const + { + return Outer()->GetProperty(Outer()->m_DisableCtrlAltDel, pdisableCtrlAltDel); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_EnableWindowsKey(long penableWindowsKey) + { + return Outer()->SetProperty(Outer()->m_EnableWindowsKey, penableWindowsKey); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_EnableWindowsKey(long * penableWindowsKey) const + { + return Outer()->GetProperty(Outer()->m_EnableWindowsKey, penableWindowsKey); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_DoubleClickDetect(long pdoubleClickDetect) + { + return Outer()->SetProperty(Outer()->m_DoubleClickDetect, pdoubleClickDetect); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_DoubleClickDetect(long * pdoubleClickDetect) const + { + return Outer()->GetProperty(Outer()->m_DoubleClickDetect, pdoubleClickDetect); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_MaximizeShell(long pmaximizeShell) + { + return Outer()->SetProperty(Outer()->m_MaximizeShell, pmaximizeShell); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_MaximizeShell(long * pmaximizeShell) const + { + return Outer()->GetProperty(Outer()->m_MaximizeShell, pmaximizeShell); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyFullScreen(long photKeyFullScreen) + { + return Outer()->SetProperty(Outer()->m_HotKeyFullScreen, photKeyFullScreen); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyFullScreen(long * photKeyFullScreen) const + { + return Outer()->GetProperty(Outer()->m_HotKeyFullScreen, photKeyFullScreen); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyCtrlEsc(long photKeyCtrlEsc) + { + return Outer()->SetProperty(Outer()->m_HotKeyCtrlEsc, photKeyCtrlEsc); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyCtrlEsc(long * photKeyCtrlEsc) const + { + return Outer()->GetProperty(Outer()->m_HotKeyCtrlEsc, photKeyCtrlEsc); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyAltEsc(long photKeyAltEsc) + { + return Outer()->SetProperty(Outer()->m_HotKeyAltEsc, photKeyAltEsc); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyAltEsc(long * photKeyAltEsc) const + { + return Outer()->GetProperty(Outer()->m_HotKeyAltEsc, photKeyAltEsc); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyAltTab(long photKeyAltTab) + { + return Outer()->SetProperty(Outer()->m_HotKeyAltTab, photKeyAltTab); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyAltTab(long * photKeyAltTab) const + { + return Outer()->GetProperty(Outer()->m_HotKeyAltTab, photKeyAltTab); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyAltShiftTab(long photKeyAltShiftTab) + { + return Outer()->SetProperty(Outer()->m_HotKeyAltShiftTab, photKeyAltShiftTab); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyAltShiftTab(long * photKeyAltShiftTab) const + { + return Outer()->GetProperty(Outer()->m_HotKeyAltShiftTab, photKeyAltShiftTab); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyAltSpace(long photKeyAltSpace) + { + return Outer()->SetProperty(Outer()->m_HotKeyAltSpace, photKeyAltSpace); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyAltSpace(long * photKeyAltSpace) const + { + return Outer()->GetProperty(Outer()->m_HotKeyAltSpace, photKeyAltSpace); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_HotKeyCtrlAltDel(long photKeyCtrlAltDel) + { + return Outer()->SetProperty(Outer()->m_HotKeyCtrlAltDel, photKeyCtrlAltDel); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_HotKeyCtrlAltDel(long * photKeyCtrlAltDel) const + { + return Outer()->GetProperty(Outer()->m_HotKeyCtrlAltDel, photKeyCtrlAltDel); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_orderDrawThreshold(long porderDrawThreshold) + { + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_orderDrawThreshold(long * porderDrawThreshold) const + { + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapCacheSize(long pbitmapCacheSize) + { + // NOTE: the upper bound of "32" for a field with a default value of 1500 seems to be a bug + if(pbitmapCacheSize < 0 || pbitmapCacheSize > 32) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_BitmapCacheSize, pbitmapCacheSize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapCacheSize(long * pbitmapCacheSize) const + { + return Outer()->GetProperty(Outer()->m_BitmapCacheSize, pbitmapCacheSize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapVirtualCacheSize(long pbitmapVirtualCacheSize) + { + if(pbitmapVirtualCacheSize < 0 || pbitmapVirtualCacheSize > 32) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_BitmapVirtualCacheSize, pbitmapVirtualCacheSize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapVirtualCacheSize(long * pbitmapVirtualCacheSize) const + { + return Outer()->GetProperty(Outer()->m_BitmapVirtualCacheSize, pbitmapVirtualCacheSize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ScaleBitmapCachesByBPP(long pbScale) + { + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_ScaleBitmapCachesByBPP(long * pbScale) const + { + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_NumBitmapCaches(long pnumBitmapCaches) + { + return Outer()->SetProperty(Outer()->m_NumBitmapCaches, pnumBitmapCaches); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_NumBitmapCaches(long * pnumBitmapCaches) const + { + return Outer()->GetProperty(Outer()->m_NumBitmapCaches, pnumBitmapCaches); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_CachePersistenceActive(long pcachePersistenceActive) + { + return Outer()->SetProperty(Outer()->m_CachePersistenceActive, pcachePersistenceActive); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_CachePersistenceActive(long * pcachePersistenceActive) const + { + return Outer()->GetProperty(Outer()->m_CachePersistenceActive, pcachePersistenceActive); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_PersistCacheDirectory(BSTR rhs) + { + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_brushSupportLevel(long pbrushSupportLevel) + { + return Outer()->SetProperty(Outer()->m_brushSupportLevel, pbrushSupportLevel); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_brushSupportLevel(long * pbrushSupportLevel) const + { + return Outer()->GetProperty(Outer()->m_brushSupportLevel, pbrushSupportLevel); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_minInputSendInterval(long pminInputSendInterval) + { + // TODO + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_minInputSendInterval(long * pminInputSendInterval) const + { + // TODO + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_InputEventsAtOnce(long pinputEventsAtOnce) + { + // TODO + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_InputEventsAtOnce(long * pinputEventsAtOnce) const + { + // TODO + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_maxEventCount(long pmaxEventCount) + { + // TODO + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_maxEventCount(long * pmaxEventCount) const + { + // TODO + return S_FALSE; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_keepAliveInterval(long pkeepAliveInterval) + { + if(pkeepAliveInterval && pkeepAliveInterval < 10) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_keepAliveInternal, pkeepAliveInterval); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_keepAliveInterval(long * pkeepAliveInterval) const + { + return Outer()->GetProperty(Outer()->m_keepAliveInternal, pkeepAliveInterval); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_shutdownTimeout(long pshutdownTimeout) + { + if(pshutdownTimeout >= 600) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_shutdownTimeout, pshutdownTimeout); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_shutdownTimeout(long * pshutdownTimeout) const + { + return Outer()->GetProperty(Outer()->m_shutdownTimeout, pshutdownTimeout); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_overallConnectionTimeout(long poverallConnectionTimeout) + { + if(poverallConnectionTimeout < 0 || poverallConnectionTimeout >= 600) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_overallConnectionTimeout, poverallConnectionTimeout); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_overallConnectionTimeout(long * poverallConnectionTimeout) const + { + return Outer()->GetProperty(Outer()->m_overallConnectionTimeout, poverallConnectionTimeout); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_singleConnectionTimeout(long psingleConnectionTimeout) + { + if(psingleConnectionTimeout >= 600) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_singleConnectionTimeout, psingleConnectionTimeout); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_singleConnectionTimeout(long * psingleConnectionTimeout) const + { + return Outer()->GetProperty(Outer()->m_singleConnectionTimeout, psingleConnectionTimeout); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_KeyboardType(long pkeyboardType) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_KeyboardType(long * pkeyboardType) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_KeyboardSubType(long pkeyboardSubType) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_KeyboardSubType(long * pkeyboardSubType) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_KeyboardFunctionKey(long pkeyboardFunctionKey) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_KeyboardFunctionKey(long * pkeyboardFunctionKey) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_WinceFixedPalette(long pwinceFixedPalette) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_WinceFixedPalette(long * pwinceFixedPalette) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ConnectToServerConsole(VARIANT_BOOL pConnectToConsole) + { + return Outer()->SetProperty(Outer()->m_ConnectToServerConsole, pConnectToConsole); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_ConnectToServerConsole(VARIANT_BOOL * pConnectToConsole) const + { + return Outer()->GetProperty(Outer()->m_ConnectToServerConsole, pConnectToConsole); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapPersistence(long pbitmapPersistence) + { + return put_BitmapPeristence(pbitmapPersistence); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapPersistence(long * pbitmapPersistence) const + { + return get_BitmapPeristence(pbitmapPersistence); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_MinutesToIdleTimeout(long pminutesToIdleTimeout) + { + if(pminutesToIdleTimeout > 240) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_MinutesToIdleTimeout, pminutesToIdleTimeout); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_MinutesToIdleTimeout(long * pminutesToIdleTimeout) const + { + return Outer()->GetProperty(Outer()->m_MinutesToIdleTimeout, pminutesToIdleTimeout); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_SmartSizing(VARIANT_BOOL pfSmartSizing) + { + return Outer()->SetProperty(Outer()->m_SmartSizing, pfSmartSizing); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_SmartSizing(VARIANT_BOOL * pfSmartSizing) const + { + return Outer()->GetProperty(Outer()->m_SmartSizing, pfSmartSizing); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RdpdrLocalPrintingDocName(BSTR pLocalPrintingDocName) + { + return Outer()->SetProperty(Outer()->m_RdpdrLocalPrintingDocName, pLocalPrintingDocName); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RdpdrLocalPrintingDocName(BSTR * pLocalPrintingDocName) const + { + return Outer()->GetProperty(Outer()->m_RdpdrLocalPrintingDocName, pLocalPrintingDocName); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RdpdrClipCleanTempDirString(BSTR clipCleanTempDirString) + { + return Outer()->SetProperty(Outer()->m_RdpdrClipCleanTempDirString, clipCleanTempDirString); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RdpdrClipCleanTempDirString(BSTR * clipCleanTempDirString) const + { + return Outer()->GetProperty(Outer()->m_RdpdrClipCleanTempDirString, clipCleanTempDirString); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RdpdrClipPasteInfoString(BSTR clipPasteInfoString) + { + return Outer()->SetProperty(Outer()->m_RdpdrClipPasteInfoString, clipPasteInfoString); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RdpdrClipPasteInfoString(BSTR * clipPasteInfoString) const + { + return Outer()->GetProperty(Outer()->m_RdpdrClipPasteInfoString, clipPasteInfoString); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ClearTextPassword(BSTR rhs) + { + return Outer()->put_ClearTextPassword(rhs); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_DisplayConnectionBar(VARIANT_BOOL pDisplayConnectionBar) + { + if(!pDisplayConnectionBar && Outer()->IsSafeForScripting()) + return E_FAIL; + + return Outer()->SetProperty(Outer()->m_DisplayConnectionBar, pDisplayConnectionBar); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_DisplayConnectionBar(VARIANT_BOOL * pDisplayConnectionBar) const + { + return Outer()->GetProperty(Outer()->m_DisplayConnectionBar, pDisplayConnectionBar); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_PinConnectionBar(VARIANT_BOOL pPinConnectionBar) + { + if(Outer()->IsSafeForScripting()) + return E_NOTIMPL; + + return Outer()->SetProperty(Outer()->m_PinConnectionBar, pPinConnectionBar); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_PinConnectionBar(VARIANT_BOOL * pPinConnectionBar) const + { + return Outer()->GetProperty(Outer()->m_PinConnectionBar, pPinConnectionBar); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_GrabFocusOnConnect(VARIANT_BOOL pfGrabFocusOnConnect) + { + return Outer()->SetProperty(Outer()->m_GrabFocusOnConnect, pfGrabFocusOnConnect); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_GrabFocusOnConnect(VARIANT_BOOL * pfGrabFocusOnConnect) const + { + return Outer()->GetProperty(Outer()->m_GrabFocusOnConnect, pfGrabFocusOnConnect); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_LoadBalanceInfo(BSTR pLBInfo) + { + return Outer()->SetProperty(Outer()->m_LoadBalanceInfo, pLBInfo); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_LoadBalanceInfo(BSTR * pLBInfo) const + { + return Outer()->GetProperty(Outer()->m_LoadBalanceInfo, pLBInfo); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RedirectDrives(VARIANT_BOOL pRedirectDrives) + { + return Outer()->SetProperty(Outer()->m_RedirectDrives, pRedirectDrives); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RedirectDrives(VARIANT_BOOL * pRedirectDrives) const + { + return Outer()->GetProperty(Outer()->m_RedirectDrives, pRedirectDrives); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RedirectPrinters(VARIANT_BOOL pRedirectPrinters) + { + return Outer()->SetProperty(Outer()->m_RedirectPrinters, pRedirectPrinters); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RedirectPrinters(VARIANT_BOOL * pRedirectPrinters) const + { + return Outer()->GetProperty(Outer()->m_RedirectPrinters, pRedirectPrinters); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RedirectPorts(VARIANT_BOOL pRedirectPorts) + { + return Outer()->SetProperty(Outer()->m_RedirectPorts, pRedirectPorts); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RedirectPorts(VARIANT_BOOL * pRedirectPorts) const + { + return Outer()->GetProperty(Outer()->m_RedirectPorts, pRedirectPorts); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_RedirectSmartCards(VARIANT_BOOL pRedirectSmartCards) + { + return Outer()->SetProperty(Outer()->m_RedirectSmartCards, pRedirectSmartCards); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_RedirectSmartCards(VARIANT_BOOL * pRedirectSmartCards) const + { + return Outer()->GetProperty(Outer()->m_RedirectSmartCards, pRedirectSmartCards); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapVirtualCache16BppSize(long pBitmapVirtualCache16BppSize) + { + if(pBitmapVirtualCache16BppSize < 0 || pBitmapVirtualCache16BppSize > 32) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_BitmapVirtualCache16BppSize, pBitmapVirtualCache16BppSize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapVirtualCache16BppSize(long * pBitmapVirtualCache16BppSize) const + { + return Outer()->GetProperty(Outer()->m_BitmapVirtualCache16BppSize, pBitmapVirtualCache16BppSize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_BitmapVirtualCache24BppSize(long pBitmapVirtualCache24BppSize) + { + if(pBitmapVirtualCache24BppSize < 0 || pBitmapVirtualCache24BppSize > 32) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_BitmapVirtualCache24BppSize, pBitmapVirtualCache24BppSize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_BitmapVirtualCache24BppSize(long * pBitmapVirtualCache24BppSize) const + { + return Outer()->GetProperty(Outer()->m_BitmapVirtualCache24BppSize, pBitmapVirtualCache24BppSize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_PerformanceFlags(long pDisableList) + { + return Outer()->SetProperty(Outer()->m_PerformanceFlags, pDisableList); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_PerformanceFlags(long * pDisableList) const + { + return Outer()->GetProperty(Outer()->m_PerformanceFlags, pDisableList); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_ConnectWithEndpoint(VARIANT * rhs) + { + // TBD? the Microsoft client implements this, but what does it mean? + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::put_NotifyTSPublicKey(VARIANT_BOOL pfNotify) + { + return Outer()->SetProperty(Outer()->m_NotifyTSPublicKey, pfNotify); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings::get_NotifyTSPublicKey(VARIANT_BOOL * pfNotify) const + { + return Outer()->GetProperty(Outer()->m_NotifyTSPublicKey, pfNotify); + } + + /* IMsRdpClientAdvancedSettings2 */ + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::get_CanAutoReconnect(VARIANT_BOOL * pfCanAutoReconnect) const + { + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::put_EnableAutoReconnect(VARIANT_BOOL pfEnableAutoReconnect) + { + return Outer()->SetProperty(Outer()->m_EnableAutoReconnect, pfEnableAutoReconnect); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::get_EnableAutoReconnect(VARIANT_BOOL * pfEnableAutoReconnect) const + { + return Outer()->GetProperty(Outer()->m_EnableAutoReconnect, pfEnableAutoReconnect); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::put_MaxReconnectAttempts(long pMaxReconnectAttempts) + { + if(pMaxReconnectAttempts < 0 || pMaxReconnectAttempts > 200) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_MaxReconnectAttempts, pMaxReconnectAttempts); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings2::get_MaxReconnectAttempts(long * pMaxReconnectAttempts) const + { + return Outer()->GetProperty(Outer()->m_MaxReconnectAttempts, pMaxReconnectAttempts); + } + + /* IMsRdpClientAdvancedSettings3 */ + virtual STDMETHODIMP IMsRdpClientAdvancedSettings3::put_ConnectionBarShowMinimizeButton(VARIANT_BOOL pfShowMinimize) + { + return Outer()->SetProperty(Outer()->m_ConnectionBarShowMinimizeButton, pfShowMinimize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings3::get_ConnectionBarShowMinimizeButton(VARIANT_BOOL * pfShowMinimize) const + { + return Outer()->GetProperty(Outer()->m_ConnectionBarShowMinimizeButton, pfShowMinimize); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings3::put_ConnectionBarShowRestoreButton(VARIANT_BOOL pfShowRestore) + { + return Outer()->SetProperty(Outer()->m_ConnectionBarShowRestoreButton, pfShowRestore); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings3::get_ConnectionBarShowRestoreButton(VARIANT_BOOL * pfShowRestore) const + { + return Outer()->GetProperty(Outer()->m_ConnectionBarShowRestoreButton, pfShowRestore); + } + + /* IMsRdpClientAdvancedSettings4 */ + virtual STDMETHODIMP IMsRdpClientAdvancedSettings4::put_AuthenticationLevel(unsigned int puiAuthLevel) + { + // TODO: this isn't implemented in rdesktop yet... + return Outer()->SetProperty(Outer()->m_AuthenticationLevel, puiAuthLevel); + } + + virtual STDMETHODIMP IMsRdpClientAdvancedSettings4::get_AuthenticationLevel(unsigned int * puiAuthLevel) const + { + return Outer()->GetProperty(Outer()->m_AuthenticationLevel, puiAuthLevel); + } + } + m_advancedSettings; + + template HRESULT GetAdvancedSettings(Interface ** ppAdvSettings) + { + addRef(); + *ppAdvSettings = &m_advancedSettings; + return S_OK; + } + + /* Secured settings wrapper */ + friend class SecuredSettings; + + class SecuredSettings SEALED_: public MSTSCLib::IMsRdpClientSecuredSettings + { + private: + RdpClient * Outer() + { + return InnerToOuter(this); + } + + const RdpClient * Outer() const + { + return InnerToOuter(this); + } + + /* IDispatch type information */ + ITypeInfo * m_dispTypeInfo; + + HRESULT LoadDispTypeInfo() + { + if(m_dispTypeInfo) + return S_OK; + + HRESULT hr = Outer()->LoadTypeLibrary(); + + if(FAILED(hr)) + return hr; + + assert(MSTSCLib::IID_IMsRdpClientSecuredSettings == MSTSCLib_Redist::IID_IMsRdpClientSecuredSettings); + + hr = Outer()->m_typeLib->GetTypeInfoOfGuid(MSTSCLib::IID_IMsRdpClientSecuredSettings, &m_dispTypeInfo); + + if(FAILED(hr)) + return hr; + + assert(m_dispTypeInfo); + return S_OK; + } + + HRESULT AcquireDispTypeInfo(ITypeInfo ** ppTI) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + m_dispTypeInfo->AddRef(); + *ppTI = m_dispTypeInfo; + return S_OK; + } + + public: + ~SecuredSettings() + { + if(m_dispTypeInfo) + m_dispTypeInfo->Release(); + } + + /* IUnknown */ + virtual STDMETHODIMP IUnknown::QueryInterface(REFIID riid, void ** ppvObject) + { + using namespace MSTSCLib; + + if + ( + riid == IID_IUnknown || + riid == IID_IDispatch || + riid == IID_IMsTscSecuredSettings || + riid == IID_IMsRdpClientSecuredSettings + ) + { + *ppvObject = this; + Outer()->addRef(); + return S_OK; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + } + + virtual STDMETHODIMP_(ULONG) IUnknown::AddRef() + { + return Outer()->addRef(); + } + + virtual STDMETHODIMP_(ULONG) IUnknown::Release() + { + return Outer()->release(); + } + + /* IDispatch */ + virtual STDMETHODIMP IDispatch::GetTypeInfoCount(UINT * pctinfo) + { + *pctinfo = 1; + return S_OK; + } + + virtual STDMETHODIMP IDispatch::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) + { + if(iTInfo != 0) + return DISP_E_BADINDEX; + + return AcquireDispTypeInfo(ppTInfo); + } + + virtual STDMETHODIMP IDispatch::GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + return m_dispTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId); + } + + virtual STDMETHODIMP IDispatch::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) + { + return m_dispTypeInfo->Invoke + ( + static_cast(this), + dispIdMember, + wFlags, + pDispParams, + pVarResult, + pExcepInfo, + puArgErr + ); + } + + /* IMsTscSecuredSettings */ + virtual STDMETHODIMP IMsTscSecuredSettings::put_StartProgram(BSTR pStartProgram) + { + return Outer()->SetProperty(Outer()->m_StartProgram, pStartProgram); + } + + virtual STDMETHODIMP IMsTscSecuredSettings::get_StartProgram(BSTR * pStartProgram) const + { + return Outer()->GetProperty(Outer()->m_StartProgram, pStartProgram); + } + + virtual STDMETHODIMP IMsTscSecuredSettings::put_WorkDir(BSTR pWorkDir) + { + return Outer()->SetProperty(Outer()->m_WorkDir, pWorkDir); + } + + virtual STDMETHODIMP IMsTscSecuredSettings::get_WorkDir(BSTR * pWorkDir) const + { + return Outer()->GetProperty(Outer()->m_WorkDir, pWorkDir); + } + + virtual STDMETHODIMP IMsTscSecuredSettings::put_FullScreen(long pfFullScreen) + { + return Outer()->put_FullScreen(!!pfFullScreen); + } + + virtual STDMETHODIMP IMsTscSecuredSettings::get_FullScreen(long * pfFullScreen) const + { + return Outer()->GetProperty(Outer()->m_FullScreen, pfFullScreen); + } + + /* IMsRdpClientSecuredSettings */ + virtual STDMETHODIMP IMsRdpClientSecuredSettings::put_KeyboardHookMode(long pkeyboardHookMode) + { + if(pkeyboardHookMode < 0 || pkeyboardHookMode > 2) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_KeyboardHookMode, pkeyboardHookMode); + } + + virtual STDMETHODIMP IMsRdpClientSecuredSettings::get_KeyboardHookMode(long * pkeyboardHookMode) const + { + return Outer()->GetProperty(Outer()->m_KeyboardHookMode, pkeyboardHookMode); + } + + virtual STDMETHODIMP IMsRdpClientSecuredSettings::put_AudioRedirectionMode(long pAudioRedirectionMode) + { + if(pAudioRedirectionMode < 0 || pAudioRedirectionMode > 2) + return E_INVALIDARG; + + return Outer()->SetProperty(Outer()->m_AudioRedirectionMode, pAudioRedirectionMode); + } + + virtual STDMETHODIMP IMsRdpClientSecuredSettings::get_AudioRedirectionMode(long * pAudioRedirectionMode) const + { + return Outer()->GetProperty(Outer()->m_AudioRedirectionMode, pAudioRedirectionMode); + } + } + m_securedSettings; + + template HRESULT GetSecuredSettings(Interface ** ppSecuredSettings) + { + if(!m_SecuredSettingsEnabled) + return E_FAIL; + + addRef(); + *ppSecuredSettings = &m_securedSettings; + return S_OK; + } + + /* Type library loading */ + HRESULT LoadTypeLibrary() + { + if(m_typeLib) + return S_OK; + + // Get the DLL name of the ActiveX control + WCHAR szPath[MAX_PATH + 1]; + DWORD cchPathLen = GetModuleFileNameW(GetCurrentModule(), szPath, ARRAYSIZE(szPath) - 1); + + if(cchPathLen == 0) + return HRESULT_FROM_WIN32(GetLastError()); + + if(cchPathLen > ((ARRAYSIZE(szPath) - 1) - 2)) + return E_FAIL; + + // Append the resource id of the type library + assert(m_typeLibIndex < 10); + + szPath[cchPathLen + 0] = L'\\'; + szPath[cchPathLen + 1] = static_cast(L'0' + m_typeLibIndex); + szPath[cchPathLen + 2] = 0; + + // Load the type library + HRESULT hr = LoadTypeLibEx(szPath, REGKIND_NONE, &m_typeLib); + + if(FAILED(hr)) + return hr; + + assert(m_typeLib); + return S_OK; + } + + /* IDispatch type information */ + HRESULT LoadDispTypeInfo() + { + if(m_dispTypeInfo) + return S_OK; + + HRESULT hr = LoadTypeLibrary(); + + if(FAILED(hr)) + return hr; + + assert(MSTSCLib::IID_IMsRdpClient4 == MSTSCLib_Redist::IID_IMsRdpClient4); + + hr = m_typeLib->GetTypeInfoOfGuid(MSTSCLib::IID_IMsRdpClient4, &m_dispTypeInfo); + + if(FAILED(hr)) + return hr; + + assert(m_dispTypeInfo); + return S_OK; + } + + HRESULT AcquireDispTypeInfo(ITypeInfo ** ppTI) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + m_dispTypeInfo->AddRef(); + *ppTI = m_dispTypeInfo; + return S_OK; + } + +public: + /* Helpers for our various embedded children */ + static RdpClient * InnerToOuter(RdpClientInner * innerThis) + { + return CONTAINING_RECORD(innerThis, RdpClient, m_inner); + } + + static RdpClient * InnerToOuter(AdvancedSettings * innerThis) + { + return CONTAINING_RECORD(innerThis, RdpClient, m_advancedSettings); + } + + static RdpClient * InnerToOuter(SecuredSettings * innerThis) + { + return CONTAINING_RECORD(innerThis, RdpClient, m_securedSettings); + } + + static RdpClient * InnerToOuter(RDPCLIENT * innerThis) + { + return CONTAINING_RECORD(innerThis, RdpClient, m_protocolState); + } + + static const RdpClient * InnerToOuter(const RdpClientInner * innerThis) + { + return CONTAINING_RECORD(innerThis, RdpClient, m_inner); + } + + static const RdpClient * InnerToOuter(const AdvancedSettings * innerThis) + { + return CONTAINING_RECORD(innerThis, RdpClient, m_advancedSettings); + } + + static const RdpClient * InnerToOuter(const SecuredSettings * innerThis) + { + return CONTAINING_RECORD(innerThis, RdpClient, m_securedSettings); + } + + static const RdpClient * InnerToOuter(const RDPCLIENT * innerThis) + { + return CONTAINING_RECORD(innerThis, RdpClient, m_protocolState); + } + + RdpClientUI * GetUI() const + { + assert(m_clientUI); + return m_clientUI; + } + + /* Glue for rdesktop-core */ +public: + static bool OnPublicKey(RDPCLIENT * This, unsigned char * key, unsigned int key_size) + { + return InnerToOuter(This)->OnPublicKey(key, key_size); + } + + static void OnLogon(RDPCLIENT * This) + { + return InnerToOuter(This)->OnLogon(); + } + + static bool OnRedirect + ( + RDPCLIENT * This, + uint32 flags, + uint32 server_len, + wchar_t * server, + uint32 cookie_len, + char * cookie, + uint32 username_len, + wchar_t * username, + uint32 domain_len, + wchar_t * domain, + uint32 password_len, + wchar_t * password + ) + { + return InnerToOuter(This)->OnRedirect + ( + flags, + server_len, + server, + cookie_len, + cookie, + username_len, + username, + domain_len, + domain, + password_len, + password + ); + } + +private: + bool OnPublicKey(unsigned char * key, unsigned int key_size) + { + HRESULT hr = FireReceivedTSPublicKey(key, key_size); + + if(FAILED(hr)) + { + m_protocolState.disconnect_reason = 262; + return false; + } + + return hr == S_OK; + } + + void OnLogon() + { + m_loggedIn = true; + FireLoginComplete(); + } + + bool OnRedirect + ( + uint32 flags, + uint32 server_len, + wchar_t * server, + uint32 cookie_len, + char * cookie, + uint32 username_len, + wchar_t * username, + uint32 domain_len, + wchar_t * domain, + uint32 password_len, + wchar_t * password + ) + { + assert(m_Connected); + assert(!InsideApartment()); + assert(IsWindow(m_controlWindow)); + + RedirectArguments redirectArgs = + { + flags, + server_len, + server, + cookie_len, + cookie, + username_len, + username, + domain_len, + domain, + password_len, + password + }; + + return SendMessage(m_controlWindow, RDPC_WM_REDIRECT, 0, reinterpret_cast(&redirectArgs)) == 0; + } + +private: + static DWORD WINAPI ProtocolLoopThreadProc(LPVOID lpParam) + { + static_cast(lpParam)->ProtocolLoop(); + return 0; + } + + static VOID CALLBACK ConnectionTimerAPC(LPVOID, DWORD, DWORD) + { + } + + // FIXME: various potential inconsistencies due to lack of detailed documentation of expected semantics + void ProtocolLoop() + { + HANDLE waitingReconnection = NULL; + + // Retrieve the local hostname to be passed to the server + WCHAR hostname[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD hostnameLen = ARRAYSIZE(hostname); + + if(!GetComputerNameW(hostname, &hostnameLen)) + hostname[0] = 0; + + // Set some connection flags + uint32 flags = RDP_LOGON_NORMAL; + + if(m_Compress) + flags |= RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2; + + if(m_AudioRedirectionMode == 1) + flags |= RDP_LOGON_LEAVE_AUDIO; + + if(m_ClearTextPassword) + flags |= RDP_LOGON_AUTO; + + // Notify the container that the connection process is beginning now + FireConnecting(); + + // Set the overall connection timer, if a timeout is set + // BUGBUG: the timeout semantics are ambiguous and have been most probably misinterpreted + HANDLE overallConnectionTimer = NULL; + LARGE_INTEGER overallTimeout; + + if(m_overallConnectionTimeout) + { + overallTimeout.QuadPart = - ((m_overallConnectionTimeout * 1000 * 1000 * 1000) / 100); + + overallConnectionTimer = CreateWaitableTimer(NULL, FALSE, NULL); + + if(overallConnectionTimer == NULL) + goto l_Disconnect; + } + + if(overallConnectionTimer) + SetWaitableTimer(overallConnectionTimer, &overallTimeout, 0, ConnectionTimerAPC, NULL, FALSE); + + // Initial connection + BOOL disconnected = rdp_connect + ( + &m_protocolState, + m_Server, + flags, + m_UserName, + m_Domain, + m_ClearTextPassword, + m_StartProgram, + m_WorkDir, + hostname, + m_LoadBalanceInfo + ); + + if(overallConnectionTimer) + CancelWaitableTimer(overallConnectionTimer); + + if(disconnected) + goto l_Disconnect; + + // TODO: set the disconnect reason for every instance in which we abort the loop + for(;;) + { + BOOL deactivated = False; + uint32 extendedDisconnectReason = 0; + + m_actuallyConnected = true; + + // Notify the container of the successful connection + FireConnected(); + + // Main protocol loop + m_loggedIn = false; + rdp_main_loop(&m_protocolState, &deactivated, &extendedDisconnectReason); + rdp_disconnect(&m_protocolState); + + m_actuallyConnected = false; + + // Redirection + // BUGBUG: redirection is very messy and probably this implementation is not "canonical" + if(m_protocolState.redirect) + { + m_protocolState.redirect = False; + rdp_reset_state(&m_protocolState); + + // TODO: reset connection parameters + // This has to be done in the main thread, so use SendMessage on the control window + + flags |= RDP_LOGON_AUTO; + + // retry + continue; + } + + // Disconnection + m_ExtendedDisconnectReason = static_cast(extendedDisconnectReason); + + // Clean disconnection + if(deactivated) + break; + + BOOL success; + + long autoReconnections = 0; + long totalReconnections = 0; + + // Reconnection + // BUGBUG: reconnection semantics may not be entirely accurate + do + { + ++ totalReconnections; + + // ask the container whether we should reconnect + long reconnectMode = FireAutoReconnecting(m_protocolState.disconnect_reason, totalReconnections); + + // do not reconnect + if(reconnectMode == MSTSCLib::autoReconnectContinueStop) + goto l_Disconnect; + + // the container will reconnect or abort manually + if(reconnectMode == MSTSCLib::autoReconnectContinueManual) + { + assert(!m_reconnectAborted); + assert(m_protocolThreadWaitingReconnection == NULL); + + if(waitingReconnection == NULL) + { + waitingReconnection = CreateEvent(NULL, TRUE, FALSE, NULL); + + if(waitingReconnection == NULL) + // TODO: fatal error + goto l_Disconnect; + } + + m_protocolThreadWaitingReconnection = waitingReconnection; + + WaitForSingleObject(waitingReconnection, INFINITE); + + m_protocolThreadWaitingReconnection = NULL; + + if(m_reconnectAborted) + { + // FIXME? do we set the disconnection status here? + goto l_Disconnect; + } + } + // reconnect automatically + else + { + // automatic reconnection is disabled + if(m_EnableAutoReconnect) + break; + + // too many consecutive automatic reconnections + if(autoReconnections == m_MaxReconnectAttempts) + break; + + ++ autoReconnections; + } + + if(overallConnectionTimer) + SetWaitableTimer(overallConnectionTimer, &overallTimeout, 0, ConnectionTimerAPC, NULL, FALSE); + + // Reconnection + success = rdp_reconnect + ( + &m_protocolState, + m_Server, + flags, + m_UserName, + m_Domain, + m_ClearTextPassword, + m_StartProgram, + m_WorkDir, + hostname, + m_LoadBalanceInfo + ); + + if(overallConnectionTimer) + CancelWaitableTimer(overallConnectionTimer); + } + while(!success); + } + +l_Disconnect: + // Disconnected + FireDisconnected(m_protocolState.disconnect_reason); + + if(overallConnectionTimer) + CloseHandle(overallConnectionTimer); + } + + void JoinProtocolThread() + { + assert(m_protocolThread); + WaitForSingleObject(m_protocolThread, INFINITE); + CloseHandle(m_protocolThread); + m_protocolThread = NULL; + } + + void TerminateProtocolThread() + { + assert(m_protocolThread); + + // wake it up if it's waiting for a manual reconnection + if(m_protocolThreadWaitingReconnection) + { + assert(!m_reconnectAborted); + m_reconnectAborted = true; + SetEvent(m_protocolThreadWaitingReconnection); + } + // otherwise, attempt to interrupt any current blocking operation + else + { + // shutdown(m_protocolState.tcp.sock, SD_BOTH); // TBD: maybe in the future? + QueueUserAPC(DisconnectAPC, m_protocolThread, 0); + } + + assert(m_protocolThreadWaitingReconnection == NULL); + } + + void PerformDisconnect(long reason) + { + assert(InsideApartment()); + assert(m_Connected); + + // TODO: notify virtual channels + + // TODO: do any other disconnection work here... + + // Put the control in the disconnected state + m_Connected = false; + m_loggedIn = false; + + // Notify the container + VARIANTARG arg = { }; + + arg.vt = VT_I4; + arg.lVal = reason; + + FireEventInsideApartment(4, &arg, 1); + } + +public: + /* Startup initialization */ + static BOOL Startup() + { + if(!RdpClientUI::Startup()) + return FALSE; + + WNDCLASSEX wcex = { sizeof(wcex) }; + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = ControlWindowProc; + wcex.hInstance = GetCurrentModule(); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wcex.lpszClassName = TEXT("MissTosca_Control"); + + return RegisterClassEx(&wcex); + } + + static void Shutdown() + { + UnregisterClass(TEXT("MissTosca_Control"), GetCurrentModule()); + } + + /* Class factory */ + static HRESULT CreateInstance(REFCLSID rclsid, unsigned libIndex, IUnknown * punkOuter, REFIID riid, void ** ppObj) + { + RdpClient * obj = new RdpClient(rclsid, libIndex, punkOuter); + + if(obj == NULL) + return E_OUTOFMEMORY; + + HRESULT hr = obj->m_inner.QueryInterface(riid, ppObj); + + if(FAILED(hr)) + { + delete obj; + return hr; + } + + assert(obj->m_refCount == 1); + assert(*ppObj != NULL); + + return S_OK; + } + +private: + /* Connection point enumerator */ + class CEnumConnectionPoints: public IEnumConnectionPoints + { + private: + LONG m_refCount; + IConnectionPoint * m_cp; + bool m_done; + + public: + CEnumConnectionPoints(IConnectionPoint * cp): m_refCount(1), m_cp(cp), m_done(false) + { + assert(m_cp); + m_cp->AddRef(); + } + + CEnumConnectionPoints(const CEnumConnectionPoints& ecp): m_refCount(1), m_cp(ecp.m_cp), m_done(ecp.m_done) + { + assert(m_cp); + m_cp->AddRef(); + } + + ~CEnumConnectionPoints() + { + assert(m_cp); + m_cp->Release(); + } + + virtual STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObject) + { + if(riid == IID_IUnknown || riid == IID_IEnumConnectionPoints) + { + *ppvObject = this; + return S_OK; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + } + + virtual STDMETHODIMP_(ULONG) AddRef() + { + return InterlockedIncrement(&m_refCount); + } + + virtual STDMETHODIMP_(ULONG) Release() + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + virtual STDMETHODIMP Next(ULONG cConnections, LPCONNECTIONPOINT * ppCP, ULONG * pcFetched) + { + if(cConnections == 0 || m_done) + return S_FALSE; + + m_done = true; + m_cp->AddRef(); + *ppCP = m_cp; + *pcFetched = 1; + + return S_OK; + } + + virtual STDMETHODIMP Skip(ULONG cConnections) + { + if(cConnections == 0) + return S_OK; + + if(cConnections == 1 && !m_done) + { + m_done = true; + return S_OK; + } + + assert(cConnections > 1 || m_done); + + return S_FALSE; + } + + virtual STDMETHODIMP Reset() + { + m_done = false; + return S_OK; + } + + virtual STDMETHODIMP Clone(IEnumConnectionPoints ** ppEnum) + { + if(ppEnum == NULL) + return E_POINTER; + + *ppEnum = new CEnumConnectionPoints(*this); + + if(*ppEnum == NULL) + return E_OUTOFMEMORY; + + return S_OK; + } + }; + + /* Pay no attention, ActiveX glue... */ + LRESULT ControlWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch(uMsg) + { + case WM_SIZE: + { + // TODO: resize UI + } + + return 0; + + case WM_PAINT: + { + LPCWSTR text = NULL; + + if(!m_Connected) + text = m_DisconnectedText; + else if(m_actuallyConnected) + text = m_ConnectedStatusText; + else + text = m_ConnectingText; + + RECT clientRect; + GetClientRect(m_controlWindow, &clientRect); + + PAINTSTRUCT ps; + HDC hdc = BeginPaint(m_controlWindow, &ps); + + SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); + SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); + SelectObject(hdc, GetStockObject(SYSTEM_FONT)); + + RECT textRect = clientRect; + + DrawTextW + ( + hdc, + text, + -1, + &textRect, + DT_CENTER | DT_EDITCONTROL | DT_END_ELLIPSIS | DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT + ); + + if(textRect.right > clientRect.right) + textRect.right = clientRect.right; + + if(textRect.bottom > clientRect.bottom) + textRect.bottom = clientRect.bottom; + + textRect.left = (clientRect.right - textRect.right) / 2; + textRect.right += textRect.left; + textRect.top = (clientRect.bottom - textRect.bottom) / 2; + textRect.bottom += textRect.top; + + DrawTextW + ( + hdc, + text, + -1, + &textRect, + DT_CENTER | DT_EDITCONTROL | DT_END_ELLIPSIS | DT_NOPREFIX | DT_WORDBREAK + ); + + EndPaint(m_controlWindow, &ps); + } + + return 0; + + default: + { + LRESULT result; + + if(HandleEvent(uMsg, wParam, lParam, result)) + return result; + } + + break; + } + + return DefWindowProc(m_controlWindow, uMsg, wParam, lParam); + } + + static LRESULT CALLBACK ControlWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + if(uMsg == WM_CREATE) + { + SetWindowLongPtr + ( + hwnd, + GWLP_USERDATA, + (LONG_PTR)reinterpret_cast(lParam)->lpCreateParams + ); + } + + RdpClient * Self = reinterpret_cast(GetWindowLongPtr(hwnd, GWLP_USERDATA)); + assert(Self); + + return Self->ControlWindowProc(uMsg, wParam, lParam); + } + + HRESULT CreateControlWindow(HWND hwndParent) + { + m_controlWindow = CreateWindow + ( + TEXT("MissTosca_Control"), + NULL, + WS_CHILD | WS_CLIPCHILDREN, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + hwndParent, + NULL, + GetCurrentModule(), + this + ); + + if(m_controlWindow == NULL) + return HRESULT_FROM_WIN32(GetLastError()); + + m_UIParentWindowHandle = m_controlWindow; + return S_OK; + } + + HRESULT DestroyControlWindow() + { + if(m_controlWindow == NULL) + return S_FALSE; + + HWND controlWindow = NULL; + std::swap(controlWindow, m_controlWindow); + DestroyWindow(controlWindow); + return S_OK; + } + + HRESULT Activate(LONG iVerb, IOleClientSite * pActiveSite, HWND hwndParent, LPCRECT lprcPosRect) + { + if(pActiveSite == NULL) + pActiveSite = m_clientSite; + + if(pActiveSite == NULL) + return E_FAIL; + + // TODO: store this until we are closed or deactivated + IOleInPlaceSite * site; + + HRESULT hr = pActiveSite->QueryInterface(&site); + + if(FAILED(hr)) + return hr; + + IOleInPlaceFrame * frame = NULL; + IOleInPlaceUIWindow * uiWindow = NULL; + + for(;;) + { + hr = site->CanInPlaceActivate(); + + if(hr == S_FALSE) + hr = E_FAIL; + + if(FAILED(hr)) + break; + + site->OnInPlaceActivate(); + + if(hwndParent == NULL) + { + hr = site->GetWindow(&hwndParent); + + if(FAILED(hr)) + break; + } + + RECT rcPos; + RECT rcClip; + OLEINPLACEFRAMEINFO frameInfo = { sizeof(frameInfo) }; + + site->GetWindowContext(&frame, &uiWindow, &rcPos, &rcClip, &frameInfo); + + if(lprcPosRect == NULL) + lprcPosRect = &rcPos; + + if(m_controlWindow) + ShowWindow(m_controlWindow, SW_SHOW); + else + { + hr = CreateControlWindow(hwndParent); + + if(FAILED(hr)) + break; + } + + SetObjectRects(lprcPosRect, &rcClip); + + // UI activation + if((iVerb == OLEIVERB_PRIMARY || iVerb == OLEIVERB_UIACTIVATE) && !m_uiActive) + { + m_uiActive = true; + + hr = site->OnUIActivate(); + + if(FAILED(hr)) + break; + + SetWindowPos + ( + m_controlWindow, + NULL, + lprcPosRect->left, + lprcPosRect->top, + lprcPosRect->right - lprcPosRect->left, + lprcPosRect->bottom - lprcPosRect->top, + SWP_SHOWWINDOW + ); + + if(frame) + { + frame->SetActiveObject(this, NULL); + frame->SetBorderSpace(NULL); + } + + if(uiWindow) + { + uiWindow->SetActiveObject(this, NULL); + uiWindow->SetBorderSpace(NULL); + } + } + + break; + } + + if(uiWindow) + uiWindow->Release(); + + if(frame) + frame->Release(); + + site->Release(); + + if(SUCCEEDED(hr)) + pActiveSite->ShowObject(); + + return hr; + } + +public: + /* IUnknown */ + /* + NOTE: this is the delegating implementation, to support aggregation. The actual + implementation is RdpClientInner, above + */ + virtual STDMETHODIMP IUnknown::QueryInterface(REFIID riid, void ** ppvObject) + { + return m_punkOuter->QueryInterface(riid, ppvObject); + } + + virtual STDMETHODIMP_(ULONG) IUnknown::AddRef() + { + return m_punkOuter->AddRef(); + } + + virtual STDMETHODIMP_(ULONG) IUnknown::Release() + { + return m_punkOuter->Release(); + } + + /* IDispatch */ + virtual STDMETHODIMP IDispatch::GetTypeInfoCount(UINT * pctinfo) + { + *pctinfo = 1; + return S_OK; + } + + virtual STDMETHODIMP IDispatch::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo ** ppTInfo) + { + if(iTInfo != 0) + return DISP_E_BADINDEX; + + return AcquireDispTypeInfo(ppTInfo); + } + + virtual STDMETHODIMP IDispatch::GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + return m_dispTypeInfo->GetIDsOfNames(rgszNames, cNames, rgDispId); + } + + virtual STDMETHODIMP IDispatch::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS * pDispParams, VARIANT * pVarResult, EXCEPINFO * pExcepInfo, UINT * puArgErr) + { + HRESULT hr = LoadDispTypeInfo(); + + if(FAILED(hr)) + return hr; + + return m_dispTypeInfo->Invoke + ( + static_cast(this), + dispIdMember, + wFlags, + pDispParams, + pVarResult, + pExcepInfo, + puArgErr + ); + } + + /* IConnectionPoint */ + virtual STDMETHODIMP GetConnectionInterface(IID * pIID) + { + if(pIID == NULL) + return E_POINTER; + + *pIID = MSTSCLib::DIID_IMsTscAxEvents; + return S_OK; + } + + virtual STDMETHODIMP GetConnectionPointContainer(IConnectionPointContainer ** ppCPC) + { + if(ppCPC == NULL) + return E_POINTER; + + addRef(); + *ppCPC = this; + return S_OK; + } + + virtual STDMETHODIMP Advise(IUnknown * pUnkSink, DWORD * pdwCookie) + { + MSTSCLib::IMsTscAxEvents * sink; + + if(FAILED(pUnkSink->QueryInterface(&sink))) + return CONNECT_E_CANNOTCONNECT; + + MSTSCLib::IMsTscAxEvents ** sinks = GetSinks(); + DWORD cookie = 0; + + if(m_EventSinksCount) + { + bool found = false; + + for(size_t i = 0; i < m_EventSinksCount; ++ i) + { + found = (sinks[i] == NULL); + + if(found) + { + cookie = static_cast(i); + break; + } + } + + if(!found) + { + MSTSCLib::IMsTscAxEvents ** newSinks = new MSTSCLib::IMsTscAxEvents *[m_EventSinksCount + 1]; + + if(newSinks == NULL) + { + sink->Release(); + return E_OUTOFMEMORY; + } + + std::copy(sinks, sinks + m_EventSinksCount, newSinks); + + m_EventSinks = newSinks; + sinks = newSinks; + + cookie = static_cast(m_EventSinksCount); + } + } + + sinks[cookie] = sink; + *pdwCookie = cookie; + + return S_OK; + } + + virtual STDMETHODIMP Unadvise(DWORD dwCookie) + { + MSTSCLib::IMsTscAxEvents ** sinks = GetSinks(); + + if(dwCookie >= m_EventSinksCount || sinks[dwCookie] == NULL) + return CONNECT_E_NOCONNECTION; + + sinks[dwCookie]->Release(); + sinks[dwCookie] = NULL; + + // BUGBUG: the array currently grows forever. Trim it whenever possible + + return S_OK; + } + + virtual STDMETHODIMP EnumConnections(IEnumConnections ** ppEnum) + { + // I see no real value in this + return E_NOTIMPL; + } + + /* IConnectionPointContainer */ + virtual STDMETHODIMP IConnectionPointContainer::EnumConnectionPoints(IEnumConnectionPoints ** ppEnum) + { + *ppEnum = new CEnumConnectionPoints(this); + + if(*ppEnum == NULL) + return E_OUTOFMEMORY; + + return S_OK; + } + + virtual STDMETHODIMP IConnectionPointContainer::FindConnectionPoint(REFIID riid, IConnectionPoint ** ppCP) + { + if(riid != MSTSCLib::DIID_IMsTscAxEvents) + return CONNECT_E_NOCONNECTION; + + addRef(); + *ppCP = this; + + return S_OK; + } + + /* IDataObject */ // 0/9 + virtual STDMETHODIMP IDataObject::GetData(FORMATETC * pformatetcIn, STGMEDIUM * pmedium) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IDataObject::GetDataHere(FORMATETC * pformatetc, STGMEDIUM * pmedium) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IDataObject::QueryGetData(FORMATETC * pformatetc) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IDataObject::GetCanonicalFormatEtc(FORMATETC * pformatectIn, FORMATETC * pformatetcOut) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IDataObject::SetData(FORMATETC * pformatetc, STGMEDIUM * pmedium, BOOL fRelease) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IDataObject::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC ** ppenumFormatEtc) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IDataObject::DAdvise(FORMATETC * pformatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IDataObject::DUnadvise(DWORD dwConnection) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IDataObject::EnumDAdvise(IEnumSTATDATA ** ppenumAdvise) + { + return E_NOTIMPL; + } + + /* IObjectSafety */ + virtual STDMETHODIMP IObjectSafety::GetInterfaceSafetyOptions(REFIID riid, DWORD * pdwSupportedOptions, DWORD * pdwEnabledOptions) + { + if(pdwSupportedOptions == NULL || pdwEnabledOptions == NULL) + return E_POINTER; + + if(riid != IID_IDispatch) + return E_NOINTERFACE; + + *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER; + *pdwEnabledOptions = m_SafetyOptions; + return S_OK; + } + + virtual STDMETHODIMP IObjectSafety::SetInterfaceSafetyOptions(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions) + { + if(riid != IID_IDispatch) + return E_NOINTERFACE; + + m_SafetyOptions = dwEnabledOptions & (dwOptionSetMask & INTERFACESAFE_FOR_UNTRUSTED_CALLER); + return S_OK; + } + + /* IOleControl */ // 3/4 + virtual STDMETHODIMP IOleControl::GetControlInfo(CONTROLINFO * pCI) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleControl::OnMnemonic(MSG * pMsg) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleControl::OnAmbientPropertyChange(DISPID dispID) + { + return S_OK; + } + + virtual STDMETHODIMP IOleControl::FreezeEvents(BOOL bFreeze) + { + if(bFreeze) + InterlockedIncrement(&m_freezeEvents); + else if(InterlockedDecrement(&m_freezeEvents) == 0) + UnfreezeEvents(); + + return S_OK; + } + + /* IOleInPlaceActiveObject */ // 3/5 + virtual STDMETHODIMP IOleInPlaceActiveObject::TranslateAccelerator(LPMSG lpmsg) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleInPlaceActiveObject::OnFrameWindowActivate(BOOL fActivate) + { + // TODO + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleInPlaceActiveObject::OnDocWindowActivate(BOOL fActivate) + { + // TODO + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleInPlaceActiveObject::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow * pUIWindow, BOOL fFrameWindow) + { + return S_OK; + } + + virtual STDMETHODIMP IOleInPlaceActiveObject::EnableModeless(BOOL fEnable) + { + return S_OK; + } + + /* IOleInPlaceObject */ // 1/4 + virtual STDMETHODIMP IOleInPlaceObject::InPlaceDeactivate() + { + // TODO: UIDeactivate, destroy window, inplacesite->OnInPlaceDeactivate + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleInPlaceObject::UIDeactivate() + { + // TODO + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleInPlaceObject::SetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect) + { + if(m_controlWindow == NULL) + return E_FAIL; + + MoveWindow + ( + m_controlWindow, + lprcPosRect->left, + lprcPosRect->top, + lprcPosRect->right - lprcPosRect->left, + lprcPosRect->bottom - lprcPosRect->top, + TRUE + ); + + SetWindowRgn(m_controlWindow, CreateRectRgnIndirect(lprcClipRect), TRUE); + + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleInPlaceObject::ReactivateAndUndo() + { + return E_NOTIMPL; + } + + /* IOleObject */ // 18/21 + virtual STDMETHODIMP IOleObject::SetClientSite(IOleClientSite * pClientSite) + { + if(m_clientSite) + m_clientSite->Release(); + + m_clientSite = pClientSite; + + if(m_clientSite) + m_clientSite->AddRef(); + + return S_OK; + } + + virtual STDMETHODIMP IOleObject::GetClientSite(IOleClientSite ** ppClientSite) + { + if(ppClientSite == NULL) + return E_POINTER; + + if(m_clientSite) + m_clientSite->AddRef(); + + *ppClientSite = m_clientSite; + return S_OK; + } + + virtual STDMETHODIMP IOleObject::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szContainerObj) + { + return S_OK; + } + + virtual STDMETHODIMP IOleObject::Close(DWORD dwSaveOption) + { + // TODO: deactivate, destroy window, release in-place site, release advise sink + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IOleObject::SetMoniker(DWORD dwWhichMoniker, IMoniker * pmk) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleObject::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleObject::InitFromData(IDataObject * pDataObject, BOOL fCreation, DWORD dwReserved) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleObject::GetClipboardData(DWORD dwReserved, IDataObject ** ppDataObject) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleObject::DoVerb(LONG iVerb, LPMSG lpmsg, IOleClientSite * pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect) + { + HRESULT hr; + + switch(iVerb) + { + case OLEIVERB_PRIMARY: + case OLEIVERB_SHOW: + case OLEIVERB_UIACTIVATE: + case OLEIVERB_INPLACEACTIVATE: + hr = S_OK; + break; + + default: + if(iVerb > 0) + hr = OLEOBJ_S_INVALIDVERB; + else + hr = E_NOTIMPL; + } + + if(FAILED(hr)) + return hr; + + HRESULT hrActivate = Activate(iVerb, pActiveSite, hwndParent, lprcPosRect); + + if(FAILED(hrActivate)) + hr = hrActivate; + + return hr; + } + + virtual STDMETHODIMP IOleObject::EnumVerbs(IEnumOLEVERB ** ppEnumOleVerb) + { + return OleRegEnumVerbs(m_classId, ppEnumOleVerb); + } + + virtual STDMETHODIMP IOleObject::Update() + { + return S_OK; + } + + virtual STDMETHODIMP IOleObject::IsUpToDate() + { + return S_OK; + } + + virtual STDMETHODIMP IOleObject::GetUserClassID(CLSID * pClsid) + { + *pClsid = m_classId; + return S_OK; + } + + virtual STDMETHODIMP IOleObject::GetUserType(DWORD dwFormOfType, LPOLESTR * pszUserType) + { + return OleRegGetUserType(m_classId, dwFormOfType, pszUserType); + } + + virtual STDMETHODIMP IOleObject::SetExtent(DWORD dwDrawAspect, SIZEL * psizel) + { + // TODO: resize + return E_NOTIMPL; + } + + virtual STDMETHODIMP IOleObject::GetExtent(DWORD dwDrawAspect, SIZEL * psizel) + { + // TODO: return size + return E_NOTIMPL; + } + + HRESULT NeedAdviseHolder() + { + if(m_adviseHolder) + return S_OK; + + return CreateOleAdviseHolder(&m_adviseHolder); + } + + virtual STDMETHODIMP IOleObject::Advise(IAdviseSink * pAdvSink, DWORD * pdwConnection) + { + HRESULT hr = NeedAdviseHolder(); + + if(FAILED(hr)) + return hr; + + return m_adviseHolder->Advise(pAdvSink, pdwConnection); + } + + virtual STDMETHODIMP IOleObject::Unadvise(DWORD dwConnection) + { + HRESULT hr = NeedAdviseHolder(); + + if(FAILED(hr)) + return hr; + + return m_adviseHolder->Unadvise(dwConnection); + } + + virtual STDMETHODIMP IOleObject::EnumAdvise(IEnumSTATDATA ** ppenumAdvise) + { + HRESULT hr = NeedAdviseHolder(); + + if(FAILED(hr)) + return hr; + + return m_adviseHolder->EnumAdvise(ppenumAdvise); + } + + virtual STDMETHODIMP IOleObject::GetMiscStatus(DWORD dwAspect, DWORD * pdwStatus) + { + return OleRegGetMiscStatus(m_classId, dwAspect, pdwStatus); + } + + virtual STDMETHODIMP IOleObject::SetColorScheme(LOGPALETTE * pLogpal) + { + return E_NOTIMPL; + } + + /* IOleWindow */ + virtual STDMETHODIMP IOleWindow::GetWindow(HWND * phwnd) + { + if(phwnd == NULL) + return E_POINTER; + + if(m_controlWindow == NULL) + return E_FAIL; + + *phwnd = m_controlWindow; + return S_OK; + } + + virtual STDMETHODIMP IOleWindow::ContextSensitiveHelp(BOOL fEnterMode) + { + return E_NOTIMPL; + } + + /* IPersist */ + virtual STDMETHODIMP IPersist::GetClassID(CLSID * pClassID) + { + *pClassID = m_classId; + return S_OK; + } + + /* IPersistPropertyBag */ // 0/3 + virtual STDMETHODIMP IPersistPropertyBag::InitNew() + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistPropertyBag::Load(IPropertyBag * pPropBag, IErrorLog * pErrorLog) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistPropertyBag::Save(IPropertyBag * pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties) + { + return E_NOTIMPL; + } + + /* IPersistStorage */ // 0/6 + virtual STDMETHODIMP IPersistStorage::IsDirty() + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStorage::InitNew(IStorage * pStg) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStorage::Load(IStorage * pStg) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStorage::Save(IStorage * pStgSave, BOOL fSameAsLoad) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStorage::SaveCompleted(IStorage * pStgNew) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStorage::HandsOffStorage() + { + return E_NOTIMPL; + } + + /* IPersistStreamInit */ // 0/5 + virtual STDMETHODIMP IPersistStreamInit::IsDirty() + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStreamInit::Load(LPSTREAM pStm) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStreamInit::Save(LPSTREAM pStm, BOOL fClearDirty) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStreamInit::GetSizeMax(ULARGE_INTEGER * pCbSize) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IPersistStreamInit::InitNew() + { + return E_NOTIMPL; + } + + /* IProvideClassInfo */ + virtual STDMETHODIMP IProvideClassInfo::GetClassInfo(ITypeInfo ** ppTI) + { + HRESULT hr = LoadTypeLibrary(); + + if(FAILED(hr)) + return hr; + + return m_typeLib->GetTypeInfoOfGuid(m_classId, ppTI); + } + + /* IProvideClassInfo2 */ + virtual STDMETHODIMP IProvideClassInfo2::GetGUID(DWORD dwGuidKind, GUID * pGUID) + { + if(dwGuidKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID) + return E_INVALIDARG; + + *pGUID = MSTSCLib::DIID_IMsTscAxEvents; + return S_OK; + } + + /* IQuickActivate */ + virtual STDMETHODIMP IQuickActivate::QuickActivate(QACONTAINER * pQaContainer, QACONTROL * pQaControl) + { + if(pQaContainer == NULL || pQaControl == NULL) + return E_POINTER; + + if(pQaContainer->cbSize < sizeof(*pQaContainer) || pQaControl->cbSize < sizeof(*pQaControl)) + return E_INVALIDARG; + + ULONG cb = pQaControl->cbSize; + ZeroMemory(pQaControl, cb); + pQaControl->cbSize = cb; + + SetClientSite(pQaContainer->pClientSite); + + if(pQaContainer->pAdviseSink) + SetAdvise(DVASPECT_CONTENT, 0, pQaContainer->pAdviseSink); + + if(pQaContainer->pUnkEventSink) + Advise(pQaContainer->pUnkEventSink, &pQaControl->dwEventCookie); + + GetMiscStatus(DVASPECT_CONTENT, &pQaControl->dwMiscStatus); + + return E_NOTIMPL; + } + + virtual STDMETHODIMP IQuickActivate::SetContentExtent(LPSIZEL pSizel) + { + return SetExtent(DVASPECT_CONTENT, pSizel); + } + + virtual STDMETHODIMP IQuickActivate::GetContentExtent(LPSIZEL pSizel) + { + return GetExtent(DVASPECT_CONTENT, pSizel); + } + + /* IViewObject */ // 3/6 + virtual STDMETHODIMP IViewObject::Draw(DWORD dwDrawAspect, LONG lindex, void * pvAspect, DVTARGETDEVICE * ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL (STDMETHODCALLTYPE * pfnContinue)(ULONG_PTR dwContinue), ULONG_PTR dwContinue) + { + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IViewObject::GetColorSet(DWORD dwDrawAspect, LONG lindex, void * pvAspect, DVTARGETDEVICE * ptd, HDC hicTargetDev, LOGPALETTE ** ppColorSet) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IViewObject::Freeze(DWORD dwDrawAspect, LONG lindex, void * pvAspect, DWORD * pdwFreeze) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IViewObject::Unfreeze(DWORD dwFreeze) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IViewObject::SetAdvise(DWORD aspects, DWORD advf, IAdviseSink * pAdvSink) + { + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IViewObject::GetAdvise(DWORD * pAspects, DWORD * pAdvf, IAdviseSink ** ppAdvSink) + { + return E_NOTIMPL; // TODO + } + + /* IViewObject2 */ // 0/1 + virtual STDMETHODIMP IViewObject2::GetExtent(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE * ptd, LPSIZEL lpsizel) + { + return E_NOTIMPL; // TODO + } + + /* IMsTscAx */ // 23/30 + virtual STDMETHODIMP IMsTscAx::put_Server(BSTR pServer) + { + // FIXME: convert the hostname to Punycode, not the ANSI codepage + return SetProperty(m_Server, pServer); + } + + virtual STDMETHODIMP IMsTscAx::get_Server(BSTR * pServer) const + { + return GetProperty(m_Server, pServer); + } + + virtual STDMETHODIMP IMsTscAx::put_Domain(BSTR pDomain) + { + return SetProperty(m_Domain, pDomain); + } + + virtual STDMETHODIMP IMsTscAx::get_Domain(BSTR * pDomain) const + { + return GetProperty(m_Domain, pDomain); + } + + virtual STDMETHODIMP IMsTscAx::put_UserName(BSTR pUserName) + { + return SetProperty(m_UserName, pUserName); + } + + virtual STDMETHODIMP IMsTscAx::get_UserName(BSTR * pUserName) const + { + return GetProperty(m_UserName, pUserName); + } + + virtual STDMETHODIMP IMsTscAx::put_DisconnectedText(BSTR pDisconnectedText) + { + return SetProperty(m_DisconnectedText, pDisconnectedText); + } + + virtual STDMETHODIMP IMsTscAx::get_DisconnectedText(BSTR * pDisconnectedText) const + { + return GetProperty(m_DisconnectedText, pDisconnectedText); + } + + virtual STDMETHODIMP IMsTscAx::put_ConnectingText(BSTR pConnectingText) + { + return SetProperty(m_ConnectingText, pConnectingText); + } + + virtual STDMETHODIMP IMsTscAx::get_ConnectingText(BSTR * pConnectingText) const + { + return GetProperty(m_ConnectingText, pConnectingText); + } + + virtual STDMETHODIMP IMsTscAx::get_Connected(short * pIsConnected) const + { + return GetProperty(m_Connected, pIsConnected); + } + + virtual STDMETHODIMP IMsTscAx::put_DesktopWidth(long pVal) + { + if(pVal < 200 || pVal > 1600) + return E_INVALIDARG; + + return SetProperty(m_DesktopWidth, pVal); + } + + virtual STDMETHODIMP IMsTscAx::get_DesktopWidth(long * pVal) const + { + return GetProperty(m_DesktopWidth, pVal); + } + + virtual STDMETHODIMP IMsTscAx::put_DesktopHeight(long pVal) + { + if(pVal < 200 || pVal > 1200) + return E_INVALIDARG; + + return SetProperty(m_DesktopHeight, pVal); + } + + virtual STDMETHODIMP IMsTscAx::get_DesktopHeight(long * pVal) const + { + return GetProperty(m_DesktopHeight, pVal); + } + + virtual STDMETHODIMP IMsTscAx::put_StartConnected(long pfStartConnected) + { + return SetProperty(m_StartConnected, pfStartConnected); + } + + virtual STDMETHODIMP IMsTscAx::get_StartConnected(long * pfStartConnected) const + { + return GetProperty(m_StartConnected, pfStartConnected); + } + + virtual STDMETHODIMP IMsTscAx::get_HorizontalScrollBarVisible(long * pfHScrollVisible) const + { + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IMsTscAx::get_VerticalScrollBarVisible(long * pfVScrollVisible) const + { + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IMsTscAx::put_FullScreenTitle(BSTR rhs) + { + // TODO + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscAx::get_CipherStrength(long * pCipherStrength) const + { + if(pCipherStrength == NULL) + return E_INVALIDARG; + + *pCipherStrength = 128; // BUGBUG: a later version may change this. Use a compile-time constant + return S_OK; + } + + virtual STDMETHODIMP IMsTscAx::get_Version(BSTR * pVersion) const + { + if(pVersion == NULL) + return E_INVALIDARG; + + BSTR version = SysAllocString(L"5.2.3790.1830"); // BUGBUG: don't use hardcoded string + + if(version == NULL) + return E_OUTOFMEMORY; + + *pVersion = version; + return S_OK; + } + + virtual STDMETHODIMP IMsTscAx::get_SecuredSettingsEnabled(long * pSecuredSettingsEnabled) const + { + // TODO: initialize m_SecuredSettingsEnabled as soon as we have an OLE client site + return GetProperty(m_SecuredSettingsEnabled, pSecuredSettingsEnabled); + } + + virtual STDMETHODIMP IMsTscAx::get_SecuredSettings(MSTSCLib::IMsTscSecuredSettings ** ppSecuredSettings) const + { + return GetSecuredSettings(ppSecuredSettings); + } + + virtual STDMETHODIMP IMsTscAx::get_AdvancedSettings(MSTSCLib::IMsTscAdvancedSettings ** ppAdvSettings) const + { + return GetAdvancedSettings(ppAdvSettings); + } + + virtual STDMETHODIMP IMsTscAx::get_Debugger(MSTSCLib::IMsTscDebug ** ppDebugger) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscAx::Connect() + { + if(m_Connected) + { + // Protocol thread waiting for a manual reconnection: wake it up + if(m_protocolThreadWaitingReconnection) + { + SetEvent(m_protocolThreadWaitingReconnection); + return S_OK; + } + + return E_FAIL; + } + + m_Connected = true; + + HRESULT hr; + + if(m_controlWindow == NULL) + { + hr = CreateControlWindow(NULL); + + if(FAILED(hr)) + return hr; + } + + for(;;) + { + // TODO: initialize plugin DLLs/channels + + m_clientUI = new RdpClientUI(); + + if(m_clientUI == NULL) + { + hr = E_OUTOFMEMORY; + break; + } + + m_clientUI->Initialize(m_controlWindow); + + m_protocolState.licence_username = BstrToLpsz(m_UserName); + + if(m_protocolState.licence_username == NULL) + { + hr = E_OUTOFMEMORY; + break; + } + + DWORD dwSize = ARRAYSIZE(m_protocolState.licence_hostname); + + if(!GetComputerNameA(m_protocolState.licence_hostname, &dwSize)) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + break; + } + + // Keyboard layout + // BUGBUG: not too sure about the semantics + long keyboardLayout = -1; + WCHAR * endPtr = NULL; + + if(m_KeyboardLayoutString) + keyboardLayout = wcstol(m_KeyboardLayoutString, &endPtr, 0); + + // no keyboard layout specified or invalid keyboard layout: use current keyboard layout + if(endPtr == NULL || *endPtr == 0 || keyboardLayout == -1) + keyboardLayout = PtrToLong(GetKeyboardLayout(0)); // FIXME? use LOWORD()? + + m_protocolState.keylayout = keyboardLayout; + + // in case of failure, assume English (US) + if(m_protocolState.keylayout == 0) + m_protocolState.keylayout = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); + + // Physical keyboard information + m_protocolState.keyboard_type = GetKeyboardType(0); + m_protocolState.keyboard_subtype = GetKeyboardType(1); + m_protocolState.keyboard_functionkeys = GetKeyboardType(2); + + // in case of failure, assume an IBM Enhanced keyboard with 12 function keys + if(m_protocolState.keyboard_type == 0 || m_protocolState.keyboard_functionkeys == 0) + { + m_protocolState.keyboard_type = 4; + m_protocolState.keyboard_subtype = 0; + m_protocolState.keyboard_functionkeys = 12; + } + + // More initialization + m_protocolState.width = m_DesktopWidth; + m_protocolState.height = m_DesktopHeight; + m_protocolState.server_depth = m_ColorDepth; + m_protocolState.bitmap_compression = m_Compress ? TRUE : FALSE; + m_protocolState.bitmap_cache = True; // TODO + m_protocolState.bitmap_cache_persist_enable = False; // TODO + m_protocolState.bitmap_cache_precache = True; // FIXME? + m_protocolState.encryption = m_EncryptionEnabled ? TRUE : FALSE; // TBD: detect automatically + m_protocolState.packet_encryption = m_EncryptionEnabled ? TRUE : FALSE; + m_protocolState.desktop_save = True; // FIXME? tie to bitmap cache setting? + m_protocolState.polygon_ellipse_orders = True; + m_protocolState.use_rdp5 = True; // TBD: detect automatically + m_protocolState.console_session = m_ConnectToServerConsole ? TRUE : FALSE; + m_protocolState.rdp5_performanceflags = m_PerformanceFlags; + m_protocolState.tcp_port_rdp = m_RDPPort; + m_protocolState.rdp.current_status = 1; + + // TODO: cache tuning based on the provided parameters + + m_protocolState.cache.bmpcache_lru[0] = -1; + m_protocolState.cache.bmpcache_lru[1] = -1; + m_protocolState.cache.bmpcache_lru[2] = -1; + m_protocolState.cache.bmpcache_mru[0] = -1; + m_protocolState.cache.bmpcache_mru[1] = -1; + m_protocolState.cache.bmpcache_mru[2] = -1; + + DWORD dwIgnore; + m_protocolThread = CreateThread(NULL, 0, ProtocolLoopThreadProc, this, 0, &dwIgnore); + + hr = S_OK; + break; + } + + if(FAILED(hr)) + m_Connected = false; + + return hr; + } + + virtual STDMETHODIMP IMsTscAx::Disconnect() + { + if(!m_Connected) + return E_FAIL; + + // Terminate the protocol thread. On exit, it will fire the Disconnected event + TerminateProtocolThread(); + return S_OK; + } + + virtual STDMETHODIMP IMsTscAx::CreateVirtualChannels(BSTR newVal) + { + UINT strLength = SysStringLen(newVal); + + if(strLength < 1 || strLength > 300) + return E_INVALIDARG; + + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IMsTscAx::SendOnVirtualChannel(BSTR chanName, BSTR ChanData) + { + return E_NOTIMPL; // TODO + } + + /* IMsRdpClient */ // 6/10 + virtual STDMETHODIMP IMsRdpClient::put_ColorDepth(long pcolorDepth) + { + switch(pcolorDepth) + { + case 8: + case 15: + case 16: + case 24: + case 32: + break; + + default: + return E_INVALIDARG; + } + + return SetProperty(m_ColorDepth, pcolorDepth); + } + + virtual STDMETHODIMP IMsRdpClient::get_ColorDepth(long * pcolorDepth) const + { + return GetProperty(m_ColorDepth, pcolorDepth); + } + + virtual STDMETHODIMP IMsRdpClient::get_AdvancedSettings2(MSTSCLib::IMsRdpClientAdvancedSettings ** ppAdvSettings) const + { + return GetAdvancedSettings(ppAdvSettings); + } + + virtual STDMETHODIMP IMsRdpClient::get_SecuredSettings2(MSTSCLib::IMsRdpClientSecuredSettings ** ppSecuredSettings) const + { + return GetSecuredSettings(ppSecuredSettings); + } + + virtual STDMETHODIMP IMsRdpClient::get_ExtendedDisconnectReason(MSTSCLib::ExtendedDisconnectReasonCode * pExtendedDisconnectReason) const + { + return GetProperty(m_ExtendedDisconnectReason, pExtendedDisconnectReason); + } + + virtual STDMETHODIMP IMsRdpClient::put_FullScreen(VARIANT_BOOL pfFullScreen) + { + if(!m_Connected) + return E_FAIL; + + if(pfFullScreen && !m_SecuredSettingsEnabled) + return E_FAIL; + + // TODO + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsRdpClient::get_FullScreen(VARIANT_BOOL * pfFullScreen) const + { + return GetProperty(m_FullScreen, pfFullScreen); + } + + virtual STDMETHODIMP IMsRdpClient::SetVirtualChannelOptions(BSTR chanName, long chanOptions) + { + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IMsRdpClient::GetVirtualChannelOptions(BSTR chanName, long * pChanOptions) + { + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IMsRdpClient::RequestClose(MSTSCLib::ControlCloseStatus * pCloseStatus) + { + if(pCloseStatus == NULL) + return E_POINTER; + + if(!m_Connected) + { + *pCloseStatus = MSTSCLib::controlCloseCanProceed; + return S_OK; + } + + *pCloseStatus = MSTSCLib::controlCloseWaitForEvents; + + if(!PostMessage(m_controlWindow, RDPC_WM_REQUEST_CLOSE, 0, 0)) + return HRESULT_FROM_WIN32(GetLastError()); + + return S_OK; + } + + /* IMsRdpClient2 */ + virtual STDMETHODIMP IMsRdpClient2::get_AdvancedSettings3(MSTSCLib::IMsRdpClientAdvancedSettings2 ** ppAdvSettings) const + { + return GetAdvancedSettings(ppAdvSettings); + } + + virtual STDMETHODIMP IMsRdpClient2::put_ConnectedStatusText(BSTR pConnectedStatusText) + { + return SetProperty(m_ConnectedStatusText, pConnectedStatusText); + } + + virtual STDMETHODIMP IMsRdpClient2::get_ConnectedStatusText(BSTR * pConnectedStatusText) const + { + return GetProperty(m_ConnectedStatusText, pConnectedStatusText); + } + + /* IMsRdpClient3 */ + virtual STDMETHODIMP IMsRdpClient3::get_AdvancedSettings4(MSTSCLib::IMsRdpClientAdvancedSettings3 ** ppAdvSettings) const + { + return GetAdvancedSettings(ppAdvSettings); + } + + /* IMsRdpClient4 */ + virtual STDMETHODIMP IMsRdpClient4::get_AdvancedSettings5(MSTSCLib::IMsRdpClientAdvancedSettings4 ** ppAdvSettings5) const + { + return GetAdvancedSettings(ppAdvSettings5); + } + + /* IMsTscNonScriptable */ + virtual STDMETHODIMP IMsTscNonScriptable::put_ClearTextPassword(BSTR rhs) + { + return SetProperty(m_ClearTextPassword, rhs); + } + + virtual STDMETHODIMP IMsTscNonScriptable::put_PortablePassword(BSTR pPortablePass) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscNonScriptable::get_PortablePassword(BSTR * pPortablePass) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscNonScriptable::put_PortableSalt(BSTR pPortableSalt) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscNonScriptable::get_PortableSalt(BSTR * pPortableSalt) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscNonScriptable::put_BinaryPassword(BSTR pBinaryPassword) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscNonScriptable::get_BinaryPassword(BSTR * pBinaryPassword) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscNonScriptable::put_BinarySalt(BSTR pSalt) + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscNonScriptable::get_BinarySalt(BSTR * pSalt) const + { + return E_NOTIMPL; + } + + virtual STDMETHODIMP IMsTscNonScriptable::ResetPassword() + { + return SetProperty(m_ClearTextPassword, NULL); + } + + /* IMsRdpClientNonScriptable */ // 0/2 + virtual STDMETHODIMP IMsRdpClientNonScriptable::NotifyRedirectDeviceChange(MSTSCLib::UINT_PTR wParam, MSTSCLib::LONG_PTR lParam) + { + return E_NOTIMPL; // TODO + } + + virtual STDMETHODIMP IMsRdpClientNonScriptable::SendKeys(long numKeys, VARIANT_BOOL * pbArrayKeyUp, long * plKeyData) + { + // NOTE: the keys must be sent in a single, atomic sequence + // TODO: acquire the write lock + return E_NOTIMPL; // TODO + } + + /* IMsRdpClientNonScriptable2 */ + virtual STDMETHODIMP IMsRdpClientNonScriptable2::put_UIParentWindowHandle(HWND phwndUIParentWindowHandle) + { + return SetProperty(m_UIParentWindowHandle, phwndUIParentWindowHandle); + } + + virtual STDMETHODIMP IMsRdpClientNonScriptable2::get_UIParentWindowHandle(HWND * phwndUIParentWindowHandle) const + { + return GetProperty(m_UIParentWindowHandle, phwndUIParentWindowHandle); + } +}; + +#pragma warning(pop) + +/* More glue to interface to the rdesktop code */ +extern "C" +{ + +/* Orders */ +/* support routines */ +void ui_begin_update(RDPCLIENT * This) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_BeginUpdate(); +} + +void ui_end_update(RDPCLIENT * This) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_EndUpdate(); +} + +void ui_set_clip(RDPCLIENT * This, int x, int y, int cx, int cy) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_SetClip(x, y, cx, cy); +} + +void ui_reset_clip(RDPCLIENT * This) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_ResetClip(); +} + +/* blits */ +void ui_destblt(RDPCLIENT * This, uint8 opcode, int x, int y, int cx, int cy) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_DestBlt(opcode, x, y, cx, cy); +} + +void ui_memblt(RDPCLIENT * This, uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_MemBlt(opcode, x, y, cx, cy, src, srcx, srcy); +} + +void ui_patblt(RDPCLIENT * This, uint8 opcode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour, int fgcolour) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_PatBlt(opcode, x, y, cx, cy, brush, bgcolour, fgcolour); +} + +void ui_screenblt(RDPCLIENT * This, uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_ScreenBlt(opcode, x, y, cx, cy, srcx, srcy); +} + +void ui_triblt(RDPCLIENT * This, uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy, BRUSH * brush, int bgcolour, int fgcolour) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_TriBlt(opcode, x, y, cx, cy, src, srcx, srcy, brush, bgcolour, fgcolour); +} + +void ui_paint_bitmap(RDPCLIENT * This, int x, int y, int cx, int cy, int width, int height, uint8 * data) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_PaintBitmap(x, y, cx, cy, width, height, data); +} + +/* shapes */ +void ui_ellipse(RDPCLIENT * This, uint8 opcode, uint8 fillmode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour, int fgcolour) +{ + // TODO +// RdpClient::InnerToOuter(This)->GetUI()->Display_Ellipse(opcode, fillmode, x, y, cx, cy, brush, bgcolour, fgcolour); +} + +void ui_line(RDPCLIENT * This, uint8 opcode, int startx, int starty, int endx, int endy, PEN * pen) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_Line(opcode, startx, starty, endx, endy, pen); +} + +void ui_polygon(RDPCLIENT * This, uint8 opcode, uint8 fillmode, POINT * point, int npoints, BRUSH * brush, int bgcolour, int fgcolour) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_Polygon(opcode, fillmode, point, npoints, brush, bgcolour, fgcolour); +} + +void ui_polyline(RDPCLIENT * This, uint8 opcode, POINT * points, int npoints, PEN * pen) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_Polyline(opcode, points, npoints, pen); +} + +void ui_rect(RDPCLIENT * This, int x, int y, int cx, int cy, int colour) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_Rect(x, y, cx, cy, colour); +} + +/* text */ +void ui_draw_text +( + RDPCLIENT * This, + uint8 font, + uint8 flags, + uint8 opcode, + int mixmode, + int x, + int y, + int clipx, + int clipy, + int clipcx, + int clipcy, + int boxx, + int boxy, + int boxcx, + int boxcy, + BRUSH * brush, + int bgcolour, + int fgcolour, + uint8 * text, + uint8 length +) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_DrawText + ( + font, + flags, + opcode, + mixmode, + x, + y, + clipx, + clipy, + clipcx, + clipcy, + boxx, + boxy, + boxcx, + boxcy, + brush, + bgcolour, + fgcolour, + text, + length + ); +} + +/* desktop save/restore */ +void ui_desktop_save(RDPCLIENT * This, uint32 offset, int x, int y, int cx, int cy) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_SaveDesktop(offset, x, y, cx, cy); +} + +void ui_desktop_restore(RDPCLIENT * This, uint32 offset, int x, int y, int cx, int cy) +{ + RdpClient::InnerToOuter(This)->GetUI()->Display_RestoreDesktop(offset, x, y, cx, cy); +} + +/* Resources */ +/* bitmaps */ +HBITMAP ui_create_bitmap(RDPCLIENT * This, int width, int height, uint8 * data) +{ + return win32_create_dib(width, height, This->server_depth, data); +} + +void ui_destroy_bitmap(RDPCLIENT *, HBITMAP bmp) +{ + DeleteObject(bmp); +} + +/* palettes */ +HCOLOURMAP ui_create_colourmap(RDPCLIENT *, COLOURMAP * colours) +{ + return NULL; +} + +void ui_set_colourmap(RDPCLIENT * This, HCOLOURMAP map) +{ + // TODO +} + +/* cursors */ +HCURSOR ui_create_cursor(RDPCLIENT * This, unsigned int x, unsigned int y, int width, int height, uint8 * andmask, uint8 * xormask) +{ + uint8 * andbuf = NULL; + uint8 * xorbuf = NULL; + + uint8 * andbits = win32_convert_scanlines(width, - height, 1, 2, 4, andmask, &andbuf); + uint8 * xorbits = win32_convert_scanlines(width, height, 24, 2, 4, xormask, &xorbuf); + + HBITMAP hbmMask = CreateBitmap(width, height, 1, 1, andbits); + HBITMAP hbmColor = win32_create_dib(width, height, 24, xorbits); + + ICONINFO iconinfo; + iconinfo.fIcon = FALSE; + iconinfo.xHotspot = x; + iconinfo.yHotspot = y; + iconinfo.hbmMask = hbmMask; + iconinfo.hbmColor = hbmColor; + + HICON icon = CreateIconIndirect(&iconinfo); + + if(icon == NULL) + error("CreateIconIndirect %dx%d failed\n", width, height); + + if(andbuf) + delete[] andbuf; + + if(xorbuf) + delete[] xorbuf; + + DeleteObject(hbmMask); + DeleteObject(hbmColor); + + return icon; +} + +void ui_destroy_cursor(RDPCLIENT *, HCURSOR cursor) +{ + DestroyIcon(cursor); +} + +/* glyphs */ +HGLYPH ui_create_glyph(RDPCLIENT * This, int width, int height, const uint8 * data) +{ + uint8 * databuf = NULL; + uint8 * databits = win32_convert_scanlines(width, height, 1, 1, 2, data, &databuf); + + HBITMAP hbm = CreateBitmap(width, height, 1, 1, databits); + + if(databuf) + delete[] databuf; + + const uint8 * p = data; + int stride = alignup(alignup(width, 8) / 8, 1); + +#ifdef _DEBUG + printf("glyph %p\n", hbm); + + for(int i = 0; i < height; ++ i, p += stride) + { + for(int j = 0; j < width; ++ j) + { + int B = p[j / 8]; + int b = 8 - j % 8 - 1; + + if(B & (1 << b)) + fputs("##", stdout); + else + fputs("..", stdout); + } + + fputc('\n', stdout); + } + + fputc('\n', stdout); +#endif + + return hbm; +} + +void ui_destroy_glyph(RDPCLIENT *, HGLYPH glyph) +{ + DeleteObject(glyph); +} + +/* Input window */ +void ui_move_pointer(RDPCLIENT * This, int x, int y) +{ + // TODO +} + +void ui_set_cursor(RDPCLIENT * This, HCURSOR cursor) +{ + // TODO +} + +void ui_set_null_cursor(RDPCLIENT * This) +{ + // TODO +} + +/* Miscellaneous */ +void ui_resize_window(RDPCLIENT * This) +{ +} + +void ui_bell(RDPCLIENT *) +{ + MessageBeep(0); +} + +int ui_select(RDPCLIENT * This, SOCKET rdp_socket) +{ + return SleepEx(0, TRUE) == WAIT_IO_COMPLETION; +} + +/* Events */ +BOOL event_pubkey(RDPCLIENT * This, unsigned char * key, unsigned int key_size) +{ + if(!RdpClient::OnPublicKey(This, key, key_size)) + return FALSE; + else + return TRUE; +} + +void event_logon(RDPCLIENT * This) +{ + RdpClient::OnLogon(This); +} + +BOOL event_redirect(RDPCLIENT * This, uint32 flags, uint32 server_len, wchar_t * server, uint32 cookie_len, char * cookie, uint32 username_len, wchar_t * username, uint32 domain_len, wchar_t * domain, uint32 password_len, wchar_t * password) +{ + if + ( + !RdpClient::OnRedirect + ( + This, + flags, + server_len, + server, + cookie_len, + cookie, + username_len, + username, + domain_len, + domain, + password_len, + password + ) + ) + return FALSE; + else + return TRUE; +} + +} + +class ClassFactory: public IClassFactory +{ +private: + LONG m_refCount; + CLSID m_classId; + unsigned m_libIndex; + +public: + ClassFactory(REFCLSID rclsid, unsigned libIndex): + m_refCount(1), + m_classId(rclsid) + { + lockServer(); + } + + ~ClassFactory() + { + unlockServer(); + } + + virtual STDMETHODIMP QueryInterface(REFIID riid, void ** ppvObject) + { + if(riid == IID_IUnknown || riid == IID_IClassFactory) + { + *ppvObject = this; + return S_OK; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + } + + virtual STDMETHODIMP_(ULONG) AddRef() + { + return InterlockedIncrement(&m_refCount); + } + + virtual STDMETHODIMP_(ULONG) Release() + { + LONG n = InterlockedDecrement(&m_refCount); + + if(n == 0) + delete this; + + return n; + } + + virtual STDMETHODIMP CreateInstance(IUnknown * pUnkOuter, REFIID riid, void ** ppvObject) + { + if(pUnkOuter && riid != IID_IUnknown) + return CLASS_E_NOAGGREGATION; + + return RdpClient::CreateInstance(m_classId, m_libIndex, pUnkOuter, riid, ppvObject); + } + + virtual STDMETHODIMP LockServer(BOOL fLock) + { + if(fLock) + lockServer(); + else + unlockServer(); + + return S_OK; + } +}; + +extern "C" +{ + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv) +{ + unsigned libindex; + + if + ( + rclsid == MSTSCLib::CLSID_MsTscAx || + rclsid == MSTSCLib::CLSID_MsRdpClient || + rclsid == MSTSCLib::CLSID_MsRdpClient2 || + rclsid == MSTSCLib::CLSID_MsRdpClient3 || + rclsid == MSTSCLib::CLSID_MsRdpClient4 + ) + libindex = 1; + else if + ( + rclsid == MSTSCLib_Redist::CLSID_MsTscAx || + rclsid == MSTSCLib_Redist::CLSID_MsRdpClient || + rclsid == MSTSCLib_Redist::CLSID_MsRdpClient2 || + rclsid == MSTSCLib_Redist::CLSID_MsRdpClient3 // || + // rclsid != MSTSCLib::CLSID_MsRdpClient4 + ) + libindex = 2; + else + return CLASS_E_CLASSNOTAVAILABLE; + + ClassFactory * p = new ClassFactory(rclsid, libindex); + + if(p == NULL) + return E_OUTOFMEMORY; + + HRESULT hr = p->QueryInterface(riid, ppv); + + p->Release(); + + if(FAILED(hr)) + return hr; + + return S_OK; +} + +STDAPI DllCanUnloadNow(void) +{ + return canUnloadServer() ? S_OK : S_FALSE; +} + +STDAPI_(ULONG) DllGetTscCtlVer(void) +{ + // BUGBUG: don't hardcode this + return 0x05020ECE; // 5.2.3790 +} + +DWORD WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved) +{ + assert(hInstance == GetCurrentModule()); + + switch(fdwReason) + { + case DLL_PROCESS_ATTACH: + { + DisableThreadLibraryCalls(hInstance); + + if(!RdpClient::Startup()) + return FALSE; + } + + break; + + case DLL_PROCESS_DETACH: + { + // Process is terminating, no need to clean up + if(lpvReserved) + break; + + RdpClient::Shutdown(); + } + + break; + } + + return TRUE; +} + +} + +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib.idl b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib.idl new file mode 100644 index 00000000000..9c78f8575f9 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib.idl @@ -0,0 +1,561 @@ +[ +#ifdef MSTSCLIB_REDIST_ + uuid(AF586AAE-B62A-420E-B796-294E7EE64C70), +#else + uuid(8C11EFA1-92C3-11D1-BC1E-00C04FA31489), +#endif + version(1.0) +] +library MSTSCLib +{ + importlib("stdole32.tlb"); + + dispinterface IMsTscAxEvents; + + interface IMsTscAx; + interface IMsRdpClient; + interface IMsRdpClient2; + interface IMsRdpClient3; + interface IMsRdpClient4; + + interface IMsTscNonScriptable; + interface IMsRdpClientNonScriptable; + interface IMsRdpClientNonScriptable2; + + interface IMsTscAdvancedSettings; + interface IMsRdpClientAdvancedSettings; + interface IMsRdpClientAdvancedSettings2; + interface IMsRdpClientAdvancedSettings3; + interface IMsRdpClientAdvancedSettings4; + + interface IMsTscSecuredSettings; + interface IMsRdpClientSecuredSettings; + + interface IMsTscDebug; + + typedef [public] enum __MIDL___MIDL_itf_mstsax_0275_0001 + { + autoReconnectContinueAutomatic = 0, + autoReconnectContinueStop = 1, + autoReconnectContinueManual = 2 + } + AutoReconnectContinueState; + + typedef [public] enum __MIDL_IMsRdpClient_0001 + { + exDiscReasonNoInfo = 0, + exDiscReasonAPIInitiatedDisconnect = 1, + exDiscReasonAPIInitiatedLogoff = 2, + exDiscReasonServerIdleTimeout = 3, + exDiscReasonServerLogonTimeout = 4, + exDiscReasonReplacedByOtherConnection = 5, + exDiscReasonOutOfMemory = 6, + exDiscReasonServerDeniedConnection = 7, + exDiscReasonServerDeniedConnectionFips = 8, + exDiscReasonLicenseInternal = 256, + exDiscReasonLicenseNoLicenseServer = 257, + exDiscReasonLicenseNoLicense = 258, + exDiscReasonLicenseErrClientMsg = 259, + exDiscReasonLicenseHwidDoesntMatchLicense = 260, + exDiscReasonLicenseErrClientLicense = 261, + exDiscReasonLicenseCantFinishProtocol = 262, + exDiscReasonLicenseClientEndedProtocol = 263, + exDiscReasonLicenseErrClientEncryption = 264, + exDiscReasonLicenseCantUpgradeLicense = 265, + exDiscReasonLicenseNoRemoteConnections = 266, + exDiscReasonProtocolRangeStart = 4096, + exDiscReasonProtocolRangeEnd = 32767 + } + ExtendedDisconnectReasonCode; + + typedef [public] enum __MIDL_IMsRdpClient_0002 + { + controlCloseCanProceed = 0, + controlCloseWaitForEvents = 1 + } + ControlCloseStatus; + + typedef [public] unsigned __int3264 UINT_PTR; + typedef [public] __int3264 LONG_PTR; + + [uuid(336D5562-EFA8-482E-8CB3-C5C0FC7A7DB6)] + dispinterface IMsTscAxEvents + { + properties: + + methods: + [id(0x00000001)] void OnConnecting(); + [id(0x00000002)] void OnConnected(); + [id(0x00000003)] void OnLoginComplete(); + [id(0x00000004)] void OnDisconnected([in] long discReason); + [id(0x00000005)] void OnEnterFullScreenMode(); + [id(0x00000006)] void OnLeaveFullScreenMode(); + [id(0x00000007)] void OnChannelReceivedData([in] BSTR chanName, [in] BSTR data); + [id(0x00000008)] void OnRequestGoFullScreen(); + [id(0x00000009)] void OnRequestLeaveFullScreen(); + [id(0x0000000a)] void OnFatalError([in] long errorCode); + [id(0x0000000b)] void OnWarning([in] long warningCode); + [id(0x0000000c)] void OnRemoteDesktopSizeChange([in] long width, [in] long height); + [id(0x0000000d)] void OnIdleTimeoutNotification(); + [id(0x0000000e)] void OnRequestContainerMinimize(); + [id(0x0000000f)] void OnConfirmClose([out, retval] VARIANT_BOOL * pfAllowClose); + [id(0x00000010)] void OnReceivedTSPublicKey([in] BSTR publicKey, [out, retval] VARIANT_BOOL * pfContinueLogon); + [id(0x00000011)] void OnAutoReconnecting([in] long disconnectReason, [in] long attemptCount, [out, retval] AutoReconnectContinueState * pArcContinueStatus); + [id(0x00000012)] void OnAuthenticationWarningDisplayed(); + [id(0x00000013)] void OnAuthenticationWarningDismissed(); + }; + + [ +#ifdef MSTSCLIB_REDIST_ + uuid(327BB5CD-834E-4400-AEF2-B30E15E5D682), +#else + uuid(8C11EFAE-92C3-11D1-BC1E-00C04FA31489), +#endif + dual, + oleautomation + ] + interface IMsTscAx: IDispatch + { + [id(0x00000001), propput] HRESULT Server([in] BSTR pServer); + [id(0x00000001), propget] HRESULT Server([out, retval] BSTR * pServer); + [id(0x00000002), propput] HRESULT Domain([in] BSTR pDomain); + [id(0x00000002), propget] HRESULT Domain([out, retval] BSTR * pDomain); + [id(0x00000003), propput] HRESULT UserName([in] BSTR pUserName); + [id(0x00000003), propget] HRESULT UserName([out, retval] BSTR * pUserName); + [id(0x00000004), propput] HRESULT DisconnectedText([in] BSTR pDisconnectedText); + [id(0x00000004), propget] HRESULT DisconnectedText([out, retval] BSTR * pDisconnectedText); + [id(0x00000005), propput] HRESULT ConnectingText([in] BSTR pConnectingText); + [id(0x00000005), propget] HRESULT ConnectingText([out, retval] BSTR * pConnectingText); + [id(0x00000006), propget] HRESULT Connected([out, retval] short * pIsConnected); + [id(0x0000000c), propput] HRESULT DesktopWidth([in] long pVal); + [id(0x0000000c), propget] HRESULT DesktopWidth([out, retval] long * pVal); + [id(0x0000000d), propput] HRESULT DesktopHeight([in] long pVal); + [id(0x0000000d), propget] HRESULT DesktopHeight([out, retval] long * pVal); + [id(0x00000010), propput] HRESULT StartConnected([in] long pfStartConnected); + [id(0x00000010), propget] HRESULT StartConnected([out, retval] long * pfStartConnected); + [id(0x00000011), propget] HRESULT HorizontalScrollBarVisible([out, retval] long * pfHScrollVisible); + [id(0x00000012), propget] HRESULT VerticalScrollBarVisible([out, retval] long * pfVScrollVisible); + [id(0x00000013), propput] HRESULT FullScreenTitle([in] BSTR rhs); + [id(0x00000014), propget] HRESULT CipherStrength([out, retval] long * pCipherStrength); + [id(0x00000015), propget] HRESULT Version([out, retval] BSTR * pVersion); + [id(0x00000016), propget] HRESULT SecuredSettingsEnabled([out, retval] long * pSecuredSettingsEnabled); + [id(0x00000061), propget] HRESULT SecuredSettings([out, retval] IMsTscSecuredSettings ** ppSecuredSettings); + [id(0x00000062), propget] HRESULT AdvancedSettings([out, retval] IMsTscAdvancedSettings ** ppAdvSettings); + [id(0x00000063), propget, hidden] HRESULT Debugger([out, retval] IMsTscDebug ** ppDebugger); + [id(0x0000001e)] HRESULT Connect(); + [id(0x0000001f)] HRESULT Disconnect(); + [id(0x00000021)] HRESULT CreateVirtualChannels([in] BSTR newVal); + [id(0x00000022)] HRESULT SendOnVirtualChannel([in] BSTR chanName, [in] BSTR ChanData); + }; + + [ + uuid(92B4A539-7115-4B7C-A5A9-E5D9EFC2780A), + dual, + oleautomation + ] + interface IMsRdpClient: IMsTscAx + { + [id(0x00000064), propput] HRESULT ColorDepth([in] long pcolorDepth); + [id(0x00000064), propget] HRESULT ColorDepth([out, retval] long * pcolorDepth); + [id(0x00000065), propget] HRESULT AdvancedSettings2([out, retval] IMsRdpClientAdvancedSettings ** ppAdvSettings); + [id(0x00000066), propget] HRESULT SecuredSettings2([out, retval] IMsRdpClientSecuredSettings ** ppSecuredSettings); + [id(0x00000067), propget] HRESULT ExtendedDisconnectReason([out, retval] ExtendedDisconnectReasonCode * pExtendedDisconnectReason); + [id(0x00000068), propput] HRESULT FullScreen([in] VARIANT_BOOL pfFullScreen); + [id(0x00000068), propget] HRESULT FullScreen([out, retval] VARIANT_BOOL * pfFullScreen); + [id(0x00000023)] HRESULT SetVirtualChannelOptions([in] BSTR chanName, [in] long chanOptions); + [id(0x00000024)] HRESULT GetVirtualChannelOptions([in] BSTR chanName, [out, retval] long * pChanOptions); + [id(0x00000025)] HRESULT RequestClose([out, retval] ControlCloseStatus * pCloseStatus); + }; + + [ + uuid(E7E17DC4-3B71-4BA7-A8E6-281FFADCA28F), + dual, + oleautomation + ] + interface IMsRdpClient2: IMsRdpClient + { + [id(0x000000c8), propget] HRESULT AdvancedSettings3([out, retval] IMsRdpClientAdvancedSettings2 ** ppAdvSettings); + [id(0x000000c9), propput] HRESULT ConnectedStatusText([in] BSTR pConnectedStatusText); + [id(0x000000c9), propget] HRESULT ConnectedStatusText([out, retval] BSTR * pConnectedStatusText); + }; + + [ + uuid(91B7CBC5-A72E-4FA0-9300-D647D7E897FF), + dual, + oleautomation + ] + interface IMsRdpClient3: IMsRdpClient2 + { + [id(0x0000012c), propget] HRESULT AdvancedSettings4([out, retval] IMsRdpClientAdvancedSettings3 ** ppAdvSettings); + }; + + [ + uuid(095E0738-D97D-488B-B9F6-DD0E8D66C0DE), + dual, + oleautomation + ] + interface IMsRdpClient4: IMsRdpClient3 + { + [id(0x00000190), propget] HRESULT AdvancedSettings5([out, retval] IMsRdpClientAdvancedSettings4 ** ppAdvSettings5); + }; + + [uuid(C1E6743A-41C1-4A74-832A-0DD06C1C7A0E)] + interface IMsTscNonScriptable: IUnknown + { + [propput] HRESULT ClearTextPassword([in] BSTR rhs); + [propput] HRESULT PortablePassword([in] BSTR pPortablePass); + [propget] HRESULT PortablePassword([out, retval] BSTR * pPortablePass); + [propput] HRESULT PortableSalt([in] BSTR pPortableSalt); + [propget] HRESULT PortableSalt([out, retval] BSTR * pPortableSalt); + [propput] HRESULT BinaryPassword([in] BSTR pBinaryPassword); + [propget] HRESULT BinaryPassword([out, retval] BSTR * pBinaryPassword); + [propput] HRESULT BinarySalt([in] BSTR pSalt); + [propget] HRESULT BinarySalt([out, retval] BSTR * pSalt); + HRESULT ResetPassword(); + }; + + [uuid(2F079C4C-87B2-4AFD-97AB-20CDB43038AE)] + interface IMsRdpClientNonScriptable: IMsTscNonScriptable + { + HRESULT NotifyRedirectDeviceChange([in] UINT_PTR wParam, [in] LONG_PTR lParam); + HRESULT SendKeys([in] long numKeys, [in] VARIANT_BOOL * pbArrayKeyUp, [in] long * plKeyData); + }; + + [uuid(17A5E535-4072-4FA4-AF32-C8D0D47345E9)] + interface IMsRdpClientNonScriptable2: IMsRdpClientNonScriptable + { + [propput] HRESULT UIParentWindowHandle([in] HWND phwndUIParentWindowHandle); + [propget] HRESULT UIParentWindowHandle([out, retval] HWND * phwndUIParentWindowHandle); + }; + + [ + uuid(809945CC-4B3B-4A92-A6B0-DBF9B5F2EF2D), + dual, + oleautomation + ] + interface IMsTscAdvancedSettings: IDispatch + { + [id(0x00000079), propput] HRESULT Compress([in] long pcompress); + [id(0x00000079), propget] HRESULT Compress([out, retval] long * pcompress); + [id(0x0000007a), propput] HRESULT BitmapPeristence([in] long pbitmapPeristence); + [id(0x0000007a), propget] HRESULT BitmapPeristence([out, retval] long * pbitmapPeristence); + [id(0x000000a1), propput] HRESULT allowBackgroundInput([in] long pallowBackgroundInput); + [id(0x000000a1), propget] HRESULT allowBackgroundInput([out, retval] long * pallowBackgroundInput); + [id(0x000000a2), propput] HRESULT KeyBoardLayoutStr([in] BSTR rhs); + [id(0x000000aa), propput] HRESULT PluginDlls([in] BSTR rhs); + [id(0x000000ab), propput] HRESULT IconFile([in] BSTR rhs); + [id(0x000000ac), propput] HRESULT IconIndex([in] long rhs); + [id(0x000000ad), propput] HRESULT ContainerHandledFullScreen([in] long pContainerHandledFullScreen); + [id(0x000000ad), propget] HRESULT ContainerHandledFullScreen([out, retval] long * pContainerHandledFullScreen); + [id(0x000000ae), propput] HRESULT DisableRdpdr([in] long pDisableRdpdr); + [id(0x000000ae), propget] HRESULT DisableRdpdr([out, retval] long * pDisableRdpdr); + }; + + [ + uuid(3C65B4AB-12B3-465B-ACD4-B8DAD3BFF9E2), + dual, + oleautomation + ] + interface IMsRdpClientAdvancedSettings: IMsTscAdvancedSettings + { + [id(0x00000065), propput] HRESULT SmoothScroll([in] long psmoothScroll); + [id(0x00000065), propget] HRESULT SmoothScroll([out, retval] long * psmoothScroll); + [id(0x00000066), propput] HRESULT AcceleratorPassthrough([in] long pacceleratorPassthrough); + [id(0x00000066), propget] HRESULT AcceleratorPassthrough([out, retval] long * pacceleratorPassthrough); + [id(0x00000067), propput] HRESULT ShadowBitmap([in] long pshadowBitmap); + [id(0x00000067), propget] HRESULT ShadowBitmap([out, retval] long * pshadowBitmap); + [id(0x00000068), propput] HRESULT TransportType([in] long ptransportType); + [id(0x00000068), propget] HRESULT TransportType([out, retval] long * ptransportType); + [id(0x00000069), propput] HRESULT SasSequence([in] long psasSequence); + [id(0x00000069), propget] HRESULT SasSequence([out, retval] long * psasSequence); + [id(0x0000006a), propput] HRESULT EncryptionEnabled([in] long pencryptionEnabled); + [id(0x0000006a), propget] HRESULT EncryptionEnabled([out, retval] long * pencryptionEnabled); + [id(0x0000006b), propput] HRESULT DedicatedTerminal([in] long pdedicatedTerminal); + [id(0x0000006b), propget] HRESULT DedicatedTerminal([out, retval] long * pdedicatedTerminal); + [id(0x0000006c), propput] HRESULT RDPPort([in] long prdpPort); + [id(0x0000006c), propget] HRESULT RDPPort([out, retval] long * prdpPort); + [id(0x0000006d), propput] HRESULT EnableMouse([in] long penableMouse); + [id(0x0000006d), propget] HRESULT EnableMouse([out, retval] long * penableMouse); + [id(0x0000006e), propput] HRESULT DisableCtrlAltDel([in] long pdisableCtrlAltDel); + [id(0x0000006e), propget] HRESULT DisableCtrlAltDel([out, retval] long * pdisableCtrlAltDel); + [id(0x0000006f), propput] HRESULT EnableWindowsKey([in] long penableWindowsKey); + [id(0x0000006f), propget] HRESULT EnableWindowsKey([out, retval] long * penableWindowsKey); + [id(0x00000070), propput] HRESULT DoubleClickDetect([in] long pdoubleClickDetect); + [id(0x00000070), propget] HRESULT DoubleClickDetect([out, retval] long * pdoubleClickDetect); + [id(0x00000071), propput] HRESULT MaximizeShell([in] long pmaximizeShell); + [id(0x00000071), propget] HRESULT MaximizeShell([out, retval] long * pmaximizeShell); + [id(0x00000072), propput] HRESULT HotKeyFullScreen([in] long photKeyFullScreen); + [id(0x00000072), propget] HRESULT HotKeyFullScreen([out, retval] long * photKeyFullScreen); + [id(0x00000073), propput] HRESULT HotKeyCtrlEsc([in] long photKeyCtrlEsc); + [id(0x00000073), propget] HRESULT HotKeyCtrlEsc([out, retval] long * photKeyCtrlEsc); + [id(0x00000074), propput] HRESULT HotKeyAltEsc([in] long photKeyAltEsc); + [id(0x00000074), propget] HRESULT HotKeyAltEsc([out, retval] long * photKeyAltEsc); + [id(0x00000075), propput] HRESULT HotKeyAltTab([in] long photKeyAltTab); + [id(0x00000075), propget] HRESULT HotKeyAltTab([out, retval] long * photKeyAltTab); + [id(0x00000076), propput] HRESULT HotKeyAltShiftTab([in] long photKeyAltShiftTab); + [id(0x00000076), propget] HRESULT HotKeyAltShiftTab([out, retval] long * photKeyAltShiftTab); + [id(0x00000077), propput] HRESULT HotKeyAltSpace([in] long photKeyAltSpace); + [id(0x00000077), propget] HRESULT HotKeyAltSpace([out, retval] long * photKeyAltSpace); + [id(0x00000078), propput] HRESULT HotKeyCtrlAltDel([in] long photKeyCtrlAltDel); + [id(0x00000078), propget] HRESULT HotKeyCtrlAltDel([out, retval] long * photKeyCtrlAltDel); + [id(0x0000007b), propput] HRESULT orderDrawThreshold([in] long porderDrawThreshold); + [id(0x0000007b), propget] HRESULT orderDrawThreshold([out, retval] long * porderDrawThreshold); + [id(0x0000007c), propput] HRESULT BitmapCacheSize([in] long pbitmapCacheSize); + [id(0x0000007c), propget] HRESULT BitmapCacheSize([out, retval] long * pbitmapCacheSize); + [id(0x0000007d), propput] HRESULT BitmapVirtualCacheSize([in] long pbitmapVirtualCacheSize); + [id(0x0000007d), propget] HRESULT BitmapVirtualCacheSize([out, retval] long * pbitmapVirtualCacheSize); + [id(0x000000af), propput] HRESULT ScaleBitmapCachesByBPP([in] long pbScale); + [id(0x000000af), propget] HRESULT ScaleBitmapCachesByBPP([out, retval] long * pbScale); + [id(0x0000007e), propput] HRESULT NumBitmapCaches([in] long pnumBitmapCaches); + [id(0x0000007e), propget] HRESULT NumBitmapCaches([out, retval] long * pnumBitmapCaches); + [id(0x0000007f), propput] HRESULT CachePersistenceActive([in] long pcachePersistenceActive); + [id(0x0000007f), propget] HRESULT CachePersistenceActive([out, retval] long * pcachePersistenceActive); + [id(0x0000008a), propput] HRESULT PersistCacheDirectory([in] BSTR rhs); + [id(0x0000009c), propput] HRESULT brushSupportLevel([in] long pbrushSupportLevel); + [id(0x0000009c), propget] HRESULT brushSupportLevel([out, retval] long * pbrushSupportLevel); + [id(0x0000009d), propput] HRESULT minInputSendInterval([in] long pminInputSendInterval); + [id(0x0000009d), propget] HRESULT minInputSendInterval([out, retval] long * pminInputSendInterval); + [id(0x0000009e), propput] HRESULT InputEventsAtOnce([in] long pinputEventsAtOnce); + [id(0x0000009e), propget] HRESULT InputEventsAtOnce([out, retval] long * pinputEventsAtOnce); + [id(0x0000009f), propput] HRESULT maxEventCount([in] long pmaxEventCount); + [id(0x0000009f), propget] HRESULT maxEventCount([out, retval] long * pmaxEventCount); + [id(0x000000a0), propput] HRESULT keepAliveInterval([in] long pkeepAliveInterval); + [id(0x000000a0), propget] HRESULT keepAliveInterval([out, retval] long * pkeepAliveInterval); + [id(0x000000a3), propput] HRESULT shutdownTimeout([in] long pshutdownTimeout); + [id(0x000000a3), propget] HRESULT shutdownTimeout([out, retval] long * pshutdownTimeout); + [id(0x000000a4), propput] HRESULT overallConnectionTimeout([in] long poverallConnectionTimeout); + [id(0x000000a4), propget] HRESULT overallConnectionTimeout([out, retval] long * poverallConnectionTimeout); + [id(0x000000a5), propput] HRESULT singleConnectionTimeout([in] long psingleConnectionTimeout); + [id(0x000000a5), propget] HRESULT singleConnectionTimeout([out, retval] long * psingleConnectionTimeout); + [id(0x000000a6), propput] HRESULT KeyboardType([in] long pkeyboardType); + [id(0x000000a6), propget] HRESULT KeyboardType([out, retval] long * pkeyboardType); + [id(0x000000a7), propput] HRESULT KeyboardSubType([in] long pkeyboardSubType); + [id(0x000000a7), propget] HRESULT KeyboardSubType([out, retval] long * pkeyboardSubType); + [id(0x000000a8), propput] HRESULT KeyboardFunctionKey([in] long pkeyboardFunctionKey); + [id(0x000000a8), propget] HRESULT KeyboardFunctionKey([out, retval] long * pkeyboardFunctionKey); + [id(0x000000a9), propput] HRESULT WinceFixedPalette([in] long pwinceFixedPalette); + [id(0x000000a9), propget] HRESULT WinceFixedPalette([out, retval] long * pwinceFixedPalette); + [id(0x000000b2), propput] HRESULT ConnectToServerConsole([in] VARIANT_BOOL pConnectToConsole); + [id(0x000000b2), propget] HRESULT ConnectToServerConsole([out, retval] VARIANT_BOOL * pConnectToConsole); + [id(0x000000b6), propput] HRESULT BitmapPersistence([in] long pbitmapPersistence); + [id(0x000000b6), propget] HRESULT BitmapPersistence([out, retval] long * pbitmapPersistence); + [id(0x000000b7), propput] HRESULT MinutesToIdleTimeout([in] long pminutesToIdleTimeout); + [id(0x000000b7), propget] HRESULT MinutesToIdleTimeout([out, retval] long * pminutesToIdleTimeout); + [id(0x000000b8), propput] HRESULT SmartSizing([in] VARIANT_BOOL pfSmartSizing); + [id(0x000000b8), propget] HRESULT SmartSizing([out, retval] VARIANT_BOOL * pfSmartSizing); + [id(0x000000b9), propput] HRESULT RdpdrLocalPrintingDocName([in] BSTR pLocalPrintingDocName); + [id(0x000000b9), propget] HRESULT RdpdrLocalPrintingDocName([out, retval] BSTR * pLocalPrintingDocName); + [id(0x000000c9), propput] HRESULT RdpdrClipCleanTempDirString([in] BSTR clipCleanTempDirString); + [id(0x000000c9), propget] HRESULT RdpdrClipCleanTempDirString([out, retval] BSTR * clipCleanTempDirString); + [id(0x000000ca), propput] HRESULT RdpdrClipPasteInfoString([in] BSTR clipPasteInfoString); + [id(0x000000ca), propget] HRESULT RdpdrClipPasteInfoString([out, retval] BSTR * clipPasteInfoString); + [id(0x000000ba), propput] HRESULT ClearTextPassword([in] BSTR rhs); + [id(0x000000bb), propput] HRESULT DisplayConnectionBar([in] VARIANT_BOOL pDisplayConnectionBar); + [id(0x000000bb), propget] HRESULT DisplayConnectionBar([out, retval] VARIANT_BOOL * pDisplayConnectionBar); + [id(0x000000bc), propput] HRESULT PinConnectionBar([in] VARIANT_BOOL pPinConnectionBar); + [id(0x000000bc), propget] HRESULT PinConnectionBar([out, retval] VARIANT_BOOL * pPinConnectionBar); + [id(0x000000bd), propput] HRESULT GrabFocusOnConnect([in] VARIANT_BOOL pfGrabFocusOnConnect); + [id(0x000000bd), propget] HRESULT GrabFocusOnConnect([out, retval] VARIANT_BOOL * pfGrabFocusOnConnect); + [id(0x000000be), propput] HRESULT LoadBalanceInfo([in] BSTR pLBInfo); + [id(0x000000be), propget] HRESULT LoadBalanceInfo([out, retval] BSTR * pLBInfo); + [id(0x000000bf), propput] HRESULT RedirectDrives([in] VARIANT_BOOL pRedirectDrives); + [id(0x000000bf), propget] HRESULT RedirectDrives([out, retval] VARIANT_BOOL * pRedirectDrives); + [id(0x000000c0), propput] HRESULT RedirectPrinters([in] VARIANT_BOOL pRedirectPrinters); + [id(0x000000c0), propget] HRESULT RedirectPrinters([out, retval] VARIANT_BOOL * pRedirectPrinters); + [id(0x000000c1), propput] HRESULT RedirectPorts([in] VARIANT_BOOL pRedirectPorts); + [id(0x000000c1), propget] HRESULT RedirectPorts([out, retval] VARIANT_BOOL * pRedirectPorts); + [id(0x000000c2), propput] HRESULT RedirectSmartCards([in] VARIANT_BOOL pRedirectSmartCards); + [id(0x000000c2), propget] HRESULT RedirectSmartCards([out, retval] VARIANT_BOOL * pRedirectSmartCards); + [id(0x000000c3), propput] HRESULT BitmapVirtualCache16BppSize([in] long pBitmapVirtualCache16BppSize); + [id(0x000000c3), propget] HRESULT BitmapVirtualCache16BppSize([out, retval] long * pBitmapVirtualCache16BppSize); + [id(0x000000c4), propput] HRESULT BitmapVirtualCache24BppSize([in] long pBitmapVirtualCache24BppSize); + [id(0x000000c4), propget] HRESULT BitmapVirtualCache24BppSize([out, retval] long * pBitmapVirtualCache24BppSize); + [id(0x000000c8), propput] HRESULT PerformanceFlags([in] long pDisableList); + [id(0x000000c8), propget] HRESULT PerformanceFlags([out, retval] long * pDisableList); + [id(0x000000cb), propput] HRESULT ConnectWithEndpoint([in] VARIANT * rhs); + [id(0x000000cc), propput] HRESULT NotifyTSPublicKey([in] VARIANT_BOOL pfNotify); + [id(0x000000cc), propget] HRESULT NotifyTSPublicKey([out, retval] VARIANT_BOOL * pfNotify); + }; + + [ + uuid(9AC42117-2B76-4320-AA44-0E616AB8437B), + dual, + oleautomation + ] + interface IMsRdpClientAdvancedSettings2: IMsRdpClientAdvancedSettings + { + [id(0x000000cd), propget] HRESULT CanAutoReconnect([out, retval] VARIANT_BOOL * pfCanAutoReconnect); + [id(0x000000ce), propput] HRESULT EnableAutoReconnect([in] VARIANT_BOOL pfEnableAutoReconnect); + [id(0x000000ce), propget] HRESULT EnableAutoReconnect([out, retval] VARIANT_BOOL * pfEnableAutoReconnect); + [id(0x000000cf), propput] HRESULT MaxReconnectAttempts([in] long pMaxReconnectAttempts); + [id(0x000000cf), propget] HRESULT MaxReconnectAttempts([out, retval] long * pMaxReconnectAttempts); + }; + + [ + uuid(19CD856B-C542-4C53-ACEE-F127E3BE1A59), + dual, + oleautomation + ] + interface IMsRdpClientAdvancedSettings3: IMsRdpClientAdvancedSettings2 + { + [id(0x000000d2), propput] HRESULT ConnectionBarShowMinimizeButton([in] VARIANT_BOOL pfShowMinimize); + [id(0x000000d2), propget] HRESULT ConnectionBarShowMinimizeButton([out, retval] VARIANT_BOOL * pfShowMinimize); + [id(0x000000d3), propput] HRESULT ConnectionBarShowRestoreButton([in] VARIANT_BOOL pfShowRestore); + [id(0x000000d3), propget] HRESULT ConnectionBarShowRestoreButton([out, retval] VARIANT_BOOL * pfShowRestore); + }; + + [ + uuid(FBA7F64E-7345-4405-AE50-FA4A763DC0DE), + dual, + oleautomation + ] + interface IMsRdpClientAdvancedSettings4: IMsRdpClientAdvancedSettings3 + { + [id(0x000000d4), propput] HRESULT AuthenticationLevel([in] unsigned int puiAuthLevel); + [id(0x000000d4), propget] HRESULT AuthenticationLevel([out, retval] unsigned int * puiAuthLevel); + }; + + [ + uuid(C9D65442-A0F9-45B2-8F73-D61D2DB8CBB6), + dual, + oleautomation + ] + interface IMsTscSecuredSettings: IDispatch + { + [id(0x00000001), propput] HRESULT StartProgram([in] BSTR pStartProgram); + [id(0x00000001), propget] HRESULT StartProgram([out, retval] BSTR * pStartProgram); + [id(0x00000002), propput] HRESULT WorkDir([in] BSTR pWorkDir); + [id(0x00000002), propget] HRESULT WorkDir([out, retval] BSTR * pWorkDir); + [id(0x00000003), propput] HRESULT FullScreen([in] long pfFullScreen); + [id(0x00000003), propget] HRESULT FullScreen([out, retval] long * pfFullScreen); + }; + + [ + uuid(605BEFCF-39C1-45CC-A811-068FB7BE346D), + dual, + oleautomation + ] + interface IMsRdpClientSecuredSettings: IMsTscSecuredSettings + { + [id(0x00000004), propput] HRESULT KeyboardHookMode([in] long pkeyboardHookMode); + [id(0x00000004), propget] HRESULT KeyboardHookMode([out, retval] long * pkeyboardHookMode); + [id(0x00000005), propput] HRESULT AudioRedirectionMode([in] long pAudioRedirectionMode); + [id(0x00000005), propget] HRESULT AudioRedirectionMode([out, retval] long * pAudioRedirectionMode); + }; + + [ + uuid(209D0EB9-6254-47B1-9033-A98DAE55BB27), + hidden, + dual, + oleautomation + ] + interface IMsTscDebug: IDispatch + { + [id(0x000000c8), propput] HRESULT HatchBitmapPDU([in] long phatchBitmapPDU); + [id(0x000000c8), propget] HRESULT HatchBitmapPDU([out, retval] long * phatchBitmapPDU); + [id(0x000000c9), propput] HRESULT HatchSSBOrder([in] long phatchSSBOrder); + [id(0x000000c9), propget] HRESULT HatchSSBOrder([out, retval] long * phatchSSBOrder); + [id(0x000000ca), propput] HRESULT HatchMembltOrder([in] long phatchMembltOrder); + [id(0x000000ca), propget] HRESULT HatchMembltOrder([out, retval] long * phatchMembltOrder); + [id(0x000000cb), propput] HRESULT HatchIndexPDU([in] long phatchIndexPDU); + [id(0x000000cb), propget] HRESULT HatchIndexPDU([out, retval] long * phatchIndexPDU); + [id(0x000000cc), propput] HRESULT LabelMemblt([in] long plabelMemblt); + [id(0x000000cc), propget] HRESULT LabelMemblt([out, retval] long * plabelMemblt); + [id(0x000000cd), propput] HRESULT BitmapCacheMonitor([in] long pbitmapCacheMonitor); + [id(0x000000cd), propget] HRESULT BitmapCacheMonitor([out, retval] long * pbitmapCacheMonitor); + [id(0x000000ce), propput] HRESULT MallocFailuresPercent([in] long pmallocFailuresPercent); + [id(0x000000ce), propget] HRESULT MallocFailuresPercent([out, retval] long * pmallocFailuresPercent); + [id(0x000000cf), propput] HRESULT MallocHugeFailuresPercent([in] long pmallocHugeFailuresPercent); + [id(0x000000cf), propget] HRESULT MallocHugeFailuresPercent([out, retval] long * pmallocHugeFailuresPercent); + [id(0x000000d0), propput] HRESULT NetThroughput([in] long NetThroughput); + [id(0x000000d0), propget] HRESULT NetThroughput([out, retval] long * NetThroughput); + [id(0x000000d1), propput] HRESULT CLXCmdLine([in] BSTR pCLXCmdLine); + [id(0x000000d1), propget] HRESULT CLXCmdLine([out, retval] BSTR * pCLXCmdLine); + [id(0x000000d2), propput] HRESULT CLXDll([in] BSTR pCLXDll); + [id(0x000000d2), propget] HRESULT CLXDll([out, retval] BSTR * pCLXDll); + }; + + [ +#ifdef MSTSCLIB_REDIST_ + uuid(1FB464C8-09BB-4017-A2F5-EB742F04392F) +#else + uuid(A41A4187-5A86-4E26-B40A-856F9035D9CB) +#endif + ] + coclass MsTscAx + { + interface IMsRdpClient; + [default] interface IMsTscAx; + [default, source] dispinterface IMsTscAxEvents; + interface IMsTscNonScriptable; + interface IMsRdpClientNonScriptable; + }; + + [ +#ifdef MSTSCLIB_REDIST_ + uuid(791FA017-2DE3-492E-ACC5-53C67A2B94D0) +#else + uuid(7CACBD7B-0D99-468F-AC33-22E495C0AFE5) +#endif + ] + coclass MsRdpClient + { + [default] interface IMsRdpClient; + interface IMsTscAx; + [default, source] dispinterface IMsTscAxEvents; + interface IMsTscNonScriptable; + interface IMsRdpClientNonScriptable; + }; + + [ +#ifdef MSTSCLIB_REDIST_ + uuid(9059F30F-4EB1-4BD2-9FDC-36F43A218F4A) +#else + uuid(3523C2FB-4031-44E4-9A3B-F1E94986EE7F) +#endif + ] + coclass MsRdpClient2 + { + [default] interface IMsRdpClient2; + interface IMsRdpClient; + interface IMsTscAx; + [default, source] dispinterface IMsTscAxEvents; + interface IMsTscNonScriptable; + interface IMsRdpClientNonScriptable; + }; + + [ +#ifdef MSTSCLIB_REDIST_ + uuid(7584C670-2274-4EFB-B00B-D6AABA6D3850) +#else + uuid(ACE575FD-1FCF-4074-9401-EBAB990FA9DE) +#endif + ] + coclass MsRdpClient3 + { + [default] interface IMsRdpClient3; + interface IMsRdpClient2; + interface IMsRdpClient; + interface IMsTscAx; + [default, source] dispinterface IMsTscAxEvents; + interface IMsTscNonScriptable; + interface IMsRdpClientNonScriptable; + }; + + [uuid(6AE29350-321B-42BE-BBE5-12FB5270C0DE)] + coclass MsRdpClient4 + { + [default] interface IMsRdpClient4; + interface IMsRdpClient3; + interface IMsRdpClient2; + interface IMsRdpClient; + interface IMsTscAx; + [default, source] dispinterface IMsTscAxEvents; + interface IMsTscNonScriptable; + interface IMsRdpClientNonScriptable; + interface IMsRdpClientNonScriptable2; + }; + +}; + +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib.rc b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib.rc new file mode 100644 index 00000000000..fa268c7e9ea --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib.rc @@ -0,0 +1,3 @@ +#define TYPELIB_RESOURCEID__ 1 +#include "./typelib.rh" +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_h.h b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_h.h new file mode 100644 index 00000000000..2685131f18a --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_h.h @@ -0,0 +1,8946 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0493 */ +/* at Sun Aug 13 16:46:06 2006 + */ +/* Compiler settings for .\mstsclib.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + + +#ifndef __mstsclib_h_h__ +#define __mstsclib_h_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IMsTscAxEvents_FWD_DEFINED__ +#define __IMsTscAxEvents_FWD_DEFINED__ +typedef interface IMsTscAxEvents IMsTscAxEvents; +#endif /* __IMsTscAxEvents_FWD_DEFINED__ */ + + +#ifndef __IMsTscAx_FWD_DEFINED__ +#define __IMsTscAx_FWD_DEFINED__ +typedef interface IMsTscAx IMsTscAx; +#endif /* __IMsTscAx_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClient_FWD_DEFINED__ +#define __IMsRdpClient_FWD_DEFINED__ +typedef interface IMsRdpClient IMsRdpClient; +#endif /* __IMsRdpClient_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClient2_FWD_DEFINED__ +#define __IMsRdpClient2_FWD_DEFINED__ +typedef interface IMsRdpClient2 IMsRdpClient2; +#endif /* __IMsRdpClient2_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClient3_FWD_DEFINED__ +#define __IMsRdpClient3_FWD_DEFINED__ +typedef interface IMsRdpClient3 IMsRdpClient3; +#endif /* __IMsRdpClient3_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClient4_FWD_DEFINED__ +#define __IMsRdpClient4_FWD_DEFINED__ +typedef interface IMsRdpClient4 IMsRdpClient4; +#endif /* __IMsRdpClient4_FWD_DEFINED__ */ + + +#ifndef __IMsTscNonScriptable_FWD_DEFINED__ +#define __IMsTscNonScriptable_FWD_DEFINED__ +typedef interface IMsTscNonScriptable IMsTscNonScriptable; +#endif /* __IMsTscNonScriptable_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientNonScriptable_FWD_DEFINED__ +#define __IMsRdpClientNonScriptable_FWD_DEFINED__ +typedef interface IMsRdpClientNonScriptable IMsRdpClientNonScriptable; +#endif /* __IMsRdpClientNonScriptable_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientNonScriptable2_FWD_DEFINED__ +#define __IMsRdpClientNonScriptable2_FWD_DEFINED__ +typedef interface IMsRdpClientNonScriptable2 IMsRdpClientNonScriptable2; +#endif /* __IMsRdpClientNonScriptable2_FWD_DEFINED__ */ + + +#ifndef __IMsTscAdvancedSettings_FWD_DEFINED__ +#define __IMsTscAdvancedSettings_FWD_DEFINED__ +typedef interface IMsTscAdvancedSettings IMsTscAdvancedSettings; +#endif /* __IMsTscAdvancedSettings_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings_FWD_DEFINED__ +#define __IMsRdpClientAdvancedSettings_FWD_DEFINED__ +typedef interface IMsRdpClientAdvancedSettings IMsRdpClientAdvancedSettings; +#endif /* __IMsRdpClientAdvancedSettings_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings2_FWD_DEFINED__ +#define __IMsRdpClientAdvancedSettings2_FWD_DEFINED__ +typedef interface IMsRdpClientAdvancedSettings2 IMsRdpClientAdvancedSettings2; +#endif /* __IMsRdpClientAdvancedSettings2_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings3_FWD_DEFINED__ +#define __IMsRdpClientAdvancedSettings3_FWD_DEFINED__ +typedef interface IMsRdpClientAdvancedSettings3 IMsRdpClientAdvancedSettings3; +#endif /* __IMsRdpClientAdvancedSettings3_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings4_FWD_DEFINED__ +#define __IMsRdpClientAdvancedSettings4_FWD_DEFINED__ +typedef interface IMsRdpClientAdvancedSettings4 IMsRdpClientAdvancedSettings4; +#endif /* __IMsRdpClientAdvancedSettings4_FWD_DEFINED__ */ + + +#ifndef __IMsTscSecuredSettings_FWD_DEFINED__ +#define __IMsTscSecuredSettings_FWD_DEFINED__ +typedef interface IMsTscSecuredSettings IMsTscSecuredSettings; +#endif /* __IMsTscSecuredSettings_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientSecuredSettings_FWD_DEFINED__ +#define __IMsRdpClientSecuredSettings_FWD_DEFINED__ +typedef interface IMsRdpClientSecuredSettings IMsRdpClientSecuredSettings; +#endif /* __IMsRdpClientSecuredSettings_FWD_DEFINED__ */ + + +#ifndef __IMsTscDebug_FWD_DEFINED__ +#define __IMsTscDebug_FWD_DEFINED__ +typedef interface IMsTscDebug IMsTscDebug; +#endif /* __IMsTscDebug_FWD_DEFINED__ */ + + +#ifndef __MsTscAx_FWD_DEFINED__ +#define __MsTscAx_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsTscAx MsTscAx; +#else +typedef struct MsTscAx MsTscAx; +#endif /* __cplusplus */ + +#endif /* __MsTscAx_FWD_DEFINED__ */ + + +#ifndef __MsRdpClient_FWD_DEFINED__ +#define __MsRdpClient_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsRdpClient MsRdpClient; +#else +typedef struct MsRdpClient MsRdpClient; +#endif /* __cplusplus */ + +#endif /* __MsRdpClient_FWD_DEFINED__ */ + + +#ifndef __MsRdpClient2_FWD_DEFINED__ +#define __MsRdpClient2_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsRdpClient2 MsRdpClient2; +#else +typedef struct MsRdpClient2 MsRdpClient2; +#endif /* __cplusplus */ + +#endif /* __MsRdpClient2_FWD_DEFINED__ */ + + +#ifndef __MsRdpClient3_FWD_DEFINED__ +#define __MsRdpClient3_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsRdpClient3 MsRdpClient3; +#else +typedef struct MsRdpClient3 MsRdpClient3; +#endif /* __cplusplus */ + +#endif /* __MsRdpClient3_FWD_DEFINED__ */ + + +#ifndef __MsRdpClient4_FWD_DEFINED__ +#define __MsRdpClient4_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsRdpClient4 MsRdpClient4; +#else +typedef struct MsRdpClient4 MsRdpClient4; +#endif /* __cplusplus */ + +#endif /* __MsRdpClient4_FWD_DEFINED__ */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + + +#ifndef __MSTSCLib_LIBRARY_DEFINED__ +#define __MSTSCLib_LIBRARY_DEFINED__ + +/* library MSTSCLib */ +/* [version][uuid] */ + + + + + + + + + + + + + + + + + + +typedef /* [public][public][public] */ +enum __MIDL___MIDL_itf_mstsax_0275_0001 + { autoReconnectContinueAutomatic = 0, + autoReconnectContinueStop = 1, + autoReconnectContinueManual = 2 + } AutoReconnectContinueState; + +typedef /* [public][public][public] */ +enum __MIDL_IMsRdpClient_0001 + { exDiscReasonNoInfo = 0, + exDiscReasonAPIInitiatedDisconnect = 1, + exDiscReasonAPIInitiatedLogoff = 2, + exDiscReasonServerIdleTimeout = 3, + exDiscReasonServerLogonTimeout = 4, + exDiscReasonReplacedByOtherConnection = 5, + exDiscReasonOutOfMemory = 6, + exDiscReasonServerDeniedConnection = 7, + exDiscReasonServerDeniedConnectionFips = 8, + exDiscReasonLicenseInternal = 256, + exDiscReasonLicenseNoLicenseServer = 257, + exDiscReasonLicenseNoLicense = 258, + exDiscReasonLicenseErrClientMsg = 259, + exDiscReasonLicenseHwidDoesntMatchLicense = 260, + exDiscReasonLicenseErrClientLicense = 261, + exDiscReasonLicenseCantFinishProtocol = 262, + exDiscReasonLicenseClientEndedProtocol = 263, + exDiscReasonLicenseErrClientEncryption = 264, + exDiscReasonLicenseCantUpgradeLicense = 265, + exDiscReasonLicenseNoRemoteConnections = 266, + exDiscReasonProtocolRangeStart = 4096, + exDiscReasonProtocolRangeEnd = 32767 + } ExtendedDisconnectReasonCode; + +typedef /* [public][public][public] */ +enum __MIDL_IMsRdpClient_0002 + { controlCloseCanProceed = 0, + controlCloseWaitForEvents = 1 + } ControlCloseStatus; + +typedef /* [custom][public] */ unsigned __int3264 UINT_PTR; + +typedef /* [custom][public] */ __int3264 LONG_PTR; + + +EXTERN_C const IID LIBID_MSTSCLib; + +#ifndef __IMsTscAxEvents_DISPINTERFACE_DEFINED__ +#define __IMsTscAxEvents_DISPINTERFACE_DEFINED__ + +/* dispinterface IMsTscAxEvents */ +/* [uuid] */ + + +EXTERN_C const IID DIID_IMsTscAxEvents; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("336D5562-EFA8-482E-8CB3-C5C0FC7A7DB6") + IMsTscAxEvents : public IDispatch + { + }; + +#else /* C style interface */ + + typedef struct IMsTscAxEventsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscAxEvents * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscAxEvents * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscAxEvents * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscAxEvents * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscAxEvents * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscAxEvents * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscAxEvents * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + END_INTERFACE + } IMsTscAxEventsVtbl; + + interface IMsTscAxEvents + { + CONST_VTBL struct IMsTscAxEventsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscAxEvents_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscAxEvents_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscAxEvents_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscAxEvents_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscAxEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscAxEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscAxEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* __IMsTscAxEvents_DISPINTERFACE_DEFINED__ */ + + +#ifndef __IMsTscAx_INTERFACE_DEFINED__ +#define __IMsTscAx_INTERFACE_DEFINED__ + +/* interface IMsTscAx */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsTscAx; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("8C11EFAE-92C3-11D1-BC1E-00C04FA31489") + IMsTscAx : public IDispatch + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Server( + /* [in] */ BSTR pServer) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Server( + /* [retval][out] */ BSTR *pServer) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Domain( + /* [in] */ BSTR pDomain) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Domain( + /* [retval][out] */ BSTR *pDomain) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_UserName( + /* [in] */ BSTR pUserName) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_UserName( + /* [retval][out] */ BSTR *pUserName) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DisconnectedText( + /* [in] */ BSTR pDisconnectedText) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DisconnectedText( + /* [retval][out] */ BSTR *pDisconnectedText) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectingText( + /* [in] */ BSTR pConnectingText) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectingText( + /* [retval][out] */ BSTR *pConnectingText) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Connected( + /* [retval][out] */ short *pIsConnected) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DesktopWidth( + /* [in] */ long pVal) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DesktopWidth( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DesktopHeight( + /* [in] */ long pVal) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DesktopHeight( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_StartConnected( + /* [in] */ long pfStartConnected) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_StartConnected( + /* [retval][out] */ long *pfStartConnected) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HorizontalScrollBarVisible( + /* [retval][out] */ long *pfHScrollVisible) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_VerticalScrollBarVisible( + /* [retval][out] */ long *pfVScrollVisible) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_FullScreenTitle( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CipherStrength( + /* [retval][out] */ long *pCipherStrength) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Version( + /* [retval][out] */ BSTR *pVersion) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SecuredSettingsEnabled( + /* [retval][out] */ long *pSecuredSettingsEnabled) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SecuredSettings( + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings( + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings) = 0; + + virtual /* [hidden][propget][id] */ HRESULT STDMETHODCALLTYPE get_Debugger( + /* [retval][out] */ IMsTscDebug **ppDebugger) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE Connect( void) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE Disconnect( void) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CreateVirtualChannels( + /* [in] */ BSTR newVal) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE SendOnVirtualChannel( + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscAxVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscAx * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscAx * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscAx * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscAx * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscAx * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscAx * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscAx * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsTscAx * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsTscAx * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsTscAx * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsTscAx * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsTscAx * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsTscAx * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsTscAx * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsTscAx * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsTscAx * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsTscAx * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsTscAx * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsTscAx * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsTscAx * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsTscAx * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsTscAx * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsTscAx * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsTscAx * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsTscAx * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsTscAx * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsTscAx * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsTscAx * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsTscAx * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsTscAx * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsTscAx * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + END_INTERFACE + } IMsTscAxVtbl; + + interface IMsTscAx + { + CONST_VTBL struct IMsTscAxVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscAx_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscAx_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscAx_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscAx_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscAx_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscAx_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscAx_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsTscAx_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsTscAx_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsTscAx_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsTscAx_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsTscAx_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsTscAx_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsTscAx_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsTscAx_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsTscAx_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsTscAx_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsTscAx_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsTscAx_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsTscAx_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsTscAx_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsTscAx_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsTscAx_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsTscAx_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsTscAx_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsTscAx_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsTscAx_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsTscAx_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsTscAx_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsTscAx_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsTscAx_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsTscAx_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsTscAx_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsTscAx_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsTscAx_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsTscAx_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsTscAx_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscAx_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClient_INTERFACE_DEFINED__ +#define __IMsRdpClient_INTERFACE_DEFINED__ + +/* interface IMsRdpClient */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClient; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("92B4A539-7115-4B7C-A5A9-E5D9EFC2780A") + IMsRdpClient : public IMsTscAx + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ColorDepth( + /* [in] */ long pcolorDepth) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ColorDepth( + /* [retval][out] */ long *pcolorDepth) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings2( + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SecuredSettings2( + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ExtendedDisconnectReason( + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_FullScreen( + /* [in] */ VARIANT_BOOL pfFullScreen) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_FullScreen( + /* [retval][out] */ VARIANT_BOOL *pfFullScreen) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE SetVirtualChannelOptions( + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetVirtualChannelOptions( + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE RequestClose( + /* [retval][out] */ ControlCloseStatus *pCloseStatus) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClient * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClient * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClient * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClient * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClient * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClient * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClient * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsRdpClient * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsRdpClient * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsRdpClient * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsRdpClient * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsRdpClient * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsRdpClient * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsRdpClient * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsRdpClient * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsRdpClient * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsRdpClient * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsRdpClient * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsRdpClient * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsRdpClient * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsRdpClient * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsRdpClient * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsRdpClient * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsRdpClient * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsRdpClient * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsRdpClient * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsRdpClient * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsRdpClient * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsRdpClient * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsRdpClient * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsRdpClient * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ColorDepth )( + IMsRdpClient * This, + /* [in] */ long pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ColorDepth )( + IMsRdpClient * This, + /* [retval][out] */ long *pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings2 )( + IMsRdpClient * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings2 )( + IMsRdpClient * This, + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExtendedDisconnectReason )( + IMsRdpClient * This, + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClient * This, + /* [in] */ VARIANT_BOOL pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClient * This, + /* [retval][out] */ VARIANT_BOOL *pfFullScreen); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SetVirtualChannelOptions )( + IMsRdpClient * This, + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *GetVirtualChannelOptions )( + IMsRdpClient * This, + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *RequestClose )( + IMsRdpClient * This, + /* [retval][out] */ ControlCloseStatus *pCloseStatus); + + END_INTERFACE + } IMsRdpClientVtbl; + + interface IMsRdpClient + { + CONST_VTBL struct IMsRdpClientVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClient_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClient_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClient_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClient_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClient_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClient_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClient_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClient_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsRdpClient_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsRdpClient_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsRdpClient_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsRdpClient_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsRdpClient_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsRdpClient_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsRdpClient_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsRdpClient_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsRdpClient_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsRdpClient_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsRdpClient_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsRdpClient_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsRdpClient_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsRdpClient_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsRdpClient_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsRdpClient_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsRdpClient_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsRdpClient_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsRdpClient_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsRdpClient_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsRdpClient_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsRdpClient_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsRdpClient_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + + +#define IMsRdpClient_put_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> put_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient_get_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> get_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient_get_AdvancedSettings2(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings2(This,ppAdvSettings) ) + +#define IMsRdpClient_get_SecuredSettings2(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings2(This,ppSecuredSettings) ) + +#define IMsRdpClient_get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) \ + ( (This)->lpVtbl -> get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) ) + +#define IMsRdpClient_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient_SetVirtualChannelOptions(This,chanName,chanOptions) \ + ( (This)->lpVtbl -> SetVirtualChannelOptions(This,chanName,chanOptions) ) + +#define IMsRdpClient_GetVirtualChannelOptions(This,chanName,pChanOptions) \ + ( (This)->lpVtbl -> GetVirtualChannelOptions(This,chanName,pChanOptions) ) + +#define IMsRdpClient_RequestClose(This,pCloseStatus) \ + ( (This)->lpVtbl -> RequestClose(This,pCloseStatus) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClient_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClient2_INTERFACE_DEFINED__ +#define __IMsRdpClient2_INTERFACE_DEFINED__ + +/* interface IMsRdpClient2 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClient2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("E7E17DC4-3B71-4BA7-A8E6-281FFADCA28F") + IMsRdpClient2 : public IMsRdpClient + { + public: + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings3( + /* [retval][out] */ IMsRdpClientAdvancedSettings2 **ppAdvSettings) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectedStatusText( + /* [in] */ BSTR pConnectedStatusText) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectedStatusText( + /* [retval][out] */ BSTR *pConnectedStatusText) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClient2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClient2 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClient2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClient2 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClient2 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClient2 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClient2 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClient2 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsRdpClient2 * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsRdpClient2 * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsRdpClient2 * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsRdpClient2 * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsRdpClient2 * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsRdpClient2 * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsRdpClient2 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsRdpClient2 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsRdpClient2 * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsRdpClient2 * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsRdpClient2 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsRdpClient2 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsRdpClient2 * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsRdpClient2 * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ColorDepth )( + IMsRdpClient2 * This, + /* [in] */ long pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ColorDepth )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings2 )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings2 )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExtendedDisconnectReason )( + IMsRdpClient2 * This, + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClient2 * This, + /* [in] */ VARIANT_BOOL pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClient2 * This, + /* [retval][out] */ VARIANT_BOOL *pfFullScreen); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SetVirtualChannelOptions )( + IMsRdpClient2 * This, + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *GetVirtualChannelOptions )( + IMsRdpClient2 * This, + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *RequestClose )( + IMsRdpClient2 * This, + /* [retval][out] */ ControlCloseStatus *pCloseStatus); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings3 )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings2 **ppAdvSettings); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectedStatusText )( + IMsRdpClient2 * This, + /* [in] */ BSTR pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectedStatusText )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pConnectedStatusText); + + END_INTERFACE + } IMsRdpClient2Vtbl; + + interface IMsRdpClient2 + { + CONST_VTBL struct IMsRdpClient2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClient2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClient2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClient2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClient2_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClient2_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClient2_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClient2_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClient2_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsRdpClient2_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsRdpClient2_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsRdpClient2_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsRdpClient2_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsRdpClient2_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsRdpClient2_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient2_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient2_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient2_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient2_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsRdpClient2_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsRdpClient2_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsRdpClient2_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsRdpClient2_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsRdpClient2_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient2_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient2_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsRdpClient2_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsRdpClient2_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsRdpClient2_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsRdpClient2_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsRdpClient2_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsRdpClient2_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsRdpClient2_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsRdpClient2_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsRdpClient2_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsRdpClient2_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsRdpClient2_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsRdpClient2_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + + +#define IMsRdpClient2_put_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> put_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient2_get_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> get_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient2_get_AdvancedSettings2(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings2(This,ppAdvSettings) ) + +#define IMsRdpClient2_get_SecuredSettings2(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings2(This,ppSecuredSettings) ) + +#define IMsRdpClient2_get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) \ + ( (This)->lpVtbl -> get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) ) + +#define IMsRdpClient2_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient2_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient2_SetVirtualChannelOptions(This,chanName,chanOptions) \ + ( (This)->lpVtbl -> SetVirtualChannelOptions(This,chanName,chanOptions) ) + +#define IMsRdpClient2_GetVirtualChannelOptions(This,chanName,pChanOptions) \ + ( (This)->lpVtbl -> GetVirtualChannelOptions(This,chanName,pChanOptions) ) + +#define IMsRdpClient2_RequestClose(This,pCloseStatus) \ + ( (This)->lpVtbl -> RequestClose(This,pCloseStatus) ) + + +#define IMsRdpClient2_get_AdvancedSettings3(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings3(This,ppAdvSettings) ) + +#define IMsRdpClient2_put_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> put_ConnectedStatusText(This,pConnectedStatusText) ) + +#define IMsRdpClient2_get_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> get_ConnectedStatusText(This,pConnectedStatusText) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClient2_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClient3_INTERFACE_DEFINED__ +#define __IMsRdpClient3_INTERFACE_DEFINED__ + +/* interface IMsRdpClient3 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClient3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("91B7CBC5-A72E-4FA0-9300-D647D7E897FF") + IMsRdpClient3 : public IMsRdpClient2 + { + public: + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings4( + /* [retval][out] */ IMsRdpClientAdvancedSettings3 **ppAdvSettings) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClient3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClient3 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClient3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClient3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClient3 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClient3 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClient3 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClient3 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsRdpClient3 * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsRdpClient3 * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsRdpClient3 * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsRdpClient3 * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsRdpClient3 * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsRdpClient3 * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsRdpClient3 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsRdpClient3 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsRdpClient3 * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsRdpClient3 * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsRdpClient3 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsRdpClient3 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsRdpClient3 * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsRdpClient3 * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ColorDepth )( + IMsRdpClient3 * This, + /* [in] */ long pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ColorDepth )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings2 )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings2 )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExtendedDisconnectReason )( + IMsRdpClient3 * This, + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClient3 * This, + /* [in] */ VARIANT_BOOL pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClient3 * This, + /* [retval][out] */ VARIANT_BOOL *pfFullScreen); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SetVirtualChannelOptions )( + IMsRdpClient3 * This, + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *GetVirtualChannelOptions )( + IMsRdpClient3 * This, + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *RequestClose )( + IMsRdpClient3 * This, + /* [retval][out] */ ControlCloseStatus *pCloseStatus); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings3 )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings2 **ppAdvSettings); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectedStatusText )( + IMsRdpClient3 * This, + /* [in] */ BSTR pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectedStatusText )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings4 )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings3 **ppAdvSettings); + + END_INTERFACE + } IMsRdpClient3Vtbl; + + interface IMsRdpClient3 + { + CONST_VTBL struct IMsRdpClient3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClient3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClient3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClient3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClient3_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClient3_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClient3_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClient3_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClient3_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsRdpClient3_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsRdpClient3_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsRdpClient3_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsRdpClient3_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsRdpClient3_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsRdpClient3_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient3_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient3_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient3_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient3_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsRdpClient3_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsRdpClient3_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsRdpClient3_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsRdpClient3_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsRdpClient3_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient3_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient3_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsRdpClient3_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsRdpClient3_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsRdpClient3_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsRdpClient3_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsRdpClient3_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsRdpClient3_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsRdpClient3_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsRdpClient3_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsRdpClient3_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsRdpClient3_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsRdpClient3_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsRdpClient3_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + + +#define IMsRdpClient3_put_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> put_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient3_get_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> get_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient3_get_AdvancedSettings2(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings2(This,ppAdvSettings) ) + +#define IMsRdpClient3_get_SecuredSettings2(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings2(This,ppSecuredSettings) ) + +#define IMsRdpClient3_get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) \ + ( (This)->lpVtbl -> get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) ) + +#define IMsRdpClient3_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient3_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient3_SetVirtualChannelOptions(This,chanName,chanOptions) \ + ( (This)->lpVtbl -> SetVirtualChannelOptions(This,chanName,chanOptions) ) + +#define IMsRdpClient3_GetVirtualChannelOptions(This,chanName,pChanOptions) \ + ( (This)->lpVtbl -> GetVirtualChannelOptions(This,chanName,pChanOptions) ) + +#define IMsRdpClient3_RequestClose(This,pCloseStatus) \ + ( (This)->lpVtbl -> RequestClose(This,pCloseStatus) ) + + +#define IMsRdpClient3_get_AdvancedSettings3(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings3(This,ppAdvSettings) ) + +#define IMsRdpClient3_put_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> put_ConnectedStatusText(This,pConnectedStatusText) ) + +#define IMsRdpClient3_get_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> get_ConnectedStatusText(This,pConnectedStatusText) ) + + +#define IMsRdpClient3_get_AdvancedSettings4(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings4(This,ppAdvSettings) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClient3_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClient4_INTERFACE_DEFINED__ +#define __IMsRdpClient4_INTERFACE_DEFINED__ + +/* interface IMsRdpClient4 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClient4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("095E0738-D97D-488B-B9F6-DD0E8D66C0DE") + IMsRdpClient4 : public IMsRdpClient3 + { + public: + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings5( + /* [retval][out] */ IMsRdpClientAdvancedSettings4 **ppAdvSettings5) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClient4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClient4 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClient4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClient4 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClient4 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClient4 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClient4 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClient4 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsRdpClient4 * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsRdpClient4 * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsRdpClient4 * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsRdpClient4 * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsRdpClient4 * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsRdpClient4 * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsRdpClient4 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsRdpClient4 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsRdpClient4 * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsRdpClient4 * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsRdpClient4 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsRdpClient4 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsRdpClient4 * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsRdpClient4 * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ColorDepth )( + IMsRdpClient4 * This, + /* [in] */ long pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ColorDepth )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings2 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings2 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExtendedDisconnectReason )( + IMsRdpClient4 * This, + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClient4 * This, + /* [in] */ VARIANT_BOOL pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClient4 * This, + /* [retval][out] */ VARIANT_BOOL *pfFullScreen); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SetVirtualChannelOptions )( + IMsRdpClient4 * This, + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *GetVirtualChannelOptions )( + IMsRdpClient4 * This, + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *RequestClose )( + IMsRdpClient4 * This, + /* [retval][out] */ ControlCloseStatus *pCloseStatus); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings3 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings2 **ppAdvSettings); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectedStatusText )( + IMsRdpClient4 * This, + /* [in] */ BSTR pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectedStatusText )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings4 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings3 **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings5 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings4 **ppAdvSettings5); + + END_INTERFACE + } IMsRdpClient4Vtbl; + + interface IMsRdpClient4 + { + CONST_VTBL struct IMsRdpClient4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClient4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClient4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClient4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClient4_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClient4_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClient4_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClient4_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClient4_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsRdpClient4_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsRdpClient4_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsRdpClient4_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsRdpClient4_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsRdpClient4_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsRdpClient4_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient4_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient4_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient4_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient4_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsRdpClient4_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsRdpClient4_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsRdpClient4_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsRdpClient4_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsRdpClient4_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient4_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient4_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsRdpClient4_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsRdpClient4_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsRdpClient4_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsRdpClient4_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsRdpClient4_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsRdpClient4_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsRdpClient4_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsRdpClient4_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsRdpClient4_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsRdpClient4_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsRdpClient4_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsRdpClient4_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + + +#define IMsRdpClient4_put_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> put_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient4_get_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> get_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient4_get_AdvancedSettings2(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings2(This,ppAdvSettings) ) + +#define IMsRdpClient4_get_SecuredSettings2(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings2(This,ppSecuredSettings) ) + +#define IMsRdpClient4_get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) \ + ( (This)->lpVtbl -> get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) ) + +#define IMsRdpClient4_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient4_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient4_SetVirtualChannelOptions(This,chanName,chanOptions) \ + ( (This)->lpVtbl -> SetVirtualChannelOptions(This,chanName,chanOptions) ) + +#define IMsRdpClient4_GetVirtualChannelOptions(This,chanName,pChanOptions) \ + ( (This)->lpVtbl -> GetVirtualChannelOptions(This,chanName,pChanOptions) ) + +#define IMsRdpClient4_RequestClose(This,pCloseStatus) \ + ( (This)->lpVtbl -> RequestClose(This,pCloseStatus) ) + + +#define IMsRdpClient4_get_AdvancedSettings3(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings3(This,ppAdvSettings) ) + +#define IMsRdpClient4_put_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> put_ConnectedStatusText(This,pConnectedStatusText) ) + +#define IMsRdpClient4_get_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> get_ConnectedStatusText(This,pConnectedStatusText) ) + + +#define IMsRdpClient4_get_AdvancedSettings4(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings4(This,ppAdvSettings) ) + + +#define IMsRdpClient4_get_AdvancedSettings5(This,ppAdvSettings5) \ + ( (This)->lpVtbl -> get_AdvancedSettings5(This,ppAdvSettings5) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClient4_INTERFACE_DEFINED__ */ + + +#ifndef __IMsTscNonScriptable_INTERFACE_DEFINED__ +#define __IMsTscNonScriptable_INTERFACE_DEFINED__ + +/* interface IMsTscNonScriptable */ +/* [object][uuid] */ + + +EXTERN_C const IID IID_IMsTscNonScriptable; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C1E6743A-41C1-4A74-832A-0DD06C1C7A0E") + IMsTscNonScriptable : public IUnknown + { + public: + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_ClearTextPassword( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_PortablePassword( + /* [in] */ BSTR pPortablePass) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_PortablePassword( + /* [retval][out] */ BSTR *pPortablePass) = 0; + + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_PortableSalt( + /* [in] */ BSTR pPortableSalt) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_PortableSalt( + /* [retval][out] */ BSTR *pPortableSalt) = 0; + + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_BinaryPassword( + /* [in] */ BSTR pBinaryPassword) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_BinaryPassword( + /* [retval][out] */ BSTR *pBinaryPassword) = 0; + + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_BinarySalt( + /* [in] */ BSTR pSalt) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_BinarySalt( + /* [retval][out] */ BSTR *pSalt) = 0; + + virtual HRESULT STDMETHODCALLTYPE ResetPassword( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscNonScriptableVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscNonScriptable * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscNonScriptable * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscNonScriptable * This); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsTscNonScriptable * This, + /* [in] */ BSTR rhs); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortablePassword )( + IMsTscNonScriptable * This, + /* [in] */ BSTR pPortablePass); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortablePassword )( + IMsTscNonScriptable * This, + /* [retval][out] */ BSTR *pPortablePass); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortableSalt )( + IMsTscNonScriptable * This, + /* [in] */ BSTR pPortableSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortableSalt )( + IMsTscNonScriptable * This, + /* [retval][out] */ BSTR *pPortableSalt); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinaryPassword )( + IMsTscNonScriptable * This, + /* [in] */ BSTR pBinaryPassword); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinaryPassword )( + IMsTscNonScriptable * This, + /* [retval][out] */ BSTR *pBinaryPassword); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinarySalt )( + IMsTscNonScriptable * This, + /* [in] */ BSTR pSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinarySalt )( + IMsTscNonScriptable * This, + /* [retval][out] */ BSTR *pSalt); + + HRESULT ( STDMETHODCALLTYPE *ResetPassword )( + IMsTscNonScriptable * This); + + END_INTERFACE + } IMsTscNonScriptableVtbl; + + interface IMsTscNonScriptable + { + CONST_VTBL struct IMsTscNonScriptableVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscNonScriptable_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscNonScriptable_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscNonScriptable_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscNonScriptable_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsTscNonScriptable_put_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> put_PortablePassword(This,pPortablePass) ) + +#define IMsTscNonScriptable_get_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> get_PortablePassword(This,pPortablePass) ) + +#define IMsTscNonScriptable_put_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> put_PortableSalt(This,pPortableSalt) ) + +#define IMsTscNonScriptable_get_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> get_PortableSalt(This,pPortableSalt) ) + +#define IMsTscNonScriptable_put_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> put_BinaryPassword(This,pBinaryPassword) ) + +#define IMsTscNonScriptable_get_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> get_BinaryPassword(This,pBinaryPassword) ) + +#define IMsTscNonScriptable_put_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> put_BinarySalt(This,pSalt) ) + +#define IMsTscNonScriptable_get_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> get_BinarySalt(This,pSalt) ) + +#define IMsTscNonScriptable_ResetPassword(This) \ + ( (This)->lpVtbl -> ResetPassword(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscNonScriptable_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientNonScriptable_INTERFACE_DEFINED__ +#define __IMsRdpClientNonScriptable_INTERFACE_DEFINED__ + +/* interface IMsRdpClientNonScriptable */ +/* [object][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientNonScriptable; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2F079C4C-87B2-4AFD-97AB-20CDB43038AE") + IMsRdpClientNonScriptable : public IMsTscNonScriptable + { + public: + virtual HRESULT STDMETHODCALLTYPE NotifyRedirectDeviceChange( + /* [in] */ UINT_PTR wParam, + /* [in] */ LONG_PTR lParam) = 0; + + virtual HRESULT STDMETHODCALLTYPE SendKeys( + /* [in] */ long numKeys, + /* [in] */ VARIANT_BOOL *pbArrayKeyUp, + /* [in] */ long *plKeyData) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientNonScriptableVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientNonScriptable * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientNonScriptable * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientNonScriptable * This); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR rhs); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortablePassword )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR pPortablePass); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortablePassword )( + IMsRdpClientNonScriptable * This, + /* [retval][out] */ BSTR *pPortablePass); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortableSalt )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR pPortableSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortableSalt )( + IMsRdpClientNonScriptable * This, + /* [retval][out] */ BSTR *pPortableSalt); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinaryPassword )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR pBinaryPassword); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinaryPassword )( + IMsRdpClientNonScriptable * This, + /* [retval][out] */ BSTR *pBinaryPassword); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinarySalt )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR pSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinarySalt )( + IMsRdpClientNonScriptable * This, + /* [retval][out] */ BSTR *pSalt); + + HRESULT ( STDMETHODCALLTYPE *ResetPassword )( + IMsRdpClientNonScriptable * This); + + HRESULT ( STDMETHODCALLTYPE *NotifyRedirectDeviceChange )( + IMsRdpClientNonScriptable * This, + /* [in] */ UINT_PTR wParam, + /* [in] */ LONG_PTR lParam); + + HRESULT ( STDMETHODCALLTYPE *SendKeys )( + IMsRdpClientNonScriptable * This, + /* [in] */ long numKeys, + /* [in] */ VARIANT_BOOL *pbArrayKeyUp, + /* [in] */ long *plKeyData); + + END_INTERFACE + } IMsRdpClientNonScriptableVtbl; + + interface IMsRdpClientNonScriptable + { + CONST_VTBL struct IMsRdpClientNonScriptableVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientNonScriptable_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientNonScriptable_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientNonScriptable_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientNonScriptable_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientNonScriptable_put_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> put_PortablePassword(This,pPortablePass) ) + +#define IMsRdpClientNonScriptable_get_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> get_PortablePassword(This,pPortablePass) ) + +#define IMsRdpClientNonScriptable_put_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> put_PortableSalt(This,pPortableSalt) ) + +#define IMsRdpClientNonScriptable_get_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> get_PortableSalt(This,pPortableSalt) ) + +#define IMsRdpClientNonScriptable_put_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> put_BinaryPassword(This,pBinaryPassword) ) + +#define IMsRdpClientNonScriptable_get_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> get_BinaryPassword(This,pBinaryPassword) ) + +#define IMsRdpClientNonScriptable_put_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> put_BinarySalt(This,pSalt) ) + +#define IMsRdpClientNonScriptable_get_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> get_BinarySalt(This,pSalt) ) + +#define IMsRdpClientNonScriptable_ResetPassword(This) \ + ( (This)->lpVtbl -> ResetPassword(This) ) + + +#define IMsRdpClientNonScriptable_NotifyRedirectDeviceChange(This,wParam,lParam) \ + ( (This)->lpVtbl -> NotifyRedirectDeviceChange(This,wParam,lParam) ) + +#define IMsRdpClientNonScriptable_SendKeys(This,numKeys,pbArrayKeyUp,plKeyData) \ + ( (This)->lpVtbl -> SendKeys(This,numKeys,pbArrayKeyUp,plKeyData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClientNonScriptable_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientNonScriptable2_INTERFACE_DEFINED__ +#define __IMsRdpClientNonScriptable2_INTERFACE_DEFINED__ + +/* interface IMsRdpClientNonScriptable2 */ +/* [object][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientNonScriptable2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("17A5E535-4072-4FA4-AF32-C8D0D47345E9") + IMsRdpClientNonScriptable2 : public IMsRdpClientNonScriptable + { + public: + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_UIParentWindowHandle( + /* [in] */ HWND phwndUIParentWindowHandle) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_UIParentWindowHandle( + /* [retval][out] */ HWND *phwndUIParentWindowHandle) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientNonScriptable2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientNonScriptable2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientNonScriptable2 * This); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR rhs); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortablePassword )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR pPortablePass); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortablePassword )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ BSTR *pPortablePass); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortableSalt )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR pPortableSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortableSalt )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ BSTR *pPortableSalt); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinaryPassword )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR pBinaryPassword); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinaryPassword )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ BSTR *pBinaryPassword); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinarySalt )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR pSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinarySalt )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ BSTR *pSalt); + + HRESULT ( STDMETHODCALLTYPE *ResetPassword )( + IMsRdpClientNonScriptable2 * This); + + HRESULT ( STDMETHODCALLTYPE *NotifyRedirectDeviceChange )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ UINT_PTR wParam, + /* [in] */ LONG_PTR lParam); + + HRESULT ( STDMETHODCALLTYPE *SendKeys )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ long numKeys, + /* [in] */ VARIANT_BOOL *pbArrayKeyUp, + /* [in] */ long *plKeyData); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_UIParentWindowHandle )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ HWND phwndUIParentWindowHandle); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_UIParentWindowHandle )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ HWND *phwndUIParentWindowHandle); + + END_INTERFACE + } IMsRdpClientNonScriptable2Vtbl; + + interface IMsRdpClientNonScriptable2 + { + CONST_VTBL struct IMsRdpClientNonScriptable2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientNonScriptable2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientNonScriptable2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientNonScriptable2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientNonScriptable2_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientNonScriptable2_put_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> put_PortablePassword(This,pPortablePass) ) + +#define IMsRdpClientNonScriptable2_get_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> get_PortablePassword(This,pPortablePass) ) + +#define IMsRdpClientNonScriptable2_put_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> put_PortableSalt(This,pPortableSalt) ) + +#define IMsRdpClientNonScriptable2_get_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> get_PortableSalt(This,pPortableSalt) ) + +#define IMsRdpClientNonScriptable2_put_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> put_BinaryPassword(This,pBinaryPassword) ) + +#define IMsRdpClientNonScriptable2_get_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> get_BinaryPassword(This,pBinaryPassword) ) + +#define IMsRdpClientNonScriptable2_put_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> put_BinarySalt(This,pSalt) ) + +#define IMsRdpClientNonScriptable2_get_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> get_BinarySalt(This,pSalt) ) + +#define IMsRdpClientNonScriptable2_ResetPassword(This) \ + ( (This)->lpVtbl -> ResetPassword(This) ) + + +#define IMsRdpClientNonScriptable2_NotifyRedirectDeviceChange(This,wParam,lParam) \ + ( (This)->lpVtbl -> NotifyRedirectDeviceChange(This,wParam,lParam) ) + +#define IMsRdpClientNonScriptable2_SendKeys(This,numKeys,pbArrayKeyUp,plKeyData) \ + ( (This)->lpVtbl -> SendKeys(This,numKeys,pbArrayKeyUp,plKeyData) ) + + +#define IMsRdpClientNonScriptable2_put_UIParentWindowHandle(This,phwndUIParentWindowHandle) \ + ( (This)->lpVtbl -> put_UIParentWindowHandle(This,phwndUIParentWindowHandle) ) + +#define IMsRdpClientNonScriptable2_get_UIParentWindowHandle(This,phwndUIParentWindowHandle) \ + ( (This)->lpVtbl -> get_UIParentWindowHandle(This,phwndUIParentWindowHandle) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClientNonScriptable2_INTERFACE_DEFINED__ */ + + +#ifndef __IMsTscAdvancedSettings_INTERFACE_DEFINED__ +#define __IMsTscAdvancedSettings_INTERFACE_DEFINED__ + +/* interface IMsTscAdvancedSettings */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsTscAdvancedSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("809945CC-4B3B-4A92-A6B0-DBF9B5F2EF2D") + IMsTscAdvancedSettings : public IDispatch + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Compress( + /* [in] */ long pcompress) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Compress( + /* [retval][out] */ long *pcompress) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapPeristence( + /* [in] */ long pbitmapPeristence) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapPeristence( + /* [retval][out] */ long *pbitmapPeristence) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_allowBackgroundInput( + /* [in] */ long pallowBackgroundInput) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_allowBackgroundInput( + /* [retval][out] */ long *pallowBackgroundInput) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyBoardLayoutStr( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PluginDlls( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_IconFile( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_IconIndex( + /* [in] */ long rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ContainerHandledFullScreen( + /* [in] */ long pContainerHandledFullScreen) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ContainerHandledFullScreen( + /* [retval][out] */ long *pContainerHandledFullScreen) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DisableRdpdr( + /* [in] */ long pDisableRdpdr) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DisableRdpdr( + /* [retval][out] */ long *pDisableRdpdr) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscAdvancedSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscAdvancedSettings * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscAdvancedSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscAdvancedSettings * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscAdvancedSettings * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscAdvancedSettings * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscAdvancedSettings * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscAdvancedSettings * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsTscAdvancedSettings * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsTscAdvancedSettings * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsTscAdvancedSettings * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsTscAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsTscAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsTscAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsTscAdvancedSettings * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsTscAdvancedSettings * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsTscAdvancedSettings * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pDisableRdpdr); + + END_INTERFACE + } IMsTscAdvancedSettingsVtbl; + + interface IMsTscAdvancedSettings + { + CONST_VTBL struct IMsTscAdvancedSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscAdvancedSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscAdvancedSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscAdvancedSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscAdvancedSettings_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscAdvancedSettings_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscAdvancedSettings_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscAdvancedSettings_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsTscAdvancedSettings_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsTscAdvancedSettings_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsTscAdvancedSettings_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsTscAdvancedSettings_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsTscAdvancedSettings_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsTscAdvancedSettings_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsTscAdvancedSettings_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsTscAdvancedSettings_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsTscAdvancedSettings_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsTscAdvancedSettings_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsTscAdvancedSettings_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsTscAdvancedSettings_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsTscAdvancedSettings_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsTscAdvancedSettings_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscAdvancedSettings_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings_INTERFACE_DEFINED__ +#define __IMsRdpClientAdvancedSettings_INTERFACE_DEFINED__ + +/* interface IMsRdpClientAdvancedSettings */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientAdvancedSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3C65B4AB-12B3-465B-ACD4-B8DAD3BFF9E2") + IMsRdpClientAdvancedSettings : public IMsTscAdvancedSettings + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SmoothScroll( + /* [in] */ long psmoothScroll) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SmoothScroll( + /* [retval][out] */ long *psmoothScroll) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_AcceleratorPassthrough( + /* [in] */ long pacceleratorPassthrough) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AcceleratorPassthrough( + /* [retval][out] */ long *pacceleratorPassthrough) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ShadowBitmap( + /* [in] */ long pshadowBitmap) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ShadowBitmap( + /* [retval][out] */ long *pshadowBitmap) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_TransportType( + /* [in] */ long ptransportType) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_TransportType( + /* [retval][out] */ long *ptransportType) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SasSequence( + /* [in] */ long psasSequence) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SasSequence( + /* [retval][out] */ long *psasSequence) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_EncryptionEnabled( + /* [in] */ long pencryptionEnabled) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_EncryptionEnabled( + /* [retval][out] */ long *pencryptionEnabled) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DedicatedTerminal( + /* [in] */ long pdedicatedTerminal) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DedicatedTerminal( + /* [retval][out] */ long *pdedicatedTerminal) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RDPPort( + /* [in] */ long prdpPort) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RDPPort( + /* [retval][out] */ long *prdpPort) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_EnableMouse( + /* [in] */ long penableMouse) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_EnableMouse( + /* [retval][out] */ long *penableMouse) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DisableCtrlAltDel( + /* [in] */ long pdisableCtrlAltDel) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DisableCtrlAltDel( + /* [retval][out] */ long *pdisableCtrlAltDel) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_EnableWindowsKey( + /* [in] */ long penableWindowsKey) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_EnableWindowsKey( + /* [retval][out] */ long *penableWindowsKey) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DoubleClickDetect( + /* [in] */ long pdoubleClickDetect) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DoubleClickDetect( + /* [retval][out] */ long *pdoubleClickDetect) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MaximizeShell( + /* [in] */ long pmaximizeShell) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MaximizeShell( + /* [retval][out] */ long *pmaximizeShell) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyFullScreen( + /* [in] */ long photKeyFullScreen) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyFullScreen( + /* [retval][out] */ long *photKeyFullScreen) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyCtrlEsc( + /* [in] */ long photKeyCtrlEsc) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyCtrlEsc( + /* [retval][out] */ long *photKeyCtrlEsc) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyAltEsc( + /* [in] */ long photKeyAltEsc) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyAltEsc( + /* [retval][out] */ long *photKeyAltEsc) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyAltTab( + /* [in] */ long photKeyAltTab) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyAltTab( + /* [retval][out] */ long *photKeyAltTab) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyAltShiftTab( + /* [in] */ long photKeyAltShiftTab) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyAltShiftTab( + /* [retval][out] */ long *photKeyAltShiftTab) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyAltSpace( + /* [in] */ long photKeyAltSpace) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyAltSpace( + /* [retval][out] */ long *photKeyAltSpace) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyCtrlAltDel( + /* [in] */ long photKeyCtrlAltDel) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyCtrlAltDel( + /* [retval][out] */ long *photKeyCtrlAltDel) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_orderDrawThreshold( + /* [in] */ long porderDrawThreshold) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_orderDrawThreshold( + /* [retval][out] */ long *porderDrawThreshold) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapCacheSize( + /* [in] */ long pbitmapCacheSize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapCacheSize( + /* [retval][out] */ long *pbitmapCacheSize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapVirtualCacheSize( + /* [in] */ long pbitmapVirtualCacheSize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapVirtualCacheSize( + /* [retval][out] */ long *pbitmapVirtualCacheSize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ScaleBitmapCachesByBPP( + /* [in] */ long pbScale) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ScaleBitmapCachesByBPP( + /* [retval][out] */ long *pbScale) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_NumBitmapCaches( + /* [in] */ long pnumBitmapCaches) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_NumBitmapCaches( + /* [retval][out] */ long *pnumBitmapCaches) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_CachePersistenceActive( + /* [in] */ long pcachePersistenceActive) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CachePersistenceActive( + /* [retval][out] */ long *pcachePersistenceActive) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PersistCacheDirectory( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_brushSupportLevel( + /* [in] */ long pbrushSupportLevel) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_brushSupportLevel( + /* [retval][out] */ long *pbrushSupportLevel) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_minInputSendInterval( + /* [in] */ long pminInputSendInterval) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_minInputSendInterval( + /* [retval][out] */ long *pminInputSendInterval) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_InputEventsAtOnce( + /* [in] */ long pinputEventsAtOnce) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_InputEventsAtOnce( + /* [retval][out] */ long *pinputEventsAtOnce) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_maxEventCount( + /* [in] */ long pmaxEventCount) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_maxEventCount( + /* [retval][out] */ long *pmaxEventCount) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_keepAliveInterval( + /* [in] */ long pkeepAliveInterval) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_keepAliveInterval( + /* [retval][out] */ long *pkeepAliveInterval) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_shutdownTimeout( + /* [in] */ long pshutdownTimeout) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_shutdownTimeout( + /* [retval][out] */ long *pshutdownTimeout) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_overallConnectionTimeout( + /* [in] */ long poverallConnectionTimeout) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_overallConnectionTimeout( + /* [retval][out] */ long *poverallConnectionTimeout) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_singleConnectionTimeout( + /* [in] */ long psingleConnectionTimeout) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_singleConnectionTimeout( + /* [retval][out] */ long *psingleConnectionTimeout) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyboardType( + /* [in] */ long pkeyboardType) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_KeyboardType( + /* [retval][out] */ long *pkeyboardType) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyboardSubType( + /* [in] */ long pkeyboardSubType) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_KeyboardSubType( + /* [retval][out] */ long *pkeyboardSubType) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyboardFunctionKey( + /* [in] */ long pkeyboardFunctionKey) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_KeyboardFunctionKey( + /* [retval][out] */ long *pkeyboardFunctionKey) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_WinceFixedPalette( + /* [in] */ long pwinceFixedPalette) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_WinceFixedPalette( + /* [retval][out] */ long *pwinceFixedPalette) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectToServerConsole( + /* [in] */ VARIANT_BOOL pConnectToConsole) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectToServerConsole( + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapPersistence( + /* [in] */ long pbitmapPersistence) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapPersistence( + /* [retval][out] */ long *pbitmapPersistence) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MinutesToIdleTimeout( + /* [in] */ long pminutesToIdleTimeout) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MinutesToIdleTimeout( + /* [retval][out] */ long *pminutesToIdleTimeout) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SmartSizing( + /* [in] */ VARIANT_BOOL pfSmartSizing) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SmartSizing( + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RdpdrLocalPrintingDocName( + /* [in] */ BSTR pLocalPrintingDocName) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RdpdrLocalPrintingDocName( + /* [retval][out] */ BSTR *pLocalPrintingDocName) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RdpdrClipCleanTempDirString( + /* [in] */ BSTR clipCleanTempDirString) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RdpdrClipCleanTempDirString( + /* [retval][out] */ BSTR *clipCleanTempDirString) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RdpdrClipPasteInfoString( + /* [in] */ BSTR clipPasteInfoString) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RdpdrClipPasteInfoString( + /* [retval][out] */ BSTR *clipPasteInfoString) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ClearTextPassword( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DisplayConnectionBar( + /* [in] */ VARIANT_BOOL pDisplayConnectionBar) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DisplayConnectionBar( + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PinConnectionBar( + /* [in] */ VARIANT_BOOL pPinConnectionBar) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_PinConnectionBar( + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_GrabFocusOnConnect( + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_GrabFocusOnConnect( + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_LoadBalanceInfo( + /* [in] */ BSTR pLBInfo) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_LoadBalanceInfo( + /* [retval][out] */ BSTR *pLBInfo) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RedirectDrives( + /* [in] */ VARIANT_BOOL pRedirectDrives) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RedirectDrives( + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RedirectPrinters( + /* [in] */ VARIANT_BOOL pRedirectPrinters) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RedirectPrinters( + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RedirectPorts( + /* [in] */ VARIANT_BOOL pRedirectPorts) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RedirectPorts( + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RedirectSmartCards( + /* [in] */ VARIANT_BOOL pRedirectSmartCards) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RedirectSmartCards( + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapVirtualCache16BppSize( + /* [in] */ long pBitmapVirtualCache16BppSize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapVirtualCache16BppSize( + /* [retval][out] */ long *pBitmapVirtualCache16BppSize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapVirtualCache24BppSize( + /* [in] */ long pBitmapVirtualCache24BppSize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapVirtualCache24BppSize( + /* [retval][out] */ long *pBitmapVirtualCache24BppSize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PerformanceFlags( + /* [in] */ long pDisableList) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_PerformanceFlags( + /* [retval][out] */ long *pDisableList) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectWithEndpoint( + /* [in] */ VARIANT *rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_NotifyTSPublicKey( + /* [in] */ VARIANT_BOOL pfNotify) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_NotifyTSPublicKey( + /* [retval][out] */ VARIANT_BOOL *pfNotify) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientAdvancedSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientAdvancedSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientAdvancedSettings * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientAdvancedSettings * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pDisableRdpdr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmoothScroll )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long psmoothScroll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmoothScroll )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *psmoothScroll); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pacceleratorPassthrough); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pacceleratorPassthrough); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ShadowBitmap )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pshadowBitmap); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ShadowBitmap )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pshadowBitmap); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_TransportType )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long ptransportType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TransportType )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *ptransportType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SasSequence )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long psasSequence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SasSequence )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *psasSequence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EncryptionEnabled )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pencryptionEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EncryptionEnabled )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pencryptionEnabled); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DedicatedTerminal )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pdedicatedTerminal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DedicatedTerminal )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pdedicatedTerminal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RDPPort )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long prdpPort); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RDPPort )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *prdpPort); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableMouse )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long penableMouse); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableMouse )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *penableMouse); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pdisableCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pdisableCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableWindowsKey )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long penableWindowsKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableWindowsKey )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *penableWindowsKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DoubleClickDetect )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pdoubleClickDetect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DoubleClickDetect )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pdoubleClickDetect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaximizeShell )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pmaximizeShell); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaximizeShell )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pmaximizeShell); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyCtrlEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyCtrlEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyAltEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyAltEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltTab )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyAltTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltTab )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyAltTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyAltShiftTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyAltShiftTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyAltSpace); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyAltSpace); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_orderDrawThreshold )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long porderDrawThreshold); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_orderDrawThreshold )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *porderDrawThreshold); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheSize )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbitmapCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheSize )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbitmapCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbitmapVirtualCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbitmapVirtualCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbScale); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbScale); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NumBitmapCaches )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pnumBitmapCaches); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NumBitmapCaches )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pnumBitmapCaches); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CachePersistenceActive )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pcachePersistenceActive); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CachePersistenceActive )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pcachePersistenceActive); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PersistCacheDirectory )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_brushSupportLevel )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbrushSupportLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_brushSupportLevel )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbrushSupportLevel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_minInputSendInterval )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pminInputSendInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_minInputSendInterval )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pminInputSendInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pinputEventsAtOnce); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pinputEventsAtOnce); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_maxEventCount )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pmaxEventCount); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_maxEventCount )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pmaxEventCount); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_keepAliveInterval )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pkeepAliveInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_keepAliveInterval )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pkeepAliveInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_shutdownTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pshutdownTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_shutdownTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pshutdownTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long poverallConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *poverallConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long psingleConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *psingleConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardType )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pkeyboardType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardType )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pkeyboardType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardSubType )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pkeyboardSubType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardSubType )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pkeyboardSubType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pkeyboardFunctionKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pkeyboardFunctionKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WinceFixedPalette )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pwinceFixedPalette); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WinceFixedPalette )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pwinceFixedPalette); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pConnectToConsole); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPersistence )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbitmapPersistence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPersistence )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbitmapPersistence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pminutesToIdleTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pminutesToIdleTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmartSizing )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pfSmartSizing); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmartSizing )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR pLocalPrintingDocName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ BSTR *pLocalPrintingDocName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR clipCleanTempDirString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ BSTR *clipCleanTempDirString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR clipPasteInfoString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ BSTR *clipPasteInfoString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pDisplayConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PinConnectionBar )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pPinConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PinConnectionBar )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR pLBInfo); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ BSTR *pLBInfo); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectDrives )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pRedirectDrives); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectDrives )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPrinters )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pRedirectPrinters); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPrinters )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPorts )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pRedirectPorts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPorts )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectSmartCards )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pRedirectSmartCards); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectSmartCards )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PerformanceFlags )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pDisableList); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PerformanceFlags )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pDisableList); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectWithEndpoint )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT *rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + END_INTERFACE + } IMsRdpClientAdvancedSettingsVtbl; + + interface IMsRdpClientAdvancedSettings + { + CONST_VTBL struct IMsRdpClientAdvancedSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientAdvancedSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientAdvancedSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientAdvancedSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientAdvancedSettings_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientAdvancedSettings_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientAdvancedSettings_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientAdvancedSettings_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientAdvancedSettings_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsRdpClientAdvancedSettings_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + + +#define IMsRdpClientAdvancedSettings_put_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> put_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings_get_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> get_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings_put_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> put_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings_get_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> get_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings_put_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> put_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings_get_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> get_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings_put_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> put_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings_get_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> get_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings_put_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> put_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings_get_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> get_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings_put_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> put_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings_get_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> get_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings_put_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> put_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings_get_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> get_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings_put_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> put_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings_get_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> get_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings_put_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> put_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings_get_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> get_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings_put_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> put_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings_get_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> get_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings_put_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> put_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings_get_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> get_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings_put_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> put_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings_get_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> get_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings_put_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> put_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings_get_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> get_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> put_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> get_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> put_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> get_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> put_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> get_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> put_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> get_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> put_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> get_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> put_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> get_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings_put_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> put_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings_get_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> get_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> put_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> get_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings_put_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> put_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings_get_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> get_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings_put_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> put_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings_get_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> get_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings_put_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> put_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings_get_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> get_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings_put_PersistCacheDirectory(This,rhs) \ + ( (This)->lpVtbl -> put_PersistCacheDirectory(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> put_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings_get_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> get_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings_put_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> put_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings_get_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> get_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings_put_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> put_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings_get_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> get_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings_put_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> put_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings_get_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> get_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings_put_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> put_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings_get_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> get_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings_put_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> put_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings_get_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> get_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings_put_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> put_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings_get_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> get_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings_put_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> put_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings_get_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> get_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings_put_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> put_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings_get_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> get_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings_put_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> put_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings_get_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> get_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings_put_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> put_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings_get_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> get_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings_put_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> put_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings_get_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> get_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings_put_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> put_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings_get_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> get_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> put_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> get_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings_put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings_get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings_put_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> put_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings_get_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> get_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings_put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings_get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings_put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings_get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings_put_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> put_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings_get_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> get_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> put_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings_get_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> get_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings_put_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> put_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings_get_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> get_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings_put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings_get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings_put_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> put_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings_get_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> get_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings_put_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> put_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings_get_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> get_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings_put_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> put_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings_get_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> get_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings_put_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> put_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings_get_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> get_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings_put_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> put_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings_get_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> get_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings_put_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> put_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings_get_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> get_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings_put_ConnectWithEndpoint(This,rhs) \ + ( (This)->lpVtbl -> put_ConnectWithEndpoint(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> put_NotifyTSPublicKey(This,pfNotify) ) + +#define IMsRdpClientAdvancedSettings_get_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> get_NotifyTSPublicKey(This,pfNotify) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_RedirectSmartCards_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_RedirectSmartCards_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_BitmapVirtualCache16BppSize_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_BitmapVirtualCache16BppSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_BitmapVirtualCache16BppSize_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_BitmapVirtualCache16BppSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_BitmapVirtualCache24BppSize_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_BitmapVirtualCache24BppSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_BitmapVirtualCache24BppSize_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_BitmapVirtualCache24BppSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_PerformanceFlags_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pDisableList); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_PerformanceFlags_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_PerformanceFlags_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pDisableList); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_PerformanceFlags_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_ConnectWithEndpoint_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT *rhs); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_ConnectWithEndpoint_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_NotifyTSPublicKey_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pfNotify); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_NotifyTSPublicKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_NotifyTSPublicKey_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_NotifyTSPublicKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMsRdpClientAdvancedSettings_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings2_INTERFACE_DEFINED__ +#define __IMsRdpClientAdvancedSettings2_INTERFACE_DEFINED__ + +/* interface IMsRdpClientAdvancedSettings2 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientAdvancedSettings2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9AC42117-2B76-4320-AA44-0E616AB8437B") + IMsRdpClientAdvancedSettings2 : public IMsRdpClientAdvancedSettings + { + public: + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CanAutoReconnect( + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_EnableAutoReconnect( + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_EnableAutoReconnect( + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MaxReconnectAttempts( + /* [in] */ long pMaxReconnectAttempts) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MaxReconnectAttempts( + /* [retval][out] */ long *pMaxReconnectAttempts) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientAdvancedSettings2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientAdvancedSettings2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientAdvancedSettings2 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientAdvancedSettings2 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pDisableRdpdr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmoothScroll )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long psmoothScroll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmoothScroll )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *psmoothScroll); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pacceleratorPassthrough); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pacceleratorPassthrough); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ShadowBitmap )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pshadowBitmap); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ShadowBitmap )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pshadowBitmap); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_TransportType )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long ptransportType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TransportType )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *ptransportType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SasSequence )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long psasSequence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SasSequence )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *psasSequence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EncryptionEnabled )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pencryptionEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EncryptionEnabled )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pencryptionEnabled); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DedicatedTerminal )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pdedicatedTerminal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DedicatedTerminal )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pdedicatedTerminal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RDPPort )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long prdpPort); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RDPPort )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *prdpPort); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableMouse )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long penableMouse); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableMouse )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *penableMouse); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pdisableCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pdisableCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableWindowsKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long penableWindowsKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableWindowsKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *penableWindowsKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DoubleClickDetect )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pdoubleClickDetect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DoubleClickDetect )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pdoubleClickDetect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaximizeShell )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pmaximizeShell); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaximizeShell )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pmaximizeShell); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyCtrlEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyCtrlEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyAltEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyAltEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltTab )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyAltTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltTab )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyAltTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyAltShiftTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyAltShiftTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyAltSpace); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyAltSpace); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_orderDrawThreshold )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long porderDrawThreshold); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_orderDrawThreshold )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *porderDrawThreshold); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbitmapCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbitmapCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbitmapVirtualCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbitmapVirtualCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbScale); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbScale); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NumBitmapCaches )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pnumBitmapCaches); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NumBitmapCaches )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pnumBitmapCaches); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CachePersistenceActive )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pcachePersistenceActive); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CachePersistenceActive )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pcachePersistenceActive); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PersistCacheDirectory )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_brushSupportLevel )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbrushSupportLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_brushSupportLevel )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbrushSupportLevel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_minInputSendInterval )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pminInputSendInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_minInputSendInterval )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pminInputSendInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pinputEventsAtOnce); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pinputEventsAtOnce); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_maxEventCount )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pmaxEventCount); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_maxEventCount )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pmaxEventCount); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_keepAliveInterval )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pkeepAliveInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_keepAliveInterval )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pkeepAliveInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_shutdownTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pshutdownTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_shutdownTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pshutdownTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long poverallConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *poverallConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long psingleConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *psingleConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardType )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pkeyboardType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardType )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pkeyboardType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardSubType )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pkeyboardSubType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardSubType )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pkeyboardSubType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pkeyboardFunctionKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pkeyboardFunctionKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WinceFixedPalette )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pwinceFixedPalette); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WinceFixedPalette )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pwinceFixedPalette); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pConnectToConsole); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPersistence )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbitmapPersistence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPersistence )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbitmapPersistence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pminutesToIdleTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pminutesToIdleTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmartSizing )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfSmartSizing); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmartSizing )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR pLocalPrintingDocName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ BSTR *pLocalPrintingDocName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR clipCleanTempDirString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ BSTR *clipCleanTempDirString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR clipPasteInfoString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ BSTR *clipPasteInfoString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pDisplayConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PinConnectionBar )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pPinConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PinConnectionBar )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR pLBInfo); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ BSTR *pLBInfo); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectDrives )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pRedirectDrives); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectDrives )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPrinters )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pRedirectPrinters); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPrinters )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPorts )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pRedirectPorts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPorts )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectSmartCards )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pRedirectSmartCards); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectSmartCards )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PerformanceFlags )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pDisableList); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PerformanceFlags )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pDisableList); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectWithEndpoint )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT *rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CanAutoReconnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pMaxReconnectAttempts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pMaxReconnectAttempts); + + END_INTERFACE + } IMsRdpClientAdvancedSettings2Vtbl; + + interface IMsRdpClientAdvancedSettings2 + { + CONST_VTBL struct IMsRdpClientAdvancedSettings2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientAdvancedSettings2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientAdvancedSettings2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientAdvancedSettings2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientAdvancedSettings2_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientAdvancedSettings2_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientAdvancedSettings2_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientAdvancedSettings2_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientAdvancedSettings2_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings2_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings2_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings2_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings2_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings2_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings2_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsRdpClientAdvancedSettings2_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + + +#define IMsRdpClientAdvancedSettings2_put_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> put_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings2_get_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> get_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings2_put_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> put_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings2_get_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> get_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings2_put_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> put_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings2_get_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> get_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings2_put_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> put_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings2_get_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> get_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings2_put_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> put_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings2_get_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> get_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings2_put_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> put_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings2_get_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> get_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings2_put_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> put_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings2_get_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> get_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings2_put_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> put_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings2_get_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> get_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings2_put_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> put_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings2_get_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> get_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings2_put_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> put_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings2_get_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> get_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings2_put_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> put_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings2_get_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> get_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings2_put_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> put_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings2_get_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> get_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings2_put_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> put_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings2_get_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> get_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> put_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> get_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> put_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> get_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> put_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> get_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> put_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> get_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> put_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> get_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> put_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> get_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings2_put_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> put_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings2_get_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> get_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> put_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> get_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings2_put_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> put_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings2_get_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> get_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings2_put_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> put_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings2_get_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> get_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings2_put_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> put_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings2_get_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> get_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings2_put_PersistCacheDirectory(This,rhs) \ + ( (This)->lpVtbl -> put_PersistCacheDirectory(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> put_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings2_get_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> get_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings2_put_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> put_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings2_get_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> get_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings2_put_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> put_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings2_get_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> get_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings2_put_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> put_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings2_get_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> get_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings2_put_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> put_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings2_get_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> get_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings2_put_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> put_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings2_get_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> get_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings2_put_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> put_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings2_get_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> get_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings2_put_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> put_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings2_get_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> get_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings2_put_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> put_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings2_get_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> get_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings2_put_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> put_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings2_get_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> get_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings2_put_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> put_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings2_get_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> get_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings2_put_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> put_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings2_get_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> get_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings2_put_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> put_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings2_get_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> get_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> put_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> get_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings2_put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings2_get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings2_put_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> put_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings2_get_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> get_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings2_put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings2_get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings2_put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings2_get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings2_put_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> put_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings2_get_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> get_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings2_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> put_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings2_get_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> get_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings2_put_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> put_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings2_get_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> get_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings2_put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings2_get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings2_put_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> put_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings2_get_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> get_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings2_put_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> put_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings2_get_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> get_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings2_put_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> put_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings2_get_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> get_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings2_put_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> put_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings2_get_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> get_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings2_put_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> put_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings2_get_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> get_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings2_put_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> put_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings2_get_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> get_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings2_put_ConnectWithEndpoint(This,rhs) \ + ( (This)->lpVtbl -> put_ConnectWithEndpoint(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> put_NotifyTSPublicKey(This,pfNotify) ) + +#define IMsRdpClientAdvancedSettings2_get_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> get_NotifyTSPublicKey(This,pfNotify) ) + + +#define IMsRdpClientAdvancedSettings2_get_CanAutoReconnect(This,pfCanAutoReconnect) \ + ( (This)->lpVtbl -> get_CanAutoReconnect(This,pfCanAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings2_put_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> put_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings2_get_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> get_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings2_put_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> put_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + +#define IMsRdpClientAdvancedSettings2_get_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> get_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_get_CanAutoReconnect_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_get_CanAutoReconnect_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_put_EnableAutoReconnect_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_put_EnableAutoReconnect_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_get_EnableAutoReconnect_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_get_EnableAutoReconnect_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_put_MaxReconnectAttempts_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pMaxReconnectAttempts); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_put_MaxReconnectAttempts_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_get_MaxReconnectAttempts_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pMaxReconnectAttempts); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_get_MaxReconnectAttempts_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMsRdpClientAdvancedSettings2_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings3_INTERFACE_DEFINED__ +#define __IMsRdpClientAdvancedSettings3_INTERFACE_DEFINED__ + +/* interface IMsRdpClientAdvancedSettings3 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientAdvancedSettings3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("19CD856B-C542-4C53-ACEE-F127E3BE1A59") + IMsRdpClientAdvancedSettings3 : public IMsRdpClientAdvancedSettings2 + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectionBarShowMinimizeButton( + /* [in] */ VARIANT_BOOL pfShowMinimize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectionBarShowMinimizeButton( + /* [retval][out] */ VARIANT_BOOL *pfShowMinimize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectionBarShowRestoreButton( + /* [in] */ VARIANT_BOOL pfShowRestore) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectionBarShowRestoreButton( + /* [retval][out] */ VARIANT_BOOL *pfShowRestore) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientAdvancedSettings3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientAdvancedSettings3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientAdvancedSettings3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientAdvancedSettings3 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pDisableRdpdr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmoothScroll )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long psmoothScroll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmoothScroll )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *psmoothScroll); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pacceleratorPassthrough); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pacceleratorPassthrough); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ShadowBitmap )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pshadowBitmap); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ShadowBitmap )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pshadowBitmap); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_TransportType )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long ptransportType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TransportType )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *ptransportType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SasSequence )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long psasSequence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SasSequence )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *psasSequence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EncryptionEnabled )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pencryptionEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EncryptionEnabled )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pencryptionEnabled); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DedicatedTerminal )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pdedicatedTerminal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DedicatedTerminal )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pdedicatedTerminal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RDPPort )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long prdpPort); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RDPPort )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *prdpPort); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableMouse )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long penableMouse); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableMouse )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *penableMouse); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pdisableCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pdisableCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableWindowsKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long penableWindowsKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableWindowsKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *penableWindowsKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DoubleClickDetect )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pdoubleClickDetect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DoubleClickDetect )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pdoubleClickDetect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaximizeShell )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pmaximizeShell); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaximizeShell )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pmaximizeShell); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyCtrlEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyCtrlEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyAltEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyAltEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltTab )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyAltTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltTab )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyAltTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyAltShiftTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyAltShiftTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyAltSpace); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyAltSpace); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_orderDrawThreshold )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long porderDrawThreshold); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_orderDrawThreshold )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *porderDrawThreshold); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbitmapCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbitmapCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbitmapVirtualCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbitmapVirtualCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbScale); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbScale); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NumBitmapCaches )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pnumBitmapCaches); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NumBitmapCaches )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pnumBitmapCaches); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CachePersistenceActive )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pcachePersistenceActive); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CachePersistenceActive )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pcachePersistenceActive); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PersistCacheDirectory )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_brushSupportLevel )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbrushSupportLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_brushSupportLevel )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbrushSupportLevel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_minInputSendInterval )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pminInputSendInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_minInputSendInterval )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pminInputSendInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pinputEventsAtOnce); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pinputEventsAtOnce); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_maxEventCount )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pmaxEventCount); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_maxEventCount )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pmaxEventCount); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_keepAliveInterval )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pkeepAliveInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_keepAliveInterval )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pkeepAliveInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_shutdownTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pshutdownTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_shutdownTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pshutdownTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long poverallConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *poverallConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long psingleConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *psingleConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardType )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pkeyboardType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardType )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pkeyboardType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardSubType )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pkeyboardSubType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardSubType )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pkeyboardSubType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pkeyboardFunctionKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pkeyboardFunctionKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WinceFixedPalette )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pwinceFixedPalette); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WinceFixedPalette )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pwinceFixedPalette); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pConnectToConsole); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPersistence )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbitmapPersistence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPersistence )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbitmapPersistence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pminutesToIdleTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pminutesToIdleTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmartSizing )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfSmartSizing); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmartSizing )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR pLocalPrintingDocName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ BSTR *pLocalPrintingDocName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR clipCleanTempDirString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ BSTR *clipCleanTempDirString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR clipPasteInfoString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ BSTR *clipPasteInfoString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pDisplayConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PinConnectionBar )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pPinConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PinConnectionBar )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR pLBInfo); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ BSTR *pLBInfo); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectDrives )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pRedirectDrives); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectDrives )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPrinters )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pRedirectPrinters); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPrinters )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPorts )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pRedirectPorts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPorts )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectSmartCards )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pRedirectSmartCards); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectSmartCards )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PerformanceFlags )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pDisableList); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PerformanceFlags )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pDisableList); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectWithEndpoint )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT *rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CanAutoReconnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pMaxReconnectAttempts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pMaxReconnectAttempts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectionBarShowMinimizeButton )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfShowMinimize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectionBarShowMinimizeButton )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowMinimize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectionBarShowRestoreButton )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfShowRestore); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectionBarShowRestoreButton )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowRestore); + + END_INTERFACE + } IMsRdpClientAdvancedSettings3Vtbl; + + interface IMsRdpClientAdvancedSettings3 + { + CONST_VTBL struct IMsRdpClientAdvancedSettings3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientAdvancedSettings3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientAdvancedSettings3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientAdvancedSettings3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientAdvancedSettings3_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientAdvancedSettings3_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientAdvancedSettings3_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientAdvancedSettings3_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientAdvancedSettings3_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings3_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings3_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings3_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings3_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings3_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings3_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsRdpClientAdvancedSettings3_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + + +#define IMsRdpClientAdvancedSettings3_put_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> put_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings3_get_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> get_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings3_put_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> put_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings3_get_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> get_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings3_put_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> put_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings3_get_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> get_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings3_put_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> put_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings3_get_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> get_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings3_put_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> put_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings3_get_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> get_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings3_put_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> put_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings3_get_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> get_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings3_put_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> put_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings3_get_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> get_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings3_put_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> put_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings3_get_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> get_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings3_put_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> put_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings3_get_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> get_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings3_put_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> put_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings3_get_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> get_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings3_put_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> put_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings3_get_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> get_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings3_put_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> put_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings3_get_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> get_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings3_put_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> put_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings3_get_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> get_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> put_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> get_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> put_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> get_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> put_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> get_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> put_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> get_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> put_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> get_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> put_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> get_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings3_put_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> put_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings3_get_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> get_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> put_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> get_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings3_put_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> put_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings3_get_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> get_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings3_put_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> put_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings3_get_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> get_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings3_put_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> put_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings3_get_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> get_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings3_put_PersistCacheDirectory(This,rhs) \ + ( (This)->lpVtbl -> put_PersistCacheDirectory(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> put_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings3_get_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> get_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings3_put_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> put_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings3_get_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> get_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings3_put_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> put_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings3_get_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> get_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings3_put_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> put_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings3_get_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> get_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings3_put_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> put_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings3_get_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> get_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings3_put_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> put_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings3_get_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> get_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings3_put_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> put_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings3_get_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> get_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings3_put_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> put_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings3_get_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> get_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings3_put_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> put_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings3_get_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> get_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings3_put_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> put_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings3_get_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> get_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings3_put_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> put_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings3_get_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> get_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings3_put_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> put_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings3_get_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> get_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings3_put_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> put_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings3_get_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> get_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> put_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> get_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings3_put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings3_get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings3_put_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> put_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings3_get_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> get_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings3_put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings3_get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings3_put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings3_get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings3_put_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> put_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings3_get_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> get_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings3_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> put_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings3_get_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> get_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings3_put_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> put_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings3_get_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> get_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings3_put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings3_get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings3_put_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> put_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings3_get_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> get_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings3_put_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> put_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings3_get_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> get_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings3_put_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> put_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings3_get_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> get_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings3_put_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> put_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings3_get_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> get_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings3_put_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> put_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings3_get_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> get_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings3_put_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> put_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings3_get_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> get_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings3_put_ConnectWithEndpoint(This,rhs) \ + ( (This)->lpVtbl -> put_ConnectWithEndpoint(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> put_NotifyTSPublicKey(This,pfNotify) ) + +#define IMsRdpClientAdvancedSettings3_get_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> get_NotifyTSPublicKey(This,pfNotify) ) + + +#define IMsRdpClientAdvancedSettings3_get_CanAutoReconnect(This,pfCanAutoReconnect) \ + ( (This)->lpVtbl -> get_CanAutoReconnect(This,pfCanAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings3_put_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> put_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings3_get_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> get_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings3_put_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> put_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + +#define IMsRdpClientAdvancedSettings3_get_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> get_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + + +#define IMsRdpClientAdvancedSettings3_put_ConnectionBarShowMinimizeButton(This,pfShowMinimize) \ + ( (This)->lpVtbl -> put_ConnectionBarShowMinimizeButton(This,pfShowMinimize) ) + +#define IMsRdpClientAdvancedSettings3_get_ConnectionBarShowMinimizeButton(This,pfShowMinimize) \ + ( (This)->lpVtbl -> get_ConnectionBarShowMinimizeButton(This,pfShowMinimize) ) + +#define IMsRdpClientAdvancedSettings3_put_ConnectionBarShowRestoreButton(This,pfShowRestore) \ + ( (This)->lpVtbl -> put_ConnectionBarShowRestoreButton(This,pfShowRestore) ) + +#define IMsRdpClientAdvancedSettings3_get_ConnectionBarShowRestoreButton(This,pfShowRestore) \ + ( (This)->lpVtbl -> get_ConnectionBarShowRestoreButton(This,pfShowRestore) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings3_put_ConnectionBarShowMinimizeButton_Proxy( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfShowMinimize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings3_put_ConnectionBarShowMinimizeButton_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings3_get_ConnectionBarShowMinimizeButton_Proxy( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowMinimize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings3_get_ConnectionBarShowMinimizeButton_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings3_put_ConnectionBarShowRestoreButton_Proxy( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfShowRestore); + + +void __RPC_STUB IMsRdpClientAdvancedSettings3_put_ConnectionBarShowRestoreButton_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings3_get_ConnectionBarShowRestoreButton_Proxy( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowRestore); + + +void __RPC_STUB IMsRdpClientAdvancedSettings3_get_ConnectionBarShowRestoreButton_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMsRdpClientAdvancedSettings3_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings4_INTERFACE_DEFINED__ +#define __IMsRdpClientAdvancedSettings4_INTERFACE_DEFINED__ + +/* interface IMsRdpClientAdvancedSettings4 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientAdvancedSettings4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("FBA7F64E-7345-4405-AE50-FA4A763DC0DE") + IMsRdpClientAdvancedSettings4 : public IMsRdpClientAdvancedSettings3 + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_AuthenticationLevel( + /* [in] */ unsigned int puiAuthLevel) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AuthenticationLevel( + /* [retval][out] */ unsigned int *puiAuthLevel) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientAdvancedSettings4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientAdvancedSettings4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientAdvancedSettings4 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientAdvancedSettings4 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pDisableRdpdr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmoothScroll )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long psmoothScroll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmoothScroll )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *psmoothScroll); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pacceleratorPassthrough); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pacceleratorPassthrough); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ShadowBitmap )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pshadowBitmap); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ShadowBitmap )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pshadowBitmap); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_TransportType )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long ptransportType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TransportType )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *ptransportType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SasSequence )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long psasSequence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SasSequence )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *psasSequence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EncryptionEnabled )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pencryptionEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EncryptionEnabled )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pencryptionEnabled); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DedicatedTerminal )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pdedicatedTerminal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DedicatedTerminal )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pdedicatedTerminal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RDPPort )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long prdpPort); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RDPPort )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *prdpPort); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableMouse )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long penableMouse); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableMouse )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *penableMouse); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pdisableCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pdisableCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableWindowsKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long penableWindowsKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableWindowsKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *penableWindowsKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DoubleClickDetect )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pdoubleClickDetect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DoubleClickDetect )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pdoubleClickDetect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaximizeShell )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pmaximizeShell); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaximizeShell )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pmaximizeShell); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyCtrlEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyCtrlEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyAltEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyAltEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltTab )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyAltTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltTab )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyAltTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyAltShiftTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyAltShiftTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyAltSpace); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyAltSpace); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_orderDrawThreshold )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long porderDrawThreshold); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_orderDrawThreshold )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *porderDrawThreshold); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbitmapCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbitmapCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbitmapVirtualCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbitmapVirtualCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbScale); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbScale); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NumBitmapCaches )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pnumBitmapCaches); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NumBitmapCaches )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pnumBitmapCaches); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CachePersistenceActive )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pcachePersistenceActive); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CachePersistenceActive )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pcachePersistenceActive); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PersistCacheDirectory )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_brushSupportLevel )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbrushSupportLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_brushSupportLevel )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbrushSupportLevel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_minInputSendInterval )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pminInputSendInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_minInputSendInterval )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pminInputSendInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pinputEventsAtOnce); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pinputEventsAtOnce); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_maxEventCount )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pmaxEventCount); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_maxEventCount )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pmaxEventCount); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_keepAliveInterval )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pkeepAliveInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_keepAliveInterval )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pkeepAliveInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_shutdownTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pshutdownTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_shutdownTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pshutdownTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long poverallConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *poverallConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long psingleConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *psingleConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardType )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pkeyboardType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardType )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pkeyboardType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardSubType )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pkeyboardSubType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardSubType )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pkeyboardSubType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pkeyboardFunctionKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pkeyboardFunctionKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WinceFixedPalette )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pwinceFixedPalette); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WinceFixedPalette )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pwinceFixedPalette); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pConnectToConsole); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPersistence )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbitmapPersistence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPersistence )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbitmapPersistence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pminutesToIdleTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pminutesToIdleTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmartSizing )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfSmartSizing); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmartSizing )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR pLocalPrintingDocName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ BSTR *pLocalPrintingDocName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR clipCleanTempDirString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ BSTR *clipCleanTempDirString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR clipPasteInfoString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ BSTR *clipPasteInfoString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pDisplayConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PinConnectionBar )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pPinConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PinConnectionBar )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR pLBInfo); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ BSTR *pLBInfo); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectDrives )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pRedirectDrives); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectDrives )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPrinters )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pRedirectPrinters); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPrinters )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPorts )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pRedirectPorts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPorts )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectSmartCards )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pRedirectSmartCards); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectSmartCards )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PerformanceFlags )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pDisableList); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PerformanceFlags )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pDisableList); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectWithEndpoint )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT *rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CanAutoReconnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pMaxReconnectAttempts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pMaxReconnectAttempts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectionBarShowMinimizeButton )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfShowMinimize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectionBarShowMinimizeButton )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowMinimize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectionBarShowRestoreButton )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfShowRestore); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectionBarShowRestoreButton )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowRestore); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AuthenticationLevel )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ unsigned int puiAuthLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AuthenticationLevel )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ unsigned int *puiAuthLevel); + + END_INTERFACE + } IMsRdpClientAdvancedSettings4Vtbl; + + interface IMsRdpClientAdvancedSettings4 + { + CONST_VTBL struct IMsRdpClientAdvancedSettings4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientAdvancedSettings4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientAdvancedSettings4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientAdvancedSettings4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientAdvancedSettings4_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientAdvancedSettings4_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientAdvancedSettings4_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientAdvancedSettings4_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientAdvancedSettings4_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings4_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings4_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings4_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings4_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings4_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings4_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsRdpClientAdvancedSettings4_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + + +#define IMsRdpClientAdvancedSettings4_put_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> put_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings4_get_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> get_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings4_put_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> put_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings4_get_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> get_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings4_put_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> put_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings4_get_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> get_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings4_put_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> put_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings4_get_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> get_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings4_put_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> put_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings4_get_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> get_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings4_put_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> put_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings4_get_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> get_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings4_put_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> put_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings4_get_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> get_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings4_put_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> put_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings4_get_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> get_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings4_put_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> put_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings4_get_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> get_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings4_put_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> put_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings4_get_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> get_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings4_put_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> put_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings4_get_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> get_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings4_put_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> put_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings4_get_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> get_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings4_put_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> put_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings4_get_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> get_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> put_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> get_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> put_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> get_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> put_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> get_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> put_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> get_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> put_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> get_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> put_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> get_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings4_put_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> put_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings4_get_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> get_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> put_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> get_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings4_put_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> put_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings4_get_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> get_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings4_put_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> put_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings4_get_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> get_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings4_put_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> put_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings4_get_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> get_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings4_put_PersistCacheDirectory(This,rhs) \ + ( (This)->lpVtbl -> put_PersistCacheDirectory(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> put_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings4_get_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> get_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings4_put_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> put_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings4_get_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> get_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings4_put_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> put_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings4_get_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> get_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings4_put_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> put_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings4_get_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> get_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings4_put_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> put_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings4_get_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> get_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings4_put_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> put_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings4_get_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> get_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings4_put_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> put_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings4_get_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> get_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings4_put_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> put_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings4_get_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> get_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings4_put_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> put_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings4_get_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> get_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings4_put_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> put_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings4_get_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> get_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings4_put_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> put_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings4_get_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> get_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings4_put_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> put_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings4_get_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> get_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings4_put_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> put_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings4_get_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> get_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> put_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> get_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings4_put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings4_get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings4_put_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> put_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings4_get_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> get_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings4_put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings4_get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings4_put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings4_get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings4_put_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> put_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings4_get_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> get_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings4_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> put_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings4_get_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> get_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings4_put_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> put_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings4_get_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> get_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings4_put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings4_get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings4_put_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> put_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings4_get_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> get_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings4_put_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> put_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings4_get_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> get_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings4_put_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> put_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings4_get_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> get_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings4_put_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> put_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings4_get_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> get_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings4_put_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> put_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings4_get_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> get_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings4_put_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> put_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings4_get_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> get_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings4_put_ConnectWithEndpoint(This,rhs) \ + ( (This)->lpVtbl -> put_ConnectWithEndpoint(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> put_NotifyTSPublicKey(This,pfNotify) ) + +#define IMsRdpClientAdvancedSettings4_get_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> get_NotifyTSPublicKey(This,pfNotify) ) + + +#define IMsRdpClientAdvancedSettings4_get_CanAutoReconnect(This,pfCanAutoReconnect) \ + ( (This)->lpVtbl -> get_CanAutoReconnect(This,pfCanAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings4_put_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> put_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings4_get_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> get_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings4_put_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> put_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + +#define IMsRdpClientAdvancedSettings4_get_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> get_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + + +#define IMsRdpClientAdvancedSettings4_put_ConnectionBarShowMinimizeButton(This,pfShowMinimize) \ + ( (This)->lpVtbl -> put_ConnectionBarShowMinimizeButton(This,pfShowMinimize) ) + +#define IMsRdpClientAdvancedSettings4_get_ConnectionBarShowMinimizeButton(This,pfShowMinimize) \ + ( (This)->lpVtbl -> get_ConnectionBarShowMinimizeButton(This,pfShowMinimize) ) + +#define IMsRdpClientAdvancedSettings4_put_ConnectionBarShowRestoreButton(This,pfShowRestore) \ + ( (This)->lpVtbl -> put_ConnectionBarShowRestoreButton(This,pfShowRestore) ) + +#define IMsRdpClientAdvancedSettings4_get_ConnectionBarShowRestoreButton(This,pfShowRestore) \ + ( (This)->lpVtbl -> get_ConnectionBarShowRestoreButton(This,pfShowRestore) ) + + +#define IMsRdpClientAdvancedSettings4_put_AuthenticationLevel(This,puiAuthLevel) \ + ( (This)->lpVtbl -> put_AuthenticationLevel(This,puiAuthLevel) ) + +#define IMsRdpClientAdvancedSettings4_get_AuthenticationLevel(This,puiAuthLevel) \ + ( (This)->lpVtbl -> get_AuthenticationLevel(This,puiAuthLevel) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings4_put_AuthenticationLevel_Proxy( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ unsigned int puiAuthLevel); + + +void __RPC_STUB IMsRdpClientAdvancedSettings4_put_AuthenticationLevel_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings4_get_AuthenticationLevel_Proxy( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ unsigned int *puiAuthLevel); + + +void __RPC_STUB IMsRdpClientAdvancedSettings4_get_AuthenticationLevel_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMsRdpClientAdvancedSettings4_INTERFACE_DEFINED__ */ + + +#ifndef __IMsTscSecuredSettings_INTERFACE_DEFINED__ +#define __IMsTscSecuredSettings_INTERFACE_DEFINED__ + +/* interface IMsTscSecuredSettings */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsTscSecuredSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C9D65442-A0F9-45B2-8F73-D61D2DB8CBB6") + IMsTscSecuredSettings : public IDispatch + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_StartProgram( + /* [in] */ BSTR pStartProgram) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_StartProgram( + /* [retval][out] */ BSTR *pStartProgram) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_WorkDir( + /* [in] */ BSTR pWorkDir) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_WorkDir( + /* [retval][out] */ BSTR *pWorkDir) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_FullScreen( + /* [in] */ long pfFullScreen) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_FullScreen( + /* [retval][out] */ long *pfFullScreen) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscSecuredSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscSecuredSettings * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscSecuredSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscSecuredSettings * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscSecuredSettings * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscSecuredSettings * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscSecuredSettings * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscSecuredSettings * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartProgram )( + IMsTscSecuredSettings * This, + /* [in] */ BSTR pStartProgram); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartProgram )( + IMsTscSecuredSettings * This, + /* [retval][out] */ BSTR *pStartProgram); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WorkDir )( + IMsTscSecuredSettings * This, + /* [in] */ BSTR pWorkDir); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WorkDir )( + IMsTscSecuredSettings * This, + /* [retval][out] */ BSTR *pWorkDir); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsTscSecuredSettings * This, + /* [in] */ long pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsTscSecuredSettings * This, + /* [retval][out] */ long *pfFullScreen); + + END_INTERFACE + } IMsTscSecuredSettingsVtbl; + + interface IMsTscSecuredSettings + { + CONST_VTBL struct IMsTscSecuredSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscSecuredSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscSecuredSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscSecuredSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscSecuredSettings_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscSecuredSettings_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscSecuredSettings_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscSecuredSettings_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsTscSecuredSettings_put_StartProgram(This,pStartProgram) \ + ( (This)->lpVtbl -> put_StartProgram(This,pStartProgram) ) + +#define IMsTscSecuredSettings_get_StartProgram(This,pStartProgram) \ + ( (This)->lpVtbl -> get_StartProgram(This,pStartProgram) ) + +#define IMsTscSecuredSettings_put_WorkDir(This,pWorkDir) \ + ( (This)->lpVtbl -> put_WorkDir(This,pWorkDir) ) + +#define IMsTscSecuredSettings_get_WorkDir(This,pWorkDir) \ + ( (This)->lpVtbl -> get_WorkDir(This,pWorkDir) ) + +#define IMsTscSecuredSettings_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsTscSecuredSettings_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscSecuredSettings_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientSecuredSettings_INTERFACE_DEFINED__ +#define __IMsRdpClientSecuredSettings_INTERFACE_DEFINED__ + +/* interface IMsRdpClientSecuredSettings */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientSecuredSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("605BEFCF-39C1-45CC-A811-068FB7BE346D") + IMsRdpClientSecuredSettings : public IMsTscSecuredSettings + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyboardHookMode( + /* [in] */ long pkeyboardHookMode) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_KeyboardHookMode( + /* [retval][out] */ long *pkeyboardHookMode) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_AudioRedirectionMode( + /* [in] */ long pAudioRedirectionMode) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AudioRedirectionMode( + /* [retval][out] */ long *pAudioRedirectionMode) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientSecuredSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientSecuredSettings * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientSecuredSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientSecuredSettings * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientSecuredSettings * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientSecuredSettings * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientSecuredSettings * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientSecuredSettings * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartProgram )( + IMsRdpClientSecuredSettings * This, + /* [in] */ BSTR pStartProgram); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartProgram )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ BSTR *pStartProgram); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WorkDir )( + IMsRdpClientSecuredSettings * This, + /* [in] */ BSTR pWorkDir); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WorkDir )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ BSTR *pWorkDir); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClientSecuredSettings * This, + /* [in] */ long pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ long *pfFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardHookMode )( + IMsRdpClientSecuredSettings * This, + /* [in] */ long pkeyboardHookMode); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardHookMode )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ long *pkeyboardHookMode); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AudioRedirectionMode )( + IMsRdpClientSecuredSettings * This, + /* [in] */ long pAudioRedirectionMode); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AudioRedirectionMode )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ long *pAudioRedirectionMode); + + END_INTERFACE + } IMsRdpClientSecuredSettingsVtbl; + + interface IMsRdpClientSecuredSettings + { + CONST_VTBL struct IMsRdpClientSecuredSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientSecuredSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientSecuredSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientSecuredSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientSecuredSettings_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientSecuredSettings_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientSecuredSettings_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientSecuredSettings_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientSecuredSettings_put_StartProgram(This,pStartProgram) \ + ( (This)->lpVtbl -> put_StartProgram(This,pStartProgram) ) + +#define IMsRdpClientSecuredSettings_get_StartProgram(This,pStartProgram) \ + ( (This)->lpVtbl -> get_StartProgram(This,pStartProgram) ) + +#define IMsRdpClientSecuredSettings_put_WorkDir(This,pWorkDir) \ + ( (This)->lpVtbl -> put_WorkDir(This,pWorkDir) ) + +#define IMsRdpClientSecuredSettings_get_WorkDir(This,pWorkDir) \ + ( (This)->lpVtbl -> get_WorkDir(This,pWorkDir) ) + +#define IMsRdpClientSecuredSettings_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClientSecuredSettings_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + + +#define IMsRdpClientSecuredSettings_put_KeyboardHookMode(This,pkeyboardHookMode) \ + ( (This)->lpVtbl -> put_KeyboardHookMode(This,pkeyboardHookMode) ) + +#define IMsRdpClientSecuredSettings_get_KeyboardHookMode(This,pkeyboardHookMode) \ + ( (This)->lpVtbl -> get_KeyboardHookMode(This,pkeyboardHookMode) ) + +#define IMsRdpClientSecuredSettings_put_AudioRedirectionMode(This,pAudioRedirectionMode) \ + ( (This)->lpVtbl -> put_AudioRedirectionMode(This,pAudioRedirectionMode) ) + +#define IMsRdpClientSecuredSettings_get_AudioRedirectionMode(This,pAudioRedirectionMode) \ + ( (This)->lpVtbl -> get_AudioRedirectionMode(This,pAudioRedirectionMode) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClientSecuredSettings_INTERFACE_DEFINED__ */ + + +#ifndef __IMsTscDebug_INTERFACE_DEFINED__ +#define __IMsTscDebug_INTERFACE_DEFINED__ + +/* interface IMsTscDebug */ +/* [object][oleautomation][dual][hidden][uuid] */ + + +EXTERN_C const IID IID_IMsTscDebug; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("209D0EB9-6254-47B1-9033-A98DAE55BB27") + IMsTscDebug : public IDispatch + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HatchBitmapPDU( + /* [in] */ long phatchBitmapPDU) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HatchBitmapPDU( + /* [retval][out] */ long *phatchBitmapPDU) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HatchSSBOrder( + /* [in] */ long phatchSSBOrder) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HatchSSBOrder( + /* [retval][out] */ long *phatchSSBOrder) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HatchMembltOrder( + /* [in] */ long phatchMembltOrder) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HatchMembltOrder( + /* [retval][out] */ long *phatchMembltOrder) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HatchIndexPDU( + /* [in] */ long phatchIndexPDU) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HatchIndexPDU( + /* [retval][out] */ long *phatchIndexPDU) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_LabelMemblt( + /* [in] */ long plabelMemblt) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_LabelMemblt( + /* [retval][out] */ long *plabelMemblt) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapCacheMonitor( + /* [in] */ long pbitmapCacheMonitor) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapCacheMonitor( + /* [retval][out] */ long *pbitmapCacheMonitor) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MallocFailuresPercent( + /* [in] */ long pmallocFailuresPercent) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MallocFailuresPercent( + /* [retval][out] */ long *pmallocFailuresPercent) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MallocHugeFailuresPercent( + /* [in] */ long pmallocHugeFailuresPercent) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MallocHugeFailuresPercent( + /* [retval][out] */ long *pmallocHugeFailuresPercent) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_NetThroughput( + /* [in] */ long NetThroughput) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_NetThroughput( + /* [retval][out] */ long *NetThroughput) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_CLXCmdLine( + /* [in] */ BSTR pCLXCmdLine) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CLXCmdLine( + /* [retval][out] */ BSTR *pCLXCmdLine) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_CLXDll( + /* [in] */ BSTR pCLXDll) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CLXDll( + /* [retval][out] */ BSTR *pCLXDll) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscDebugVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscDebug * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscDebug * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscDebug * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscDebug * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscDebug * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscDebug * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscDebug * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HatchBitmapPDU )( + IMsTscDebug * This, + /* [in] */ long phatchBitmapPDU); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HatchBitmapPDU )( + IMsTscDebug * This, + /* [retval][out] */ long *phatchBitmapPDU); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HatchSSBOrder )( + IMsTscDebug * This, + /* [in] */ long phatchSSBOrder); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HatchSSBOrder )( + IMsTscDebug * This, + /* [retval][out] */ long *phatchSSBOrder); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HatchMembltOrder )( + IMsTscDebug * This, + /* [in] */ long phatchMembltOrder); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HatchMembltOrder )( + IMsTscDebug * This, + /* [retval][out] */ long *phatchMembltOrder); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HatchIndexPDU )( + IMsTscDebug * This, + /* [in] */ long phatchIndexPDU); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HatchIndexPDU )( + IMsTscDebug * This, + /* [retval][out] */ long *phatchIndexPDU); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LabelMemblt )( + IMsTscDebug * This, + /* [in] */ long plabelMemblt); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LabelMemblt )( + IMsTscDebug * This, + /* [retval][out] */ long *plabelMemblt); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheMonitor )( + IMsTscDebug * This, + /* [in] */ long pbitmapCacheMonitor); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheMonitor )( + IMsTscDebug * This, + /* [retval][out] */ long *pbitmapCacheMonitor); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MallocFailuresPercent )( + IMsTscDebug * This, + /* [in] */ long pmallocFailuresPercent); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MallocFailuresPercent )( + IMsTscDebug * This, + /* [retval][out] */ long *pmallocFailuresPercent); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MallocHugeFailuresPercent )( + IMsTscDebug * This, + /* [in] */ long pmallocHugeFailuresPercent); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MallocHugeFailuresPercent )( + IMsTscDebug * This, + /* [retval][out] */ long *pmallocHugeFailuresPercent); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NetThroughput )( + IMsTscDebug * This, + /* [in] */ long NetThroughput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NetThroughput )( + IMsTscDebug * This, + /* [retval][out] */ long *NetThroughput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CLXCmdLine )( + IMsTscDebug * This, + /* [in] */ BSTR pCLXCmdLine); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CLXCmdLine )( + IMsTscDebug * This, + /* [retval][out] */ BSTR *pCLXCmdLine); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CLXDll )( + IMsTscDebug * This, + /* [in] */ BSTR pCLXDll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CLXDll )( + IMsTscDebug * This, + /* [retval][out] */ BSTR *pCLXDll); + + END_INTERFACE + } IMsTscDebugVtbl; + + interface IMsTscDebug + { + CONST_VTBL struct IMsTscDebugVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscDebug_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscDebug_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscDebug_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscDebug_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscDebug_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscDebug_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscDebug_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsTscDebug_put_HatchBitmapPDU(This,phatchBitmapPDU) \ + ( (This)->lpVtbl -> put_HatchBitmapPDU(This,phatchBitmapPDU) ) + +#define IMsTscDebug_get_HatchBitmapPDU(This,phatchBitmapPDU) \ + ( (This)->lpVtbl -> get_HatchBitmapPDU(This,phatchBitmapPDU) ) + +#define IMsTscDebug_put_HatchSSBOrder(This,phatchSSBOrder) \ + ( (This)->lpVtbl -> put_HatchSSBOrder(This,phatchSSBOrder) ) + +#define IMsTscDebug_get_HatchSSBOrder(This,phatchSSBOrder) \ + ( (This)->lpVtbl -> get_HatchSSBOrder(This,phatchSSBOrder) ) + +#define IMsTscDebug_put_HatchMembltOrder(This,phatchMembltOrder) \ + ( (This)->lpVtbl -> put_HatchMembltOrder(This,phatchMembltOrder) ) + +#define IMsTscDebug_get_HatchMembltOrder(This,phatchMembltOrder) \ + ( (This)->lpVtbl -> get_HatchMembltOrder(This,phatchMembltOrder) ) + +#define IMsTscDebug_put_HatchIndexPDU(This,phatchIndexPDU) \ + ( (This)->lpVtbl -> put_HatchIndexPDU(This,phatchIndexPDU) ) + +#define IMsTscDebug_get_HatchIndexPDU(This,phatchIndexPDU) \ + ( (This)->lpVtbl -> get_HatchIndexPDU(This,phatchIndexPDU) ) + +#define IMsTscDebug_put_LabelMemblt(This,plabelMemblt) \ + ( (This)->lpVtbl -> put_LabelMemblt(This,plabelMemblt) ) + +#define IMsTscDebug_get_LabelMemblt(This,plabelMemblt) \ + ( (This)->lpVtbl -> get_LabelMemblt(This,plabelMemblt) ) + +#define IMsTscDebug_put_BitmapCacheMonitor(This,pbitmapCacheMonitor) \ + ( (This)->lpVtbl -> put_BitmapCacheMonitor(This,pbitmapCacheMonitor) ) + +#define IMsTscDebug_get_BitmapCacheMonitor(This,pbitmapCacheMonitor) \ + ( (This)->lpVtbl -> get_BitmapCacheMonitor(This,pbitmapCacheMonitor) ) + +#define IMsTscDebug_put_MallocFailuresPercent(This,pmallocFailuresPercent) \ + ( (This)->lpVtbl -> put_MallocFailuresPercent(This,pmallocFailuresPercent) ) + +#define IMsTscDebug_get_MallocFailuresPercent(This,pmallocFailuresPercent) \ + ( (This)->lpVtbl -> get_MallocFailuresPercent(This,pmallocFailuresPercent) ) + +#define IMsTscDebug_put_MallocHugeFailuresPercent(This,pmallocHugeFailuresPercent) \ + ( (This)->lpVtbl -> put_MallocHugeFailuresPercent(This,pmallocHugeFailuresPercent) ) + +#define IMsTscDebug_get_MallocHugeFailuresPercent(This,pmallocHugeFailuresPercent) \ + ( (This)->lpVtbl -> get_MallocHugeFailuresPercent(This,pmallocHugeFailuresPercent) ) + +#define IMsTscDebug_put_NetThroughput(This,NetThroughput) \ + ( (This)->lpVtbl -> put_NetThroughput(This,NetThroughput) ) + +#define IMsTscDebug_get_NetThroughput(This,NetThroughput) \ + ( (This)->lpVtbl -> get_NetThroughput(This,NetThroughput) ) + +#define IMsTscDebug_put_CLXCmdLine(This,pCLXCmdLine) \ + ( (This)->lpVtbl -> put_CLXCmdLine(This,pCLXCmdLine) ) + +#define IMsTscDebug_get_CLXCmdLine(This,pCLXCmdLine) \ + ( (This)->lpVtbl -> get_CLXCmdLine(This,pCLXCmdLine) ) + +#define IMsTscDebug_put_CLXDll(This,pCLXDll) \ + ( (This)->lpVtbl -> put_CLXDll(This,pCLXDll) ) + +#define IMsTscDebug_get_CLXDll(This,pCLXDll) \ + ( (This)->lpVtbl -> get_CLXDll(This,pCLXDll) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscDebug_INTERFACE_DEFINED__ */ + + +EXTERN_C const CLSID CLSID_MsTscAx; + +#ifdef __cplusplus + +class DECLSPEC_UUID("A41A4187-5A86-4E26-B40A-856F9035D9CB") +MsTscAx; +#endif + +EXTERN_C const CLSID CLSID_MsRdpClient; + +#ifdef __cplusplus + +class DECLSPEC_UUID("7CACBD7B-0D99-468F-AC33-22E495C0AFE5") +MsRdpClient; +#endif + +EXTERN_C const CLSID CLSID_MsRdpClient2; + +#ifdef __cplusplus + +class DECLSPEC_UUID("3523C2FB-4031-44E4-9A3B-F1E94986EE7F") +MsRdpClient2; +#endif + +EXTERN_C const CLSID CLSID_MsRdpClient3; + +#ifdef __cplusplus + +class DECLSPEC_UUID("ACE575FD-1FCF-4074-9401-EBAB990FA9DE") +MsRdpClient3; +#endif + +EXTERN_C const CLSID CLSID_MsRdpClient4; + +#ifdef __cplusplus + +class DECLSPEC_UUID("6AE29350-321B-42BE-BBE5-12FB5270C0DE") +MsRdpClient4; +#endif +#endif /* __MSTSCLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_i.c b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_i.c new file mode 100644 index 00000000000..b66a1a51b68 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_i.c @@ -0,0 +1,145 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 7.00.0493 */ +/* at Sun Aug 13 16:46:06 2006 + */ +/* Compiler settings for .\mstsclib.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_MSTSCLib,0x8C11EFA1,0x92C3,0x11D1,0xBC,0x1E,0x00,0xC0,0x4F,0xA3,0x14,0x89); + + +MIDL_DEFINE_GUID(IID, DIID_IMsTscAxEvents,0x336D5562,0xEFA8,0x482E,0x8C,0xB3,0xC5,0xC0,0xFC,0x7A,0x7D,0xB6); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscAx,0x8C11EFAE,0x92C3,0x11D1,0xBC,0x1E,0x00,0xC0,0x4F,0xA3,0x14,0x89); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClient,0x92B4A539,0x7115,0x4B7C,0xA5,0xA9,0xE5,0xD9,0xEF,0xC2,0x78,0x0A); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClient2,0xE7E17DC4,0x3B71,0x4BA7,0xA8,0xE6,0x28,0x1F,0xFA,0xDC,0xA2,0x8F); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClient3,0x91B7CBC5,0xA72E,0x4FA0,0x93,0x00,0xD6,0x47,0xD7,0xE8,0x97,0xFF); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClient4,0x095E0738,0xD97D,0x488B,0xB9,0xF6,0xDD,0x0E,0x8D,0x66,0xC0,0xDE); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscNonScriptable,0xC1E6743A,0x41C1,0x4A74,0x83,0x2A,0x0D,0xD0,0x6C,0x1C,0x7A,0x0E); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientNonScriptable,0x2F079C4C,0x87B2,0x4AFD,0x97,0xAB,0x20,0xCD,0xB4,0x30,0x38,0xAE); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientNonScriptable2,0x17A5E535,0x4072,0x4FA4,0xAF,0x32,0xC8,0xD0,0xD4,0x73,0x45,0xE9); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscAdvancedSettings,0x809945CC,0x4B3B,0x4A92,0xA6,0xB0,0xDB,0xF9,0xB5,0xF2,0xEF,0x2D); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientAdvancedSettings,0x3C65B4AB,0x12B3,0x465B,0xAC,0xD4,0xB8,0xDA,0xD3,0xBF,0xF9,0xE2); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientAdvancedSettings2,0x9AC42117,0x2B76,0x4320,0xAA,0x44,0x0E,0x61,0x6A,0xB8,0x43,0x7B); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientAdvancedSettings3,0x19CD856B,0xC542,0x4C53,0xAC,0xEE,0xF1,0x27,0xE3,0xBE,0x1A,0x59); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientAdvancedSettings4,0xFBA7F64E,0x7345,0x4405,0xAE,0x50,0xFA,0x4A,0x76,0x3D,0xC0,0xDE); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscSecuredSettings,0xC9D65442,0xA0F9,0x45B2,0x8F,0x73,0xD6,0x1D,0x2D,0xB8,0xCB,0xB6); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientSecuredSettings,0x605BEFCF,0x39C1,0x45CC,0xA8,0x11,0x06,0x8F,0xB7,0xBE,0x34,0x6D); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscDebug,0x209D0EB9,0x6254,0x47B1,0x90,0x33,0xA9,0x8D,0xAE,0x55,0xBB,0x27); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsTscAx,0xA41A4187,0x5A86,0x4E26,0xB4,0x0A,0x85,0x6F,0x90,0x35,0xD9,0xCB); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsRdpClient,0x7CACBD7B,0x0D99,0x468F,0xAC,0x33,0x22,0xE4,0x95,0xC0,0xAF,0xE5); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsRdpClient2,0x3523C2FB,0x4031,0x44E4,0x9A,0x3B,0xF1,0xE9,0x49,0x86,0xEE,0x7F); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsRdpClient3,0xACE575FD,0x1FCF,0x4074,0x94,0x01,0xEB,0xAB,0x99,0x0F,0xA9,0xDE); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsRdpClient4,0x6AE29350,0x321B,0x42BE,0xBB,0xE5,0x12,0xFB,0x52,0x70,0xC0,0xDE); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist.idl b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist.idl new file mode 100644 index 00000000000..8a2421bc5e5 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist.idl @@ -0,0 +1,3 @@ +#define MSTSCLIB_REDIST_ +#include "./mstsclib.idl" +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist.rc b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist.rc new file mode 100644 index 00000000000..3cbb8ee6746 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist.rc @@ -0,0 +1,3 @@ +#define TYPELIB_RESOURCEID__ 2 +#include "./typelib.rh" +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_h.h b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_h.h new file mode 100644 index 00000000000..3ee3213df53 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_h.h @@ -0,0 +1,8946 @@ + + +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + + /* File created by MIDL compiler version 7.00.0493 */ +/* at Sun Aug 13 16:46:05 2006 + */ +/* Compiler settings for .\mstsclib_redist.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __RPCNDR_H_VERSION__ +#error this stub requires an updated version of +#endif // __RPCNDR_H_VERSION__ + + +#ifndef __mstsclib_redist_h_h__ +#define __mstsclib_redist_h_h__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +/* Forward Declarations */ + +#ifndef __IMsTscAxEvents_FWD_DEFINED__ +#define __IMsTscAxEvents_FWD_DEFINED__ +typedef interface IMsTscAxEvents IMsTscAxEvents; +#endif /* __IMsTscAxEvents_FWD_DEFINED__ */ + + +#ifndef __IMsTscAx_FWD_DEFINED__ +#define __IMsTscAx_FWD_DEFINED__ +typedef interface IMsTscAx IMsTscAx; +#endif /* __IMsTscAx_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClient_FWD_DEFINED__ +#define __IMsRdpClient_FWD_DEFINED__ +typedef interface IMsRdpClient IMsRdpClient; +#endif /* __IMsRdpClient_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClient2_FWD_DEFINED__ +#define __IMsRdpClient2_FWD_DEFINED__ +typedef interface IMsRdpClient2 IMsRdpClient2; +#endif /* __IMsRdpClient2_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClient3_FWD_DEFINED__ +#define __IMsRdpClient3_FWD_DEFINED__ +typedef interface IMsRdpClient3 IMsRdpClient3; +#endif /* __IMsRdpClient3_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClient4_FWD_DEFINED__ +#define __IMsRdpClient4_FWD_DEFINED__ +typedef interface IMsRdpClient4 IMsRdpClient4; +#endif /* __IMsRdpClient4_FWD_DEFINED__ */ + + +#ifndef __IMsTscNonScriptable_FWD_DEFINED__ +#define __IMsTscNonScriptable_FWD_DEFINED__ +typedef interface IMsTscNonScriptable IMsTscNonScriptable; +#endif /* __IMsTscNonScriptable_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientNonScriptable_FWD_DEFINED__ +#define __IMsRdpClientNonScriptable_FWD_DEFINED__ +typedef interface IMsRdpClientNonScriptable IMsRdpClientNonScriptable; +#endif /* __IMsRdpClientNonScriptable_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientNonScriptable2_FWD_DEFINED__ +#define __IMsRdpClientNonScriptable2_FWD_DEFINED__ +typedef interface IMsRdpClientNonScriptable2 IMsRdpClientNonScriptable2; +#endif /* __IMsRdpClientNonScriptable2_FWD_DEFINED__ */ + + +#ifndef __IMsTscAdvancedSettings_FWD_DEFINED__ +#define __IMsTscAdvancedSettings_FWD_DEFINED__ +typedef interface IMsTscAdvancedSettings IMsTscAdvancedSettings; +#endif /* __IMsTscAdvancedSettings_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings_FWD_DEFINED__ +#define __IMsRdpClientAdvancedSettings_FWD_DEFINED__ +typedef interface IMsRdpClientAdvancedSettings IMsRdpClientAdvancedSettings; +#endif /* __IMsRdpClientAdvancedSettings_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings2_FWD_DEFINED__ +#define __IMsRdpClientAdvancedSettings2_FWD_DEFINED__ +typedef interface IMsRdpClientAdvancedSettings2 IMsRdpClientAdvancedSettings2; +#endif /* __IMsRdpClientAdvancedSettings2_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings3_FWD_DEFINED__ +#define __IMsRdpClientAdvancedSettings3_FWD_DEFINED__ +typedef interface IMsRdpClientAdvancedSettings3 IMsRdpClientAdvancedSettings3; +#endif /* __IMsRdpClientAdvancedSettings3_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings4_FWD_DEFINED__ +#define __IMsRdpClientAdvancedSettings4_FWD_DEFINED__ +typedef interface IMsRdpClientAdvancedSettings4 IMsRdpClientAdvancedSettings4; +#endif /* __IMsRdpClientAdvancedSettings4_FWD_DEFINED__ */ + + +#ifndef __IMsTscSecuredSettings_FWD_DEFINED__ +#define __IMsTscSecuredSettings_FWD_DEFINED__ +typedef interface IMsTscSecuredSettings IMsTscSecuredSettings; +#endif /* __IMsTscSecuredSettings_FWD_DEFINED__ */ + + +#ifndef __IMsRdpClientSecuredSettings_FWD_DEFINED__ +#define __IMsRdpClientSecuredSettings_FWD_DEFINED__ +typedef interface IMsRdpClientSecuredSettings IMsRdpClientSecuredSettings; +#endif /* __IMsRdpClientSecuredSettings_FWD_DEFINED__ */ + + +#ifndef __IMsTscDebug_FWD_DEFINED__ +#define __IMsTscDebug_FWD_DEFINED__ +typedef interface IMsTscDebug IMsTscDebug; +#endif /* __IMsTscDebug_FWD_DEFINED__ */ + + +#ifndef __MsTscAx_FWD_DEFINED__ +#define __MsTscAx_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsTscAx MsTscAx; +#else +typedef struct MsTscAx MsTscAx; +#endif /* __cplusplus */ + +#endif /* __MsTscAx_FWD_DEFINED__ */ + + +#ifndef __MsRdpClient_FWD_DEFINED__ +#define __MsRdpClient_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsRdpClient MsRdpClient; +#else +typedef struct MsRdpClient MsRdpClient; +#endif /* __cplusplus */ + +#endif /* __MsRdpClient_FWD_DEFINED__ */ + + +#ifndef __MsRdpClient2_FWD_DEFINED__ +#define __MsRdpClient2_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsRdpClient2 MsRdpClient2; +#else +typedef struct MsRdpClient2 MsRdpClient2; +#endif /* __cplusplus */ + +#endif /* __MsRdpClient2_FWD_DEFINED__ */ + + +#ifndef __MsRdpClient3_FWD_DEFINED__ +#define __MsRdpClient3_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsRdpClient3 MsRdpClient3; +#else +typedef struct MsRdpClient3 MsRdpClient3; +#endif /* __cplusplus */ + +#endif /* __MsRdpClient3_FWD_DEFINED__ */ + + +#ifndef __MsRdpClient4_FWD_DEFINED__ +#define __MsRdpClient4_FWD_DEFINED__ + +#ifdef __cplusplus +typedef class MsRdpClient4 MsRdpClient4; +#else +typedef struct MsRdpClient4 MsRdpClient4; +#endif /* __cplusplus */ + +#endif /* __MsRdpClient4_FWD_DEFINED__ */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + + +#ifndef __MSTSCLib_LIBRARY_DEFINED__ +#define __MSTSCLib_LIBRARY_DEFINED__ + +/* library MSTSCLib */ +/* [version][uuid] */ + + + + + + + + + + + + + + + + + + +typedef /* [public][public][public] */ +enum __MIDL___MIDL_itf_mstsax_0275_0001 + { autoReconnectContinueAutomatic = 0, + autoReconnectContinueStop = 1, + autoReconnectContinueManual = 2 + } AutoReconnectContinueState; + +typedef /* [public][public][public] */ +enum __MIDL_IMsRdpClient_0001 + { exDiscReasonNoInfo = 0, + exDiscReasonAPIInitiatedDisconnect = 1, + exDiscReasonAPIInitiatedLogoff = 2, + exDiscReasonServerIdleTimeout = 3, + exDiscReasonServerLogonTimeout = 4, + exDiscReasonReplacedByOtherConnection = 5, + exDiscReasonOutOfMemory = 6, + exDiscReasonServerDeniedConnection = 7, + exDiscReasonServerDeniedConnectionFips = 8, + exDiscReasonLicenseInternal = 256, + exDiscReasonLicenseNoLicenseServer = 257, + exDiscReasonLicenseNoLicense = 258, + exDiscReasonLicenseErrClientMsg = 259, + exDiscReasonLicenseHwidDoesntMatchLicense = 260, + exDiscReasonLicenseErrClientLicense = 261, + exDiscReasonLicenseCantFinishProtocol = 262, + exDiscReasonLicenseClientEndedProtocol = 263, + exDiscReasonLicenseErrClientEncryption = 264, + exDiscReasonLicenseCantUpgradeLicense = 265, + exDiscReasonLicenseNoRemoteConnections = 266, + exDiscReasonProtocolRangeStart = 4096, + exDiscReasonProtocolRangeEnd = 32767 + } ExtendedDisconnectReasonCode; + +typedef /* [public][public][public] */ +enum __MIDL_IMsRdpClient_0002 + { controlCloseCanProceed = 0, + controlCloseWaitForEvents = 1 + } ControlCloseStatus; + +typedef /* [custom][public] */ unsigned __int3264 UINT_PTR; + +typedef /* [custom][public] */ __int3264 LONG_PTR; + + +EXTERN_C const IID LIBID_MSTSCLib; + +#ifndef __IMsTscAxEvents_DISPINTERFACE_DEFINED__ +#define __IMsTscAxEvents_DISPINTERFACE_DEFINED__ + +/* dispinterface IMsTscAxEvents */ +/* [uuid] */ + + +EXTERN_C const IID DIID_IMsTscAxEvents; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("336D5562-EFA8-482E-8CB3-C5C0FC7A7DB6") + IMsTscAxEvents : public IDispatch + { + }; + +#else /* C style interface */ + + typedef struct IMsTscAxEventsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscAxEvents * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscAxEvents * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscAxEvents * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscAxEvents * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscAxEvents * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscAxEvents * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscAxEvents * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + END_INTERFACE + } IMsTscAxEventsVtbl; + + interface IMsTscAxEvents + { + CONST_VTBL struct IMsTscAxEventsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscAxEvents_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscAxEvents_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscAxEvents_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscAxEvents_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscAxEvents_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscAxEvents_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscAxEvents_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* __IMsTscAxEvents_DISPINTERFACE_DEFINED__ */ + + +#ifndef __IMsTscAx_INTERFACE_DEFINED__ +#define __IMsTscAx_INTERFACE_DEFINED__ + +/* interface IMsTscAx */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsTscAx; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("327BB5CD-834E-4400-AEF2-B30E15E5D682") + IMsTscAx : public IDispatch + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Server( + /* [in] */ BSTR pServer) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Server( + /* [retval][out] */ BSTR *pServer) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Domain( + /* [in] */ BSTR pDomain) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Domain( + /* [retval][out] */ BSTR *pDomain) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_UserName( + /* [in] */ BSTR pUserName) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_UserName( + /* [retval][out] */ BSTR *pUserName) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DisconnectedText( + /* [in] */ BSTR pDisconnectedText) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DisconnectedText( + /* [retval][out] */ BSTR *pDisconnectedText) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectingText( + /* [in] */ BSTR pConnectingText) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectingText( + /* [retval][out] */ BSTR *pConnectingText) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Connected( + /* [retval][out] */ short *pIsConnected) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DesktopWidth( + /* [in] */ long pVal) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DesktopWidth( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DesktopHeight( + /* [in] */ long pVal) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DesktopHeight( + /* [retval][out] */ long *pVal) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_StartConnected( + /* [in] */ long pfStartConnected) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_StartConnected( + /* [retval][out] */ long *pfStartConnected) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HorizontalScrollBarVisible( + /* [retval][out] */ long *pfHScrollVisible) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_VerticalScrollBarVisible( + /* [retval][out] */ long *pfVScrollVisible) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_FullScreenTitle( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CipherStrength( + /* [retval][out] */ long *pCipherStrength) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Version( + /* [retval][out] */ BSTR *pVersion) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SecuredSettingsEnabled( + /* [retval][out] */ long *pSecuredSettingsEnabled) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SecuredSettings( + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings( + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings) = 0; + + virtual /* [hidden][propget][id] */ HRESULT STDMETHODCALLTYPE get_Debugger( + /* [retval][out] */ IMsTscDebug **ppDebugger) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE Connect( void) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE Disconnect( void) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE CreateVirtualChannels( + /* [in] */ BSTR newVal) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE SendOnVirtualChannel( + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscAxVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscAx * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscAx * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscAx * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscAx * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscAx * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscAx * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscAx * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsTscAx * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsTscAx * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsTscAx * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsTscAx * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsTscAx * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsTscAx * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsTscAx * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsTscAx * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsTscAx * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsTscAx * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsTscAx * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsTscAx * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsTscAx * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsTscAx * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsTscAx * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsTscAx * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsTscAx * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsTscAx * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsTscAx * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsTscAx * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsTscAx * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsTscAx * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsTscAx * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsTscAx * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsTscAx * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + END_INTERFACE + } IMsTscAxVtbl; + + interface IMsTscAx + { + CONST_VTBL struct IMsTscAxVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscAx_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscAx_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscAx_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscAx_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscAx_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscAx_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscAx_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsTscAx_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsTscAx_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsTscAx_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsTscAx_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsTscAx_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsTscAx_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsTscAx_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsTscAx_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsTscAx_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsTscAx_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsTscAx_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsTscAx_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsTscAx_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsTscAx_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsTscAx_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsTscAx_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsTscAx_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsTscAx_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsTscAx_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsTscAx_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsTscAx_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsTscAx_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsTscAx_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsTscAx_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsTscAx_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsTscAx_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsTscAx_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsTscAx_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsTscAx_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsTscAx_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscAx_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClient_INTERFACE_DEFINED__ +#define __IMsRdpClient_INTERFACE_DEFINED__ + +/* interface IMsRdpClient */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClient; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("92B4A539-7115-4B7C-A5A9-E5D9EFC2780A") + IMsRdpClient : public IMsTscAx + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ColorDepth( + /* [in] */ long pcolorDepth) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ColorDepth( + /* [retval][out] */ long *pcolorDepth) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings2( + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SecuredSettings2( + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ExtendedDisconnectReason( + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_FullScreen( + /* [in] */ VARIANT_BOOL pfFullScreen) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_FullScreen( + /* [retval][out] */ VARIANT_BOOL *pfFullScreen) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE SetVirtualChannelOptions( + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetVirtualChannelOptions( + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions) = 0; + + virtual /* [id] */ HRESULT STDMETHODCALLTYPE RequestClose( + /* [retval][out] */ ControlCloseStatus *pCloseStatus) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClient * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClient * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClient * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClient * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClient * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClient * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClient * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsRdpClient * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsRdpClient * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsRdpClient * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsRdpClient * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsRdpClient * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsRdpClient * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsRdpClient * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsRdpClient * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsRdpClient * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsRdpClient * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsRdpClient * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsRdpClient * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsRdpClient * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsRdpClient * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsRdpClient * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsRdpClient * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsRdpClient * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsRdpClient * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsRdpClient * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsRdpClient * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsRdpClient * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsRdpClient * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsRdpClient * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsRdpClient * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsRdpClient * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ColorDepth )( + IMsRdpClient * This, + /* [in] */ long pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ColorDepth )( + IMsRdpClient * This, + /* [retval][out] */ long *pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings2 )( + IMsRdpClient * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings2 )( + IMsRdpClient * This, + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExtendedDisconnectReason )( + IMsRdpClient * This, + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClient * This, + /* [in] */ VARIANT_BOOL pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClient * This, + /* [retval][out] */ VARIANT_BOOL *pfFullScreen); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SetVirtualChannelOptions )( + IMsRdpClient * This, + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *GetVirtualChannelOptions )( + IMsRdpClient * This, + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *RequestClose )( + IMsRdpClient * This, + /* [retval][out] */ ControlCloseStatus *pCloseStatus); + + END_INTERFACE + } IMsRdpClientVtbl; + + interface IMsRdpClient + { + CONST_VTBL struct IMsRdpClientVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClient_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClient_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClient_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClient_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClient_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClient_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClient_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClient_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsRdpClient_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsRdpClient_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsRdpClient_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsRdpClient_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsRdpClient_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsRdpClient_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsRdpClient_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsRdpClient_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsRdpClient_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsRdpClient_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsRdpClient_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsRdpClient_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsRdpClient_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsRdpClient_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsRdpClient_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsRdpClient_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsRdpClient_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsRdpClient_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsRdpClient_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsRdpClient_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsRdpClient_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsRdpClient_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsRdpClient_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + + +#define IMsRdpClient_put_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> put_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient_get_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> get_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient_get_AdvancedSettings2(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings2(This,ppAdvSettings) ) + +#define IMsRdpClient_get_SecuredSettings2(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings2(This,ppSecuredSettings) ) + +#define IMsRdpClient_get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) \ + ( (This)->lpVtbl -> get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) ) + +#define IMsRdpClient_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient_SetVirtualChannelOptions(This,chanName,chanOptions) \ + ( (This)->lpVtbl -> SetVirtualChannelOptions(This,chanName,chanOptions) ) + +#define IMsRdpClient_GetVirtualChannelOptions(This,chanName,pChanOptions) \ + ( (This)->lpVtbl -> GetVirtualChannelOptions(This,chanName,pChanOptions) ) + +#define IMsRdpClient_RequestClose(This,pCloseStatus) \ + ( (This)->lpVtbl -> RequestClose(This,pCloseStatus) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClient_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClient2_INTERFACE_DEFINED__ +#define __IMsRdpClient2_INTERFACE_DEFINED__ + +/* interface IMsRdpClient2 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClient2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("E7E17DC4-3B71-4BA7-A8E6-281FFADCA28F") + IMsRdpClient2 : public IMsRdpClient + { + public: + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings3( + /* [retval][out] */ IMsRdpClientAdvancedSettings2 **ppAdvSettings) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectedStatusText( + /* [in] */ BSTR pConnectedStatusText) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectedStatusText( + /* [retval][out] */ BSTR *pConnectedStatusText) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClient2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClient2 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClient2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClient2 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClient2 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClient2 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClient2 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClient2 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsRdpClient2 * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsRdpClient2 * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsRdpClient2 * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsRdpClient2 * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsRdpClient2 * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsRdpClient2 * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsRdpClient2 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsRdpClient2 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsRdpClient2 * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsRdpClient2 * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsRdpClient2 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsRdpClient2 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsRdpClient2 * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsRdpClient2 * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ColorDepth )( + IMsRdpClient2 * This, + /* [in] */ long pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ColorDepth )( + IMsRdpClient2 * This, + /* [retval][out] */ long *pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings2 )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings2 )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExtendedDisconnectReason )( + IMsRdpClient2 * This, + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClient2 * This, + /* [in] */ VARIANT_BOOL pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClient2 * This, + /* [retval][out] */ VARIANT_BOOL *pfFullScreen); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SetVirtualChannelOptions )( + IMsRdpClient2 * This, + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *GetVirtualChannelOptions )( + IMsRdpClient2 * This, + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *RequestClose )( + IMsRdpClient2 * This, + /* [retval][out] */ ControlCloseStatus *pCloseStatus); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings3 )( + IMsRdpClient2 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings2 **ppAdvSettings); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectedStatusText )( + IMsRdpClient2 * This, + /* [in] */ BSTR pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectedStatusText )( + IMsRdpClient2 * This, + /* [retval][out] */ BSTR *pConnectedStatusText); + + END_INTERFACE + } IMsRdpClient2Vtbl; + + interface IMsRdpClient2 + { + CONST_VTBL struct IMsRdpClient2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClient2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClient2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClient2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClient2_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClient2_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClient2_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClient2_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClient2_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsRdpClient2_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsRdpClient2_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsRdpClient2_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsRdpClient2_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsRdpClient2_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsRdpClient2_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient2_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient2_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient2_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient2_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsRdpClient2_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsRdpClient2_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsRdpClient2_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsRdpClient2_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsRdpClient2_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient2_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient2_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsRdpClient2_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsRdpClient2_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsRdpClient2_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsRdpClient2_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsRdpClient2_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsRdpClient2_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsRdpClient2_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsRdpClient2_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsRdpClient2_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsRdpClient2_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsRdpClient2_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsRdpClient2_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + + +#define IMsRdpClient2_put_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> put_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient2_get_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> get_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient2_get_AdvancedSettings2(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings2(This,ppAdvSettings) ) + +#define IMsRdpClient2_get_SecuredSettings2(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings2(This,ppSecuredSettings) ) + +#define IMsRdpClient2_get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) \ + ( (This)->lpVtbl -> get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) ) + +#define IMsRdpClient2_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient2_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient2_SetVirtualChannelOptions(This,chanName,chanOptions) \ + ( (This)->lpVtbl -> SetVirtualChannelOptions(This,chanName,chanOptions) ) + +#define IMsRdpClient2_GetVirtualChannelOptions(This,chanName,pChanOptions) \ + ( (This)->lpVtbl -> GetVirtualChannelOptions(This,chanName,pChanOptions) ) + +#define IMsRdpClient2_RequestClose(This,pCloseStatus) \ + ( (This)->lpVtbl -> RequestClose(This,pCloseStatus) ) + + +#define IMsRdpClient2_get_AdvancedSettings3(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings3(This,ppAdvSettings) ) + +#define IMsRdpClient2_put_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> put_ConnectedStatusText(This,pConnectedStatusText) ) + +#define IMsRdpClient2_get_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> get_ConnectedStatusText(This,pConnectedStatusText) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClient2_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClient3_INTERFACE_DEFINED__ +#define __IMsRdpClient3_INTERFACE_DEFINED__ + +/* interface IMsRdpClient3 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClient3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("91B7CBC5-A72E-4FA0-9300-D647D7E897FF") + IMsRdpClient3 : public IMsRdpClient2 + { + public: + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings4( + /* [retval][out] */ IMsRdpClientAdvancedSettings3 **ppAdvSettings) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClient3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClient3 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClient3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClient3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClient3 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClient3 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClient3 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClient3 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsRdpClient3 * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsRdpClient3 * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsRdpClient3 * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsRdpClient3 * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsRdpClient3 * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsRdpClient3 * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsRdpClient3 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsRdpClient3 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsRdpClient3 * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsRdpClient3 * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsRdpClient3 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsRdpClient3 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsRdpClient3 * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsRdpClient3 * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ColorDepth )( + IMsRdpClient3 * This, + /* [in] */ long pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ColorDepth )( + IMsRdpClient3 * This, + /* [retval][out] */ long *pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings2 )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings2 )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExtendedDisconnectReason )( + IMsRdpClient3 * This, + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClient3 * This, + /* [in] */ VARIANT_BOOL pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClient3 * This, + /* [retval][out] */ VARIANT_BOOL *pfFullScreen); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SetVirtualChannelOptions )( + IMsRdpClient3 * This, + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *GetVirtualChannelOptions )( + IMsRdpClient3 * This, + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *RequestClose )( + IMsRdpClient3 * This, + /* [retval][out] */ ControlCloseStatus *pCloseStatus); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings3 )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings2 **ppAdvSettings); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectedStatusText )( + IMsRdpClient3 * This, + /* [in] */ BSTR pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectedStatusText )( + IMsRdpClient3 * This, + /* [retval][out] */ BSTR *pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings4 )( + IMsRdpClient3 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings3 **ppAdvSettings); + + END_INTERFACE + } IMsRdpClient3Vtbl; + + interface IMsRdpClient3 + { + CONST_VTBL struct IMsRdpClient3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClient3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClient3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClient3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClient3_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClient3_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClient3_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClient3_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClient3_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsRdpClient3_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsRdpClient3_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsRdpClient3_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsRdpClient3_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsRdpClient3_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsRdpClient3_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient3_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient3_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient3_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient3_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsRdpClient3_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsRdpClient3_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsRdpClient3_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsRdpClient3_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsRdpClient3_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient3_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient3_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsRdpClient3_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsRdpClient3_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsRdpClient3_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsRdpClient3_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsRdpClient3_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsRdpClient3_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsRdpClient3_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsRdpClient3_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsRdpClient3_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsRdpClient3_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsRdpClient3_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsRdpClient3_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + + +#define IMsRdpClient3_put_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> put_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient3_get_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> get_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient3_get_AdvancedSettings2(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings2(This,ppAdvSettings) ) + +#define IMsRdpClient3_get_SecuredSettings2(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings2(This,ppSecuredSettings) ) + +#define IMsRdpClient3_get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) \ + ( (This)->lpVtbl -> get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) ) + +#define IMsRdpClient3_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient3_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient3_SetVirtualChannelOptions(This,chanName,chanOptions) \ + ( (This)->lpVtbl -> SetVirtualChannelOptions(This,chanName,chanOptions) ) + +#define IMsRdpClient3_GetVirtualChannelOptions(This,chanName,pChanOptions) \ + ( (This)->lpVtbl -> GetVirtualChannelOptions(This,chanName,pChanOptions) ) + +#define IMsRdpClient3_RequestClose(This,pCloseStatus) \ + ( (This)->lpVtbl -> RequestClose(This,pCloseStatus) ) + + +#define IMsRdpClient3_get_AdvancedSettings3(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings3(This,ppAdvSettings) ) + +#define IMsRdpClient3_put_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> put_ConnectedStatusText(This,pConnectedStatusText) ) + +#define IMsRdpClient3_get_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> get_ConnectedStatusText(This,pConnectedStatusText) ) + + +#define IMsRdpClient3_get_AdvancedSettings4(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings4(This,ppAdvSettings) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClient3_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClient4_INTERFACE_DEFINED__ +#define __IMsRdpClient4_INTERFACE_DEFINED__ + +/* interface IMsRdpClient4 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClient4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("095E0738-D97D-488B-B9F6-DD0E8D66C0DE") + IMsRdpClient4 : public IMsRdpClient3 + { + public: + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AdvancedSettings5( + /* [retval][out] */ IMsRdpClientAdvancedSettings4 **ppAdvSettings5) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClient4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClient4 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClient4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClient4 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClient4 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClient4 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClient4 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClient4 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Server )( + IMsRdpClient4 * This, + /* [in] */ BSTR pServer); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Server )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pServer); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Domain )( + IMsRdpClient4 * This, + /* [in] */ BSTR pDomain); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Domain )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pDomain); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_UserName )( + IMsRdpClient4 * This, + /* [in] */ BSTR pUserName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_UserName )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pUserName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisconnectedText )( + IMsRdpClient4 * This, + /* [in] */ BSTR pDisconnectedText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisconnectedText )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pDisconnectedText); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectingText )( + IMsRdpClient4 * This, + /* [in] */ BSTR pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectingText )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pConnectingText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Connected )( + IMsRdpClient4 * This, + /* [retval][out] */ short *pIsConnected); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopWidth )( + IMsRdpClient4 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopWidth )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DesktopHeight )( + IMsRdpClient4 * This, + /* [in] */ long pVal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DesktopHeight )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pVal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartConnected )( + IMsRdpClient4 * This, + /* [in] */ long pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartConnected )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pfStartConnected); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HorizontalScrollBarVisible )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pfHScrollVisible); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_VerticalScrollBarVisible )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pfVScrollVisible); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreenTitle )( + IMsRdpClient4 * This, + /* [in] */ BSTR rhs); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CipherStrength )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pCipherStrength); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Version )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pVersion); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettingsEnabled )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pSecuredSettingsEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsTscSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsTscAdvancedSettings **ppAdvSettings); + + /* [hidden][propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Debugger )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsTscDebug **ppDebugger); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Connect )( + IMsRdpClient4 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *Disconnect )( + IMsRdpClient4 * This); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *CreateVirtualChannels )( + IMsRdpClient4 * This, + /* [in] */ BSTR newVal); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SendOnVirtualChannel )( + IMsRdpClient4 * This, + /* [in] */ BSTR chanName, + /* [in] */ BSTR ChanData); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ColorDepth )( + IMsRdpClient4 * This, + /* [in] */ long pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ColorDepth )( + IMsRdpClient4 * This, + /* [retval][out] */ long *pcolorDepth); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings2 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SecuredSettings2 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientSecuredSettings **ppSecuredSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ExtendedDisconnectReason )( + IMsRdpClient4 * This, + /* [retval][out] */ ExtendedDisconnectReasonCode *pExtendedDisconnectReason); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClient4 * This, + /* [in] */ VARIANT_BOOL pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClient4 * This, + /* [retval][out] */ VARIANT_BOOL *pfFullScreen); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *SetVirtualChannelOptions )( + IMsRdpClient4 * This, + /* [in] */ BSTR chanName, + /* [in] */ long chanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *GetVirtualChannelOptions )( + IMsRdpClient4 * This, + /* [in] */ BSTR chanName, + /* [retval][out] */ long *pChanOptions); + + /* [id] */ HRESULT ( STDMETHODCALLTYPE *RequestClose )( + IMsRdpClient4 * This, + /* [retval][out] */ ControlCloseStatus *pCloseStatus); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings3 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings2 **ppAdvSettings); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectedStatusText )( + IMsRdpClient4 * This, + /* [in] */ BSTR pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectedStatusText )( + IMsRdpClient4 * This, + /* [retval][out] */ BSTR *pConnectedStatusText); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings4 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings3 **ppAdvSettings); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AdvancedSettings5 )( + IMsRdpClient4 * This, + /* [retval][out] */ IMsRdpClientAdvancedSettings4 **ppAdvSettings5); + + END_INTERFACE + } IMsRdpClient4Vtbl; + + interface IMsRdpClient4 + { + CONST_VTBL struct IMsRdpClient4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClient4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClient4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClient4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClient4_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClient4_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClient4_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClient4_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClient4_put_Server(This,pServer) \ + ( (This)->lpVtbl -> put_Server(This,pServer) ) + +#define IMsRdpClient4_get_Server(This,pServer) \ + ( (This)->lpVtbl -> get_Server(This,pServer) ) + +#define IMsRdpClient4_put_Domain(This,pDomain) \ + ( (This)->lpVtbl -> put_Domain(This,pDomain) ) + +#define IMsRdpClient4_get_Domain(This,pDomain) \ + ( (This)->lpVtbl -> get_Domain(This,pDomain) ) + +#define IMsRdpClient4_put_UserName(This,pUserName) \ + ( (This)->lpVtbl -> put_UserName(This,pUserName) ) + +#define IMsRdpClient4_get_UserName(This,pUserName) \ + ( (This)->lpVtbl -> get_UserName(This,pUserName) ) + +#define IMsRdpClient4_put_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> put_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient4_get_DisconnectedText(This,pDisconnectedText) \ + ( (This)->lpVtbl -> get_DisconnectedText(This,pDisconnectedText) ) + +#define IMsRdpClient4_put_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> put_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient4_get_ConnectingText(This,pConnectingText) \ + ( (This)->lpVtbl -> get_ConnectingText(This,pConnectingText) ) + +#define IMsRdpClient4_get_Connected(This,pIsConnected) \ + ( (This)->lpVtbl -> get_Connected(This,pIsConnected) ) + +#define IMsRdpClient4_put_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopWidth(This,pVal) ) + +#define IMsRdpClient4_get_DesktopWidth(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopWidth(This,pVal) ) + +#define IMsRdpClient4_put_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> put_DesktopHeight(This,pVal) ) + +#define IMsRdpClient4_get_DesktopHeight(This,pVal) \ + ( (This)->lpVtbl -> get_DesktopHeight(This,pVal) ) + +#define IMsRdpClient4_put_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> put_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient4_get_StartConnected(This,pfStartConnected) \ + ( (This)->lpVtbl -> get_StartConnected(This,pfStartConnected) ) + +#define IMsRdpClient4_get_HorizontalScrollBarVisible(This,pfHScrollVisible) \ + ( (This)->lpVtbl -> get_HorizontalScrollBarVisible(This,pfHScrollVisible) ) + +#define IMsRdpClient4_get_VerticalScrollBarVisible(This,pfVScrollVisible) \ + ( (This)->lpVtbl -> get_VerticalScrollBarVisible(This,pfVScrollVisible) ) + +#define IMsRdpClient4_put_FullScreenTitle(This,rhs) \ + ( (This)->lpVtbl -> put_FullScreenTitle(This,rhs) ) + +#define IMsRdpClient4_get_CipherStrength(This,pCipherStrength) \ + ( (This)->lpVtbl -> get_CipherStrength(This,pCipherStrength) ) + +#define IMsRdpClient4_get_Version(This,pVersion) \ + ( (This)->lpVtbl -> get_Version(This,pVersion) ) + +#define IMsRdpClient4_get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) \ + ( (This)->lpVtbl -> get_SecuredSettingsEnabled(This,pSecuredSettingsEnabled) ) + +#define IMsRdpClient4_get_SecuredSettings(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings(This,ppSecuredSettings) ) + +#define IMsRdpClient4_get_AdvancedSettings(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings(This,ppAdvSettings) ) + +#define IMsRdpClient4_get_Debugger(This,ppDebugger) \ + ( (This)->lpVtbl -> get_Debugger(This,ppDebugger) ) + +#define IMsRdpClient4_Connect(This) \ + ( (This)->lpVtbl -> Connect(This) ) + +#define IMsRdpClient4_Disconnect(This) \ + ( (This)->lpVtbl -> Disconnect(This) ) + +#define IMsRdpClient4_CreateVirtualChannels(This,newVal) \ + ( (This)->lpVtbl -> CreateVirtualChannels(This,newVal) ) + +#define IMsRdpClient4_SendOnVirtualChannel(This,chanName,ChanData) \ + ( (This)->lpVtbl -> SendOnVirtualChannel(This,chanName,ChanData) ) + + +#define IMsRdpClient4_put_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> put_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient4_get_ColorDepth(This,pcolorDepth) \ + ( (This)->lpVtbl -> get_ColorDepth(This,pcolorDepth) ) + +#define IMsRdpClient4_get_AdvancedSettings2(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings2(This,ppAdvSettings) ) + +#define IMsRdpClient4_get_SecuredSettings2(This,ppSecuredSettings) \ + ( (This)->lpVtbl -> get_SecuredSettings2(This,ppSecuredSettings) ) + +#define IMsRdpClient4_get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) \ + ( (This)->lpVtbl -> get_ExtendedDisconnectReason(This,pExtendedDisconnectReason) ) + +#define IMsRdpClient4_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient4_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClient4_SetVirtualChannelOptions(This,chanName,chanOptions) \ + ( (This)->lpVtbl -> SetVirtualChannelOptions(This,chanName,chanOptions) ) + +#define IMsRdpClient4_GetVirtualChannelOptions(This,chanName,pChanOptions) \ + ( (This)->lpVtbl -> GetVirtualChannelOptions(This,chanName,pChanOptions) ) + +#define IMsRdpClient4_RequestClose(This,pCloseStatus) \ + ( (This)->lpVtbl -> RequestClose(This,pCloseStatus) ) + + +#define IMsRdpClient4_get_AdvancedSettings3(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings3(This,ppAdvSettings) ) + +#define IMsRdpClient4_put_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> put_ConnectedStatusText(This,pConnectedStatusText) ) + +#define IMsRdpClient4_get_ConnectedStatusText(This,pConnectedStatusText) \ + ( (This)->lpVtbl -> get_ConnectedStatusText(This,pConnectedStatusText) ) + + +#define IMsRdpClient4_get_AdvancedSettings4(This,ppAdvSettings) \ + ( (This)->lpVtbl -> get_AdvancedSettings4(This,ppAdvSettings) ) + + +#define IMsRdpClient4_get_AdvancedSettings5(This,ppAdvSettings5) \ + ( (This)->lpVtbl -> get_AdvancedSettings5(This,ppAdvSettings5) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClient4_INTERFACE_DEFINED__ */ + + +#ifndef __IMsTscNonScriptable_INTERFACE_DEFINED__ +#define __IMsTscNonScriptable_INTERFACE_DEFINED__ + +/* interface IMsTscNonScriptable */ +/* [object][uuid] */ + + +EXTERN_C const IID IID_IMsTscNonScriptable; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C1E6743A-41C1-4A74-832A-0DD06C1C7A0E") + IMsTscNonScriptable : public IUnknown + { + public: + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_ClearTextPassword( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_PortablePassword( + /* [in] */ BSTR pPortablePass) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_PortablePassword( + /* [retval][out] */ BSTR *pPortablePass) = 0; + + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_PortableSalt( + /* [in] */ BSTR pPortableSalt) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_PortableSalt( + /* [retval][out] */ BSTR *pPortableSalt) = 0; + + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_BinaryPassword( + /* [in] */ BSTR pBinaryPassword) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_BinaryPassword( + /* [retval][out] */ BSTR *pBinaryPassword) = 0; + + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_BinarySalt( + /* [in] */ BSTR pSalt) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_BinarySalt( + /* [retval][out] */ BSTR *pSalt) = 0; + + virtual HRESULT STDMETHODCALLTYPE ResetPassword( void) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscNonScriptableVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscNonScriptable * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscNonScriptable * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscNonScriptable * This); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsTscNonScriptable * This, + /* [in] */ BSTR rhs); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortablePassword )( + IMsTscNonScriptable * This, + /* [in] */ BSTR pPortablePass); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortablePassword )( + IMsTscNonScriptable * This, + /* [retval][out] */ BSTR *pPortablePass); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortableSalt )( + IMsTscNonScriptable * This, + /* [in] */ BSTR pPortableSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortableSalt )( + IMsTscNonScriptable * This, + /* [retval][out] */ BSTR *pPortableSalt); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinaryPassword )( + IMsTscNonScriptable * This, + /* [in] */ BSTR pBinaryPassword); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinaryPassword )( + IMsTscNonScriptable * This, + /* [retval][out] */ BSTR *pBinaryPassword); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinarySalt )( + IMsTscNonScriptable * This, + /* [in] */ BSTR pSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinarySalt )( + IMsTscNonScriptable * This, + /* [retval][out] */ BSTR *pSalt); + + HRESULT ( STDMETHODCALLTYPE *ResetPassword )( + IMsTscNonScriptable * This); + + END_INTERFACE + } IMsTscNonScriptableVtbl; + + interface IMsTscNonScriptable + { + CONST_VTBL struct IMsTscNonScriptableVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscNonScriptable_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscNonScriptable_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscNonScriptable_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscNonScriptable_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsTscNonScriptable_put_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> put_PortablePassword(This,pPortablePass) ) + +#define IMsTscNonScriptable_get_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> get_PortablePassword(This,pPortablePass) ) + +#define IMsTscNonScriptable_put_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> put_PortableSalt(This,pPortableSalt) ) + +#define IMsTscNonScriptable_get_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> get_PortableSalt(This,pPortableSalt) ) + +#define IMsTscNonScriptable_put_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> put_BinaryPassword(This,pBinaryPassword) ) + +#define IMsTscNonScriptable_get_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> get_BinaryPassword(This,pBinaryPassword) ) + +#define IMsTscNonScriptable_put_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> put_BinarySalt(This,pSalt) ) + +#define IMsTscNonScriptable_get_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> get_BinarySalt(This,pSalt) ) + +#define IMsTscNonScriptable_ResetPassword(This) \ + ( (This)->lpVtbl -> ResetPassword(This) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscNonScriptable_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientNonScriptable_INTERFACE_DEFINED__ +#define __IMsRdpClientNonScriptable_INTERFACE_DEFINED__ + +/* interface IMsRdpClientNonScriptable */ +/* [object][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientNonScriptable; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("2F079C4C-87B2-4AFD-97AB-20CDB43038AE") + IMsRdpClientNonScriptable : public IMsTscNonScriptable + { + public: + virtual HRESULT STDMETHODCALLTYPE NotifyRedirectDeviceChange( + /* [in] */ UINT_PTR wParam, + /* [in] */ LONG_PTR lParam) = 0; + + virtual HRESULT STDMETHODCALLTYPE SendKeys( + /* [in] */ long numKeys, + /* [in] */ VARIANT_BOOL *pbArrayKeyUp, + /* [in] */ long *plKeyData) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientNonScriptableVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientNonScriptable * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientNonScriptable * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientNonScriptable * This); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR rhs); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortablePassword )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR pPortablePass); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortablePassword )( + IMsRdpClientNonScriptable * This, + /* [retval][out] */ BSTR *pPortablePass); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortableSalt )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR pPortableSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortableSalt )( + IMsRdpClientNonScriptable * This, + /* [retval][out] */ BSTR *pPortableSalt); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinaryPassword )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR pBinaryPassword); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinaryPassword )( + IMsRdpClientNonScriptable * This, + /* [retval][out] */ BSTR *pBinaryPassword); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinarySalt )( + IMsRdpClientNonScriptable * This, + /* [in] */ BSTR pSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinarySalt )( + IMsRdpClientNonScriptable * This, + /* [retval][out] */ BSTR *pSalt); + + HRESULT ( STDMETHODCALLTYPE *ResetPassword )( + IMsRdpClientNonScriptable * This); + + HRESULT ( STDMETHODCALLTYPE *NotifyRedirectDeviceChange )( + IMsRdpClientNonScriptable * This, + /* [in] */ UINT_PTR wParam, + /* [in] */ LONG_PTR lParam); + + HRESULT ( STDMETHODCALLTYPE *SendKeys )( + IMsRdpClientNonScriptable * This, + /* [in] */ long numKeys, + /* [in] */ VARIANT_BOOL *pbArrayKeyUp, + /* [in] */ long *plKeyData); + + END_INTERFACE + } IMsRdpClientNonScriptableVtbl; + + interface IMsRdpClientNonScriptable + { + CONST_VTBL struct IMsRdpClientNonScriptableVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientNonScriptable_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientNonScriptable_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientNonScriptable_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientNonScriptable_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientNonScriptable_put_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> put_PortablePassword(This,pPortablePass) ) + +#define IMsRdpClientNonScriptable_get_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> get_PortablePassword(This,pPortablePass) ) + +#define IMsRdpClientNonScriptable_put_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> put_PortableSalt(This,pPortableSalt) ) + +#define IMsRdpClientNonScriptable_get_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> get_PortableSalt(This,pPortableSalt) ) + +#define IMsRdpClientNonScriptable_put_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> put_BinaryPassword(This,pBinaryPassword) ) + +#define IMsRdpClientNonScriptable_get_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> get_BinaryPassword(This,pBinaryPassword) ) + +#define IMsRdpClientNonScriptable_put_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> put_BinarySalt(This,pSalt) ) + +#define IMsRdpClientNonScriptable_get_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> get_BinarySalt(This,pSalt) ) + +#define IMsRdpClientNonScriptable_ResetPassword(This) \ + ( (This)->lpVtbl -> ResetPassword(This) ) + + +#define IMsRdpClientNonScriptable_NotifyRedirectDeviceChange(This,wParam,lParam) \ + ( (This)->lpVtbl -> NotifyRedirectDeviceChange(This,wParam,lParam) ) + +#define IMsRdpClientNonScriptable_SendKeys(This,numKeys,pbArrayKeyUp,plKeyData) \ + ( (This)->lpVtbl -> SendKeys(This,numKeys,pbArrayKeyUp,plKeyData) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClientNonScriptable_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientNonScriptable2_INTERFACE_DEFINED__ +#define __IMsRdpClientNonScriptable2_INTERFACE_DEFINED__ + +/* interface IMsRdpClientNonScriptable2 */ +/* [object][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientNonScriptable2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("17A5E535-4072-4FA4-AF32-C8D0D47345E9") + IMsRdpClientNonScriptable2 : public IMsRdpClientNonScriptable + { + public: + virtual /* [propput] */ HRESULT STDMETHODCALLTYPE put_UIParentWindowHandle( + /* [in] */ HWND phwndUIParentWindowHandle) = 0; + + virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_UIParentWindowHandle( + /* [retval][out] */ HWND *phwndUIParentWindowHandle) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientNonScriptable2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientNonScriptable2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientNonScriptable2 * This); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR rhs); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortablePassword )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR pPortablePass); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortablePassword )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ BSTR *pPortablePass); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_PortableSalt )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR pPortableSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_PortableSalt )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ BSTR *pPortableSalt); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinaryPassword )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR pBinaryPassword); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinaryPassword )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ BSTR *pBinaryPassword); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_BinarySalt )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ BSTR pSalt); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_BinarySalt )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ BSTR *pSalt); + + HRESULT ( STDMETHODCALLTYPE *ResetPassword )( + IMsRdpClientNonScriptable2 * This); + + HRESULT ( STDMETHODCALLTYPE *NotifyRedirectDeviceChange )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ UINT_PTR wParam, + /* [in] */ LONG_PTR lParam); + + HRESULT ( STDMETHODCALLTYPE *SendKeys )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ long numKeys, + /* [in] */ VARIANT_BOOL *pbArrayKeyUp, + /* [in] */ long *plKeyData); + + /* [propput] */ HRESULT ( STDMETHODCALLTYPE *put_UIParentWindowHandle )( + IMsRdpClientNonScriptable2 * This, + /* [in] */ HWND phwndUIParentWindowHandle); + + /* [propget] */ HRESULT ( STDMETHODCALLTYPE *get_UIParentWindowHandle )( + IMsRdpClientNonScriptable2 * This, + /* [retval][out] */ HWND *phwndUIParentWindowHandle); + + END_INTERFACE + } IMsRdpClientNonScriptable2Vtbl; + + interface IMsRdpClientNonScriptable2 + { + CONST_VTBL struct IMsRdpClientNonScriptable2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientNonScriptable2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientNonScriptable2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientNonScriptable2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientNonScriptable2_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientNonScriptable2_put_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> put_PortablePassword(This,pPortablePass) ) + +#define IMsRdpClientNonScriptable2_get_PortablePassword(This,pPortablePass) \ + ( (This)->lpVtbl -> get_PortablePassword(This,pPortablePass) ) + +#define IMsRdpClientNonScriptable2_put_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> put_PortableSalt(This,pPortableSalt) ) + +#define IMsRdpClientNonScriptable2_get_PortableSalt(This,pPortableSalt) \ + ( (This)->lpVtbl -> get_PortableSalt(This,pPortableSalt) ) + +#define IMsRdpClientNonScriptable2_put_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> put_BinaryPassword(This,pBinaryPassword) ) + +#define IMsRdpClientNonScriptable2_get_BinaryPassword(This,pBinaryPassword) \ + ( (This)->lpVtbl -> get_BinaryPassword(This,pBinaryPassword) ) + +#define IMsRdpClientNonScriptable2_put_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> put_BinarySalt(This,pSalt) ) + +#define IMsRdpClientNonScriptable2_get_BinarySalt(This,pSalt) \ + ( (This)->lpVtbl -> get_BinarySalt(This,pSalt) ) + +#define IMsRdpClientNonScriptable2_ResetPassword(This) \ + ( (This)->lpVtbl -> ResetPassword(This) ) + + +#define IMsRdpClientNonScriptable2_NotifyRedirectDeviceChange(This,wParam,lParam) \ + ( (This)->lpVtbl -> NotifyRedirectDeviceChange(This,wParam,lParam) ) + +#define IMsRdpClientNonScriptable2_SendKeys(This,numKeys,pbArrayKeyUp,plKeyData) \ + ( (This)->lpVtbl -> SendKeys(This,numKeys,pbArrayKeyUp,plKeyData) ) + + +#define IMsRdpClientNonScriptable2_put_UIParentWindowHandle(This,phwndUIParentWindowHandle) \ + ( (This)->lpVtbl -> put_UIParentWindowHandle(This,phwndUIParentWindowHandle) ) + +#define IMsRdpClientNonScriptable2_get_UIParentWindowHandle(This,phwndUIParentWindowHandle) \ + ( (This)->lpVtbl -> get_UIParentWindowHandle(This,phwndUIParentWindowHandle) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClientNonScriptable2_INTERFACE_DEFINED__ */ + + +#ifndef __IMsTscAdvancedSettings_INTERFACE_DEFINED__ +#define __IMsTscAdvancedSettings_INTERFACE_DEFINED__ + +/* interface IMsTscAdvancedSettings */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsTscAdvancedSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("809945CC-4B3B-4A92-A6B0-DBF9B5F2EF2D") + IMsTscAdvancedSettings : public IDispatch + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Compress( + /* [in] */ long pcompress) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Compress( + /* [retval][out] */ long *pcompress) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapPeristence( + /* [in] */ long pbitmapPeristence) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapPeristence( + /* [retval][out] */ long *pbitmapPeristence) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_allowBackgroundInput( + /* [in] */ long pallowBackgroundInput) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_allowBackgroundInput( + /* [retval][out] */ long *pallowBackgroundInput) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyBoardLayoutStr( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PluginDlls( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_IconFile( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_IconIndex( + /* [in] */ long rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ContainerHandledFullScreen( + /* [in] */ long pContainerHandledFullScreen) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ContainerHandledFullScreen( + /* [retval][out] */ long *pContainerHandledFullScreen) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DisableRdpdr( + /* [in] */ long pDisableRdpdr) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DisableRdpdr( + /* [retval][out] */ long *pDisableRdpdr) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscAdvancedSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscAdvancedSettings * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscAdvancedSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscAdvancedSettings * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscAdvancedSettings * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscAdvancedSettings * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscAdvancedSettings * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscAdvancedSettings * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsTscAdvancedSettings * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsTscAdvancedSettings * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsTscAdvancedSettings * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsTscAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsTscAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsTscAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsTscAdvancedSettings * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsTscAdvancedSettings * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsTscAdvancedSettings * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsTscAdvancedSettings * This, + /* [retval][out] */ long *pDisableRdpdr); + + END_INTERFACE + } IMsTscAdvancedSettingsVtbl; + + interface IMsTscAdvancedSettings + { + CONST_VTBL struct IMsTscAdvancedSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscAdvancedSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscAdvancedSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscAdvancedSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscAdvancedSettings_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscAdvancedSettings_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscAdvancedSettings_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscAdvancedSettings_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsTscAdvancedSettings_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsTscAdvancedSettings_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsTscAdvancedSettings_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsTscAdvancedSettings_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsTscAdvancedSettings_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsTscAdvancedSettings_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsTscAdvancedSettings_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsTscAdvancedSettings_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsTscAdvancedSettings_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsTscAdvancedSettings_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsTscAdvancedSettings_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsTscAdvancedSettings_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsTscAdvancedSettings_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsTscAdvancedSettings_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscAdvancedSettings_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings_INTERFACE_DEFINED__ +#define __IMsRdpClientAdvancedSettings_INTERFACE_DEFINED__ + +/* interface IMsRdpClientAdvancedSettings */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientAdvancedSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("3C65B4AB-12B3-465B-ACD4-B8DAD3BFF9E2") + IMsRdpClientAdvancedSettings : public IMsTscAdvancedSettings + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SmoothScroll( + /* [in] */ long psmoothScroll) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SmoothScroll( + /* [retval][out] */ long *psmoothScroll) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_AcceleratorPassthrough( + /* [in] */ long pacceleratorPassthrough) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AcceleratorPassthrough( + /* [retval][out] */ long *pacceleratorPassthrough) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ShadowBitmap( + /* [in] */ long pshadowBitmap) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ShadowBitmap( + /* [retval][out] */ long *pshadowBitmap) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_TransportType( + /* [in] */ long ptransportType) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_TransportType( + /* [retval][out] */ long *ptransportType) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SasSequence( + /* [in] */ long psasSequence) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SasSequence( + /* [retval][out] */ long *psasSequence) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_EncryptionEnabled( + /* [in] */ long pencryptionEnabled) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_EncryptionEnabled( + /* [retval][out] */ long *pencryptionEnabled) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DedicatedTerminal( + /* [in] */ long pdedicatedTerminal) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DedicatedTerminal( + /* [retval][out] */ long *pdedicatedTerminal) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RDPPort( + /* [in] */ long prdpPort) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RDPPort( + /* [retval][out] */ long *prdpPort) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_EnableMouse( + /* [in] */ long penableMouse) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_EnableMouse( + /* [retval][out] */ long *penableMouse) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DisableCtrlAltDel( + /* [in] */ long pdisableCtrlAltDel) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DisableCtrlAltDel( + /* [retval][out] */ long *pdisableCtrlAltDel) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_EnableWindowsKey( + /* [in] */ long penableWindowsKey) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_EnableWindowsKey( + /* [retval][out] */ long *penableWindowsKey) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DoubleClickDetect( + /* [in] */ long pdoubleClickDetect) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DoubleClickDetect( + /* [retval][out] */ long *pdoubleClickDetect) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MaximizeShell( + /* [in] */ long pmaximizeShell) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MaximizeShell( + /* [retval][out] */ long *pmaximizeShell) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyFullScreen( + /* [in] */ long photKeyFullScreen) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyFullScreen( + /* [retval][out] */ long *photKeyFullScreen) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyCtrlEsc( + /* [in] */ long photKeyCtrlEsc) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyCtrlEsc( + /* [retval][out] */ long *photKeyCtrlEsc) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyAltEsc( + /* [in] */ long photKeyAltEsc) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyAltEsc( + /* [retval][out] */ long *photKeyAltEsc) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyAltTab( + /* [in] */ long photKeyAltTab) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyAltTab( + /* [retval][out] */ long *photKeyAltTab) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyAltShiftTab( + /* [in] */ long photKeyAltShiftTab) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyAltShiftTab( + /* [retval][out] */ long *photKeyAltShiftTab) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyAltSpace( + /* [in] */ long photKeyAltSpace) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyAltSpace( + /* [retval][out] */ long *photKeyAltSpace) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HotKeyCtrlAltDel( + /* [in] */ long photKeyCtrlAltDel) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HotKeyCtrlAltDel( + /* [retval][out] */ long *photKeyCtrlAltDel) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_orderDrawThreshold( + /* [in] */ long porderDrawThreshold) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_orderDrawThreshold( + /* [retval][out] */ long *porderDrawThreshold) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapCacheSize( + /* [in] */ long pbitmapCacheSize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapCacheSize( + /* [retval][out] */ long *pbitmapCacheSize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapVirtualCacheSize( + /* [in] */ long pbitmapVirtualCacheSize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapVirtualCacheSize( + /* [retval][out] */ long *pbitmapVirtualCacheSize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ScaleBitmapCachesByBPP( + /* [in] */ long pbScale) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ScaleBitmapCachesByBPP( + /* [retval][out] */ long *pbScale) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_NumBitmapCaches( + /* [in] */ long pnumBitmapCaches) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_NumBitmapCaches( + /* [retval][out] */ long *pnumBitmapCaches) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_CachePersistenceActive( + /* [in] */ long pcachePersistenceActive) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CachePersistenceActive( + /* [retval][out] */ long *pcachePersistenceActive) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PersistCacheDirectory( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_brushSupportLevel( + /* [in] */ long pbrushSupportLevel) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_brushSupportLevel( + /* [retval][out] */ long *pbrushSupportLevel) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_minInputSendInterval( + /* [in] */ long pminInputSendInterval) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_minInputSendInterval( + /* [retval][out] */ long *pminInputSendInterval) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_InputEventsAtOnce( + /* [in] */ long pinputEventsAtOnce) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_InputEventsAtOnce( + /* [retval][out] */ long *pinputEventsAtOnce) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_maxEventCount( + /* [in] */ long pmaxEventCount) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_maxEventCount( + /* [retval][out] */ long *pmaxEventCount) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_keepAliveInterval( + /* [in] */ long pkeepAliveInterval) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_keepAliveInterval( + /* [retval][out] */ long *pkeepAliveInterval) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_shutdownTimeout( + /* [in] */ long pshutdownTimeout) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_shutdownTimeout( + /* [retval][out] */ long *pshutdownTimeout) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_overallConnectionTimeout( + /* [in] */ long poverallConnectionTimeout) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_overallConnectionTimeout( + /* [retval][out] */ long *poverallConnectionTimeout) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_singleConnectionTimeout( + /* [in] */ long psingleConnectionTimeout) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_singleConnectionTimeout( + /* [retval][out] */ long *psingleConnectionTimeout) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyboardType( + /* [in] */ long pkeyboardType) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_KeyboardType( + /* [retval][out] */ long *pkeyboardType) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyboardSubType( + /* [in] */ long pkeyboardSubType) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_KeyboardSubType( + /* [retval][out] */ long *pkeyboardSubType) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyboardFunctionKey( + /* [in] */ long pkeyboardFunctionKey) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_KeyboardFunctionKey( + /* [retval][out] */ long *pkeyboardFunctionKey) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_WinceFixedPalette( + /* [in] */ long pwinceFixedPalette) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_WinceFixedPalette( + /* [retval][out] */ long *pwinceFixedPalette) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectToServerConsole( + /* [in] */ VARIANT_BOOL pConnectToConsole) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectToServerConsole( + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapPersistence( + /* [in] */ long pbitmapPersistence) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapPersistence( + /* [retval][out] */ long *pbitmapPersistence) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MinutesToIdleTimeout( + /* [in] */ long pminutesToIdleTimeout) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MinutesToIdleTimeout( + /* [retval][out] */ long *pminutesToIdleTimeout) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SmartSizing( + /* [in] */ VARIANT_BOOL pfSmartSizing) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SmartSizing( + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RdpdrLocalPrintingDocName( + /* [in] */ BSTR pLocalPrintingDocName) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RdpdrLocalPrintingDocName( + /* [retval][out] */ BSTR *pLocalPrintingDocName) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RdpdrClipCleanTempDirString( + /* [in] */ BSTR clipCleanTempDirString) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RdpdrClipCleanTempDirString( + /* [retval][out] */ BSTR *clipCleanTempDirString) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RdpdrClipPasteInfoString( + /* [in] */ BSTR clipPasteInfoString) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RdpdrClipPasteInfoString( + /* [retval][out] */ BSTR *clipPasteInfoString) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ClearTextPassword( + /* [in] */ BSTR rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DisplayConnectionBar( + /* [in] */ VARIANT_BOOL pDisplayConnectionBar) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DisplayConnectionBar( + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PinConnectionBar( + /* [in] */ VARIANT_BOOL pPinConnectionBar) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_PinConnectionBar( + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_GrabFocusOnConnect( + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_GrabFocusOnConnect( + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_LoadBalanceInfo( + /* [in] */ BSTR pLBInfo) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_LoadBalanceInfo( + /* [retval][out] */ BSTR *pLBInfo) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RedirectDrives( + /* [in] */ VARIANT_BOOL pRedirectDrives) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RedirectDrives( + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RedirectPrinters( + /* [in] */ VARIANT_BOOL pRedirectPrinters) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RedirectPrinters( + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RedirectPorts( + /* [in] */ VARIANT_BOOL pRedirectPorts) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RedirectPorts( + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_RedirectSmartCards( + /* [in] */ VARIANT_BOOL pRedirectSmartCards) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RedirectSmartCards( + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapVirtualCache16BppSize( + /* [in] */ long pBitmapVirtualCache16BppSize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapVirtualCache16BppSize( + /* [retval][out] */ long *pBitmapVirtualCache16BppSize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapVirtualCache24BppSize( + /* [in] */ long pBitmapVirtualCache24BppSize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapVirtualCache24BppSize( + /* [retval][out] */ long *pBitmapVirtualCache24BppSize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PerformanceFlags( + /* [in] */ long pDisableList) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_PerformanceFlags( + /* [retval][out] */ long *pDisableList) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectWithEndpoint( + /* [in] */ VARIANT *rhs) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_NotifyTSPublicKey( + /* [in] */ VARIANT_BOOL pfNotify) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_NotifyTSPublicKey( + /* [retval][out] */ VARIANT_BOOL *pfNotify) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientAdvancedSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientAdvancedSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientAdvancedSettings * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientAdvancedSettings * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pDisableRdpdr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmoothScroll )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long psmoothScroll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmoothScroll )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *psmoothScroll); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pacceleratorPassthrough); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pacceleratorPassthrough); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ShadowBitmap )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pshadowBitmap); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ShadowBitmap )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pshadowBitmap); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_TransportType )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long ptransportType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TransportType )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *ptransportType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SasSequence )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long psasSequence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SasSequence )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *psasSequence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EncryptionEnabled )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pencryptionEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EncryptionEnabled )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pencryptionEnabled); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DedicatedTerminal )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pdedicatedTerminal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DedicatedTerminal )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pdedicatedTerminal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RDPPort )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long prdpPort); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RDPPort )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *prdpPort); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableMouse )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long penableMouse); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableMouse )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *penableMouse); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pdisableCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pdisableCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableWindowsKey )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long penableWindowsKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableWindowsKey )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *penableWindowsKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DoubleClickDetect )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pdoubleClickDetect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DoubleClickDetect )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pdoubleClickDetect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaximizeShell )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pmaximizeShell); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaximizeShell )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pmaximizeShell); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyCtrlEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyCtrlEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyAltEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyAltEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltTab )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyAltTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltTab )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyAltTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyAltShiftTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyAltShiftTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyAltSpace); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyAltSpace); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long photKeyCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *photKeyCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_orderDrawThreshold )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long porderDrawThreshold); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_orderDrawThreshold )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *porderDrawThreshold); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheSize )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbitmapCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheSize )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbitmapCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbitmapVirtualCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbitmapVirtualCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbScale); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbScale); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NumBitmapCaches )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pnumBitmapCaches); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NumBitmapCaches )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pnumBitmapCaches); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CachePersistenceActive )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pcachePersistenceActive); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CachePersistenceActive )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pcachePersistenceActive); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PersistCacheDirectory )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_brushSupportLevel )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbrushSupportLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_brushSupportLevel )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbrushSupportLevel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_minInputSendInterval )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pminInputSendInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_minInputSendInterval )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pminInputSendInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pinputEventsAtOnce); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pinputEventsAtOnce); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_maxEventCount )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pmaxEventCount); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_maxEventCount )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pmaxEventCount); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_keepAliveInterval )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pkeepAliveInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_keepAliveInterval )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pkeepAliveInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_shutdownTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pshutdownTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_shutdownTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pshutdownTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long poverallConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *poverallConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long psingleConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *psingleConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardType )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pkeyboardType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardType )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pkeyboardType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardSubType )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pkeyboardSubType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardSubType )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pkeyboardSubType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pkeyboardFunctionKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pkeyboardFunctionKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WinceFixedPalette )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pwinceFixedPalette); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WinceFixedPalette )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pwinceFixedPalette); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pConnectToConsole); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPersistence )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pbitmapPersistence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPersistence )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pbitmapPersistence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pminutesToIdleTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pminutesToIdleTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmartSizing )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pfSmartSizing); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmartSizing )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR pLocalPrintingDocName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ BSTR *pLocalPrintingDocName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR clipCleanTempDirString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ BSTR *clipCleanTempDirString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR clipPasteInfoString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ BSTR *clipPasteInfoString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pDisplayConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PinConnectionBar )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pPinConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PinConnectionBar )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ BSTR pLBInfo); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ BSTR *pLBInfo); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectDrives )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pRedirectDrives); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectDrives )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPrinters )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pRedirectPrinters); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPrinters )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPorts )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pRedirectPorts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPorts )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectSmartCards )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pRedirectSmartCards); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectSmartCards )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PerformanceFlags )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pDisableList); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PerformanceFlags )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pDisableList); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectWithEndpoint )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT *rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + END_INTERFACE + } IMsRdpClientAdvancedSettingsVtbl; + + interface IMsRdpClientAdvancedSettings + { + CONST_VTBL struct IMsRdpClientAdvancedSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientAdvancedSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientAdvancedSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientAdvancedSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientAdvancedSettings_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientAdvancedSettings_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientAdvancedSettings_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientAdvancedSettings_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientAdvancedSettings_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsRdpClientAdvancedSettings_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + + +#define IMsRdpClientAdvancedSettings_put_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> put_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings_get_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> get_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings_put_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> put_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings_get_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> get_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings_put_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> put_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings_get_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> get_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings_put_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> put_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings_get_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> get_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings_put_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> put_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings_get_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> get_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings_put_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> put_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings_get_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> get_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings_put_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> put_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings_get_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> get_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings_put_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> put_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings_get_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> get_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings_put_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> put_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings_get_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> get_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings_put_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> put_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings_get_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> get_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings_put_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> put_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings_get_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> get_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings_put_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> put_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings_get_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> get_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings_put_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> put_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings_get_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> get_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> put_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> get_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> put_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> get_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> put_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> get_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> put_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> get_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> put_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> get_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> put_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> get_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings_put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings_get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings_put_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> put_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings_get_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> get_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> put_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> get_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings_put_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> put_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings_get_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> get_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings_put_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> put_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings_get_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> get_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings_put_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> put_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings_get_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> get_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings_put_PersistCacheDirectory(This,rhs) \ + ( (This)->lpVtbl -> put_PersistCacheDirectory(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> put_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings_get_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> get_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings_put_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> put_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings_get_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> get_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings_put_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> put_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings_get_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> get_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings_put_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> put_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings_get_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> get_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings_put_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> put_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings_get_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> get_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings_put_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> put_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings_get_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> get_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings_put_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> put_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings_get_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> get_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings_put_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> put_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings_get_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> get_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings_put_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> put_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings_get_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> get_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings_put_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> put_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings_get_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> get_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings_put_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> put_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings_get_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> get_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings_put_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> put_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings_get_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> get_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings_put_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> put_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings_get_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> get_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> put_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> get_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings_put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings_get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings_put_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> put_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings_get_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> get_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings_put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings_get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings_put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings_get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings_put_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> put_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings_get_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> get_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> put_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings_get_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> get_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings_put_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> put_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings_get_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> get_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings_put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings_get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings_put_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> put_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings_get_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> get_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings_put_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> put_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings_get_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> get_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings_put_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> put_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings_get_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> get_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings_put_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> put_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings_get_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> get_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings_put_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> put_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings_get_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> get_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings_put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings_get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings_put_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> put_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings_get_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> get_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings_put_ConnectWithEndpoint(This,rhs) \ + ( (This)->lpVtbl -> put_ConnectWithEndpoint(This,rhs) ) + +#define IMsRdpClientAdvancedSettings_put_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> put_NotifyTSPublicKey(This,pfNotify) ) + +#define IMsRdpClientAdvancedSettings_get_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> get_NotifyTSPublicKey(This,pfNotify) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_RedirectSmartCards_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_RedirectSmartCards_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_BitmapVirtualCache16BppSize_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_BitmapVirtualCache16BppSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_BitmapVirtualCache16BppSize_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_BitmapVirtualCache16BppSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_BitmapVirtualCache24BppSize_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_BitmapVirtualCache24BppSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_BitmapVirtualCache24BppSize_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_BitmapVirtualCache24BppSize_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_PerformanceFlags_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ long pDisableList); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_PerformanceFlags_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_PerformanceFlags_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ long *pDisableList); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_PerformanceFlags_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_ConnectWithEndpoint_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT *rhs); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_ConnectWithEndpoint_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_put_NotifyTSPublicKey_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [in] */ VARIANT_BOOL pfNotify); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_put_NotifyTSPublicKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings_get_NotifyTSPublicKey_Proxy( + IMsRdpClientAdvancedSettings * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + +void __RPC_STUB IMsRdpClientAdvancedSettings_get_NotifyTSPublicKey_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMsRdpClientAdvancedSettings_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings2_INTERFACE_DEFINED__ +#define __IMsRdpClientAdvancedSettings2_INTERFACE_DEFINED__ + +/* interface IMsRdpClientAdvancedSettings2 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientAdvancedSettings2; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("9AC42117-2B76-4320-AA44-0E616AB8437B") + IMsRdpClientAdvancedSettings2 : public IMsRdpClientAdvancedSettings + { + public: + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CanAutoReconnect( + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_EnableAutoReconnect( + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_EnableAutoReconnect( + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MaxReconnectAttempts( + /* [in] */ long pMaxReconnectAttempts) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MaxReconnectAttempts( + /* [retval][out] */ long *pMaxReconnectAttempts) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientAdvancedSettings2Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientAdvancedSettings2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientAdvancedSettings2 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientAdvancedSettings2 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pDisableRdpdr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmoothScroll )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long psmoothScroll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmoothScroll )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *psmoothScroll); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pacceleratorPassthrough); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pacceleratorPassthrough); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ShadowBitmap )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pshadowBitmap); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ShadowBitmap )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pshadowBitmap); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_TransportType )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long ptransportType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TransportType )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *ptransportType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SasSequence )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long psasSequence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SasSequence )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *psasSequence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EncryptionEnabled )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pencryptionEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EncryptionEnabled )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pencryptionEnabled); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DedicatedTerminal )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pdedicatedTerminal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DedicatedTerminal )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pdedicatedTerminal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RDPPort )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long prdpPort); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RDPPort )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *prdpPort); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableMouse )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long penableMouse); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableMouse )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *penableMouse); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pdisableCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pdisableCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableWindowsKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long penableWindowsKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableWindowsKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *penableWindowsKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DoubleClickDetect )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pdoubleClickDetect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DoubleClickDetect )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pdoubleClickDetect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaximizeShell )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pmaximizeShell); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaximizeShell )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pmaximizeShell); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyCtrlEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyCtrlEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyAltEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyAltEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltTab )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyAltTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltTab )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyAltTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyAltShiftTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyAltShiftTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyAltSpace); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyAltSpace); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long photKeyCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *photKeyCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_orderDrawThreshold )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long porderDrawThreshold); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_orderDrawThreshold )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *porderDrawThreshold); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbitmapCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbitmapCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbitmapVirtualCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbitmapVirtualCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbScale); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbScale); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NumBitmapCaches )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pnumBitmapCaches); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NumBitmapCaches )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pnumBitmapCaches); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CachePersistenceActive )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pcachePersistenceActive); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CachePersistenceActive )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pcachePersistenceActive); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PersistCacheDirectory )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_brushSupportLevel )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbrushSupportLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_brushSupportLevel )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbrushSupportLevel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_minInputSendInterval )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pminInputSendInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_minInputSendInterval )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pminInputSendInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pinputEventsAtOnce); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pinputEventsAtOnce); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_maxEventCount )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pmaxEventCount); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_maxEventCount )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pmaxEventCount); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_keepAliveInterval )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pkeepAliveInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_keepAliveInterval )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pkeepAliveInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_shutdownTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pshutdownTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_shutdownTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pshutdownTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long poverallConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *poverallConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long psingleConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *psingleConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardType )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pkeyboardType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardType )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pkeyboardType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardSubType )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pkeyboardSubType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardSubType )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pkeyboardSubType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pkeyboardFunctionKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pkeyboardFunctionKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WinceFixedPalette )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pwinceFixedPalette); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WinceFixedPalette )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pwinceFixedPalette); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pConnectToConsole); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPersistence )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pbitmapPersistence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPersistence )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pbitmapPersistence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pminutesToIdleTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pminutesToIdleTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmartSizing )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfSmartSizing); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmartSizing )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR pLocalPrintingDocName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ BSTR *pLocalPrintingDocName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR clipCleanTempDirString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ BSTR *clipCleanTempDirString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR clipPasteInfoString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ BSTR *clipPasteInfoString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pDisplayConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PinConnectionBar )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pPinConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PinConnectionBar )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ BSTR pLBInfo); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ BSTR *pLBInfo); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectDrives )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pRedirectDrives); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectDrives )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPrinters )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pRedirectPrinters); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPrinters )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPorts )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pRedirectPorts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPorts )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectSmartCards )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pRedirectSmartCards); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectSmartCards )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PerformanceFlags )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pDisableList); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PerformanceFlags )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pDisableList); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectWithEndpoint )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT *rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CanAutoReconnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pMaxReconnectAttempts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pMaxReconnectAttempts); + + END_INTERFACE + } IMsRdpClientAdvancedSettings2Vtbl; + + interface IMsRdpClientAdvancedSettings2 + { + CONST_VTBL struct IMsRdpClientAdvancedSettings2Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientAdvancedSettings2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientAdvancedSettings2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientAdvancedSettings2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientAdvancedSettings2_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientAdvancedSettings2_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientAdvancedSettings2_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientAdvancedSettings2_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientAdvancedSettings2_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings2_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings2_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings2_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings2_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings2_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings2_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsRdpClientAdvancedSettings2_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + + +#define IMsRdpClientAdvancedSettings2_put_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> put_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings2_get_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> get_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings2_put_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> put_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings2_get_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> get_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings2_put_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> put_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings2_get_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> get_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings2_put_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> put_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings2_get_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> get_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings2_put_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> put_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings2_get_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> get_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings2_put_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> put_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings2_get_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> get_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings2_put_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> put_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings2_get_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> get_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings2_put_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> put_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings2_get_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> get_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings2_put_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> put_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings2_get_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> get_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings2_put_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> put_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings2_get_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> get_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings2_put_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> put_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings2_get_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> get_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings2_put_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> put_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings2_get_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> get_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings2_put_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> put_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings2_get_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> get_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> put_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> get_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> put_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> get_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> put_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> get_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> put_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> get_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> put_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> get_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> put_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> get_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings2_put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings2_get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings2_put_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> put_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings2_get_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> get_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> put_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> get_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings2_put_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> put_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings2_get_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> get_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings2_put_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> put_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings2_get_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> get_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings2_put_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> put_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings2_get_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> get_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings2_put_PersistCacheDirectory(This,rhs) \ + ( (This)->lpVtbl -> put_PersistCacheDirectory(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> put_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings2_get_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> get_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings2_put_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> put_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings2_get_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> get_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings2_put_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> put_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings2_get_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> get_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings2_put_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> put_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings2_get_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> get_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings2_put_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> put_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings2_get_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> get_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings2_put_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> put_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings2_get_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> get_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings2_put_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> put_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings2_get_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> get_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings2_put_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> put_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings2_get_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> get_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings2_put_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> put_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings2_get_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> get_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings2_put_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> put_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings2_get_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> get_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings2_put_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> put_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings2_get_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> get_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings2_put_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> put_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings2_get_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> get_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings2_put_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> put_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings2_get_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> get_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> put_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> get_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings2_put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings2_get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings2_put_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> put_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings2_get_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> get_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings2_put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings2_get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings2_put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings2_get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings2_put_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> put_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings2_get_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> get_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings2_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> put_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings2_get_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> get_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings2_put_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> put_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings2_get_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> get_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings2_put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings2_get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings2_put_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> put_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings2_get_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> get_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings2_put_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> put_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings2_get_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> get_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings2_put_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> put_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings2_get_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> get_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings2_put_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> put_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings2_get_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> get_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings2_put_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> put_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings2_get_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> get_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings2_put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings2_get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings2_put_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> put_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings2_get_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> get_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings2_put_ConnectWithEndpoint(This,rhs) \ + ( (This)->lpVtbl -> put_ConnectWithEndpoint(This,rhs) ) + +#define IMsRdpClientAdvancedSettings2_put_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> put_NotifyTSPublicKey(This,pfNotify) ) + +#define IMsRdpClientAdvancedSettings2_get_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> get_NotifyTSPublicKey(This,pfNotify) ) + + +#define IMsRdpClientAdvancedSettings2_get_CanAutoReconnect(This,pfCanAutoReconnect) \ + ( (This)->lpVtbl -> get_CanAutoReconnect(This,pfCanAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings2_put_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> put_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings2_get_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> get_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings2_put_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> put_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + +#define IMsRdpClientAdvancedSettings2_get_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> get_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_get_CanAutoReconnect_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_get_CanAutoReconnect_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_put_EnableAutoReconnect_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_put_EnableAutoReconnect_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_get_EnableAutoReconnect_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_get_EnableAutoReconnect_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_put_MaxReconnectAttempts_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [in] */ long pMaxReconnectAttempts); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_put_MaxReconnectAttempts_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings2_get_MaxReconnectAttempts_Proxy( + IMsRdpClientAdvancedSettings2 * This, + /* [retval][out] */ long *pMaxReconnectAttempts); + + +void __RPC_STUB IMsRdpClientAdvancedSettings2_get_MaxReconnectAttempts_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMsRdpClientAdvancedSettings2_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings3_INTERFACE_DEFINED__ +#define __IMsRdpClientAdvancedSettings3_INTERFACE_DEFINED__ + +/* interface IMsRdpClientAdvancedSettings3 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientAdvancedSettings3; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("19CD856B-C542-4C53-ACEE-F127E3BE1A59") + IMsRdpClientAdvancedSettings3 : public IMsRdpClientAdvancedSettings2 + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectionBarShowMinimizeButton( + /* [in] */ VARIANT_BOOL pfShowMinimize) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectionBarShowMinimizeButton( + /* [retval][out] */ VARIANT_BOOL *pfShowMinimize) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_ConnectionBarShowRestoreButton( + /* [in] */ VARIANT_BOOL pfShowRestore) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectionBarShowRestoreButton( + /* [retval][out] */ VARIANT_BOOL *pfShowRestore) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientAdvancedSettings3Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientAdvancedSettings3 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientAdvancedSettings3 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientAdvancedSettings3 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pDisableRdpdr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmoothScroll )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long psmoothScroll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmoothScroll )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *psmoothScroll); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pacceleratorPassthrough); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pacceleratorPassthrough); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ShadowBitmap )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pshadowBitmap); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ShadowBitmap )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pshadowBitmap); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_TransportType )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long ptransportType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TransportType )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *ptransportType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SasSequence )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long psasSequence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SasSequence )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *psasSequence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EncryptionEnabled )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pencryptionEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EncryptionEnabled )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pencryptionEnabled); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DedicatedTerminal )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pdedicatedTerminal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DedicatedTerminal )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pdedicatedTerminal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RDPPort )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long prdpPort); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RDPPort )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *prdpPort); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableMouse )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long penableMouse); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableMouse )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *penableMouse); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pdisableCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pdisableCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableWindowsKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long penableWindowsKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableWindowsKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *penableWindowsKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DoubleClickDetect )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pdoubleClickDetect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DoubleClickDetect )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pdoubleClickDetect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaximizeShell )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pmaximizeShell); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaximizeShell )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pmaximizeShell); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyCtrlEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyCtrlEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyAltEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyAltEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltTab )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyAltTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltTab )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyAltTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyAltShiftTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyAltShiftTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyAltSpace); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyAltSpace); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long photKeyCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *photKeyCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_orderDrawThreshold )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long porderDrawThreshold); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_orderDrawThreshold )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *porderDrawThreshold); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbitmapCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbitmapCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbitmapVirtualCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbitmapVirtualCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbScale); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbScale); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NumBitmapCaches )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pnumBitmapCaches); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NumBitmapCaches )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pnumBitmapCaches); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CachePersistenceActive )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pcachePersistenceActive); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CachePersistenceActive )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pcachePersistenceActive); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PersistCacheDirectory )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_brushSupportLevel )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbrushSupportLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_brushSupportLevel )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbrushSupportLevel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_minInputSendInterval )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pminInputSendInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_minInputSendInterval )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pminInputSendInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pinputEventsAtOnce); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pinputEventsAtOnce); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_maxEventCount )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pmaxEventCount); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_maxEventCount )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pmaxEventCount); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_keepAliveInterval )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pkeepAliveInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_keepAliveInterval )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pkeepAliveInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_shutdownTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pshutdownTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_shutdownTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pshutdownTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long poverallConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *poverallConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long psingleConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *psingleConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardType )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pkeyboardType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardType )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pkeyboardType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardSubType )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pkeyboardSubType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardSubType )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pkeyboardSubType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pkeyboardFunctionKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pkeyboardFunctionKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WinceFixedPalette )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pwinceFixedPalette); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WinceFixedPalette )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pwinceFixedPalette); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pConnectToConsole); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPersistence )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pbitmapPersistence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPersistence )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pbitmapPersistence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pminutesToIdleTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pminutesToIdleTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmartSizing )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfSmartSizing); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmartSizing )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR pLocalPrintingDocName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ BSTR *pLocalPrintingDocName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR clipCleanTempDirString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ BSTR *clipCleanTempDirString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR clipPasteInfoString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ BSTR *clipPasteInfoString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pDisplayConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PinConnectionBar )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pPinConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PinConnectionBar )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ BSTR pLBInfo); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ BSTR *pLBInfo); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectDrives )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pRedirectDrives); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectDrives )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPrinters )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pRedirectPrinters); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPrinters )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPorts )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pRedirectPorts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPorts )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectSmartCards )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pRedirectSmartCards); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectSmartCards )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PerformanceFlags )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pDisableList); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PerformanceFlags )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pDisableList); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectWithEndpoint )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT *rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CanAutoReconnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ long pMaxReconnectAttempts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ long *pMaxReconnectAttempts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectionBarShowMinimizeButton )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfShowMinimize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectionBarShowMinimizeButton )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowMinimize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectionBarShowRestoreButton )( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfShowRestore); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectionBarShowRestoreButton )( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowRestore); + + END_INTERFACE + } IMsRdpClientAdvancedSettings3Vtbl; + + interface IMsRdpClientAdvancedSettings3 + { + CONST_VTBL struct IMsRdpClientAdvancedSettings3Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientAdvancedSettings3_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientAdvancedSettings3_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientAdvancedSettings3_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientAdvancedSettings3_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientAdvancedSettings3_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientAdvancedSettings3_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientAdvancedSettings3_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientAdvancedSettings3_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings3_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings3_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings3_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings3_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings3_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings3_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsRdpClientAdvancedSettings3_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + + +#define IMsRdpClientAdvancedSettings3_put_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> put_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings3_get_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> get_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings3_put_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> put_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings3_get_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> get_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings3_put_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> put_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings3_get_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> get_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings3_put_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> put_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings3_get_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> get_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings3_put_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> put_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings3_get_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> get_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings3_put_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> put_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings3_get_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> get_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings3_put_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> put_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings3_get_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> get_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings3_put_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> put_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings3_get_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> get_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings3_put_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> put_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings3_get_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> get_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings3_put_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> put_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings3_get_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> get_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings3_put_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> put_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings3_get_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> get_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings3_put_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> put_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings3_get_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> get_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings3_put_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> put_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings3_get_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> get_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> put_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> get_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> put_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> get_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> put_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> get_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> put_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> get_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> put_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> get_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> put_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> get_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings3_put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings3_get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings3_put_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> put_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings3_get_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> get_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> put_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> get_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings3_put_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> put_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings3_get_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> get_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings3_put_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> put_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings3_get_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> get_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings3_put_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> put_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings3_get_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> get_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings3_put_PersistCacheDirectory(This,rhs) \ + ( (This)->lpVtbl -> put_PersistCacheDirectory(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> put_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings3_get_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> get_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings3_put_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> put_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings3_get_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> get_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings3_put_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> put_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings3_get_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> get_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings3_put_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> put_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings3_get_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> get_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings3_put_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> put_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings3_get_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> get_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings3_put_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> put_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings3_get_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> get_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings3_put_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> put_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings3_get_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> get_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings3_put_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> put_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings3_get_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> get_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings3_put_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> put_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings3_get_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> get_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings3_put_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> put_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings3_get_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> get_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings3_put_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> put_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings3_get_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> get_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings3_put_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> put_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings3_get_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> get_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings3_put_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> put_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings3_get_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> get_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> put_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> get_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings3_put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings3_get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings3_put_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> put_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings3_get_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> get_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings3_put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings3_get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings3_put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings3_get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings3_put_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> put_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings3_get_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> get_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings3_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> put_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings3_get_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> get_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings3_put_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> put_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings3_get_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> get_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings3_put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings3_get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings3_put_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> put_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings3_get_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> get_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings3_put_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> put_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings3_get_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> get_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings3_put_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> put_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings3_get_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> get_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings3_put_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> put_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings3_get_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> get_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings3_put_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> put_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings3_get_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> get_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings3_put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings3_get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings3_put_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> put_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings3_get_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> get_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings3_put_ConnectWithEndpoint(This,rhs) \ + ( (This)->lpVtbl -> put_ConnectWithEndpoint(This,rhs) ) + +#define IMsRdpClientAdvancedSettings3_put_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> put_NotifyTSPublicKey(This,pfNotify) ) + +#define IMsRdpClientAdvancedSettings3_get_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> get_NotifyTSPublicKey(This,pfNotify) ) + + +#define IMsRdpClientAdvancedSettings3_get_CanAutoReconnect(This,pfCanAutoReconnect) \ + ( (This)->lpVtbl -> get_CanAutoReconnect(This,pfCanAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings3_put_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> put_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings3_get_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> get_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings3_put_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> put_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + +#define IMsRdpClientAdvancedSettings3_get_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> get_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + + +#define IMsRdpClientAdvancedSettings3_put_ConnectionBarShowMinimizeButton(This,pfShowMinimize) \ + ( (This)->lpVtbl -> put_ConnectionBarShowMinimizeButton(This,pfShowMinimize) ) + +#define IMsRdpClientAdvancedSettings3_get_ConnectionBarShowMinimizeButton(This,pfShowMinimize) \ + ( (This)->lpVtbl -> get_ConnectionBarShowMinimizeButton(This,pfShowMinimize) ) + +#define IMsRdpClientAdvancedSettings3_put_ConnectionBarShowRestoreButton(This,pfShowRestore) \ + ( (This)->lpVtbl -> put_ConnectionBarShowRestoreButton(This,pfShowRestore) ) + +#define IMsRdpClientAdvancedSettings3_get_ConnectionBarShowRestoreButton(This,pfShowRestore) \ + ( (This)->lpVtbl -> get_ConnectionBarShowRestoreButton(This,pfShowRestore) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings3_put_ConnectionBarShowMinimizeButton_Proxy( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfShowMinimize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings3_put_ConnectionBarShowMinimizeButton_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings3_get_ConnectionBarShowMinimizeButton_Proxy( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowMinimize); + + +void __RPC_STUB IMsRdpClientAdvancedSettings3_get_ConnectionBarShowMinimizeButton_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings3_put_ConnectionBarShowRestoreButton_Proxy( + IMsRdpClientAdvancedSettings3 * This, + /* [in] */ VARIANT_BOOL pfShowRestore); + + +void __RPC_STUB IMsRdpClientAdvancedSettings3_put_ConnectionBarShowRestoreButton_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings3_get_ConnectionBarShowRestoreButton_Proxy( + IMsRdpClientAdvancedSettings3 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowRestore); + + +void __RPC_STUB IMsRdpClientAdvancedSettings3_get_ConnectionBarShowRestoreButton_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMsRdpClientAdvancedSettings3_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientAdvancedSettings4_INTERFACE_DEFINED__ +#define __IMsRdpClientAdvancedSettings4_INTERFACE_DEFINED__ + +/* interface IMsRdpClientAdvancedSettings4 */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientAdvancedSettings4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("FBA7F64E-7345-4405-AE50-FA4A763DC0DE") + IMsRdpClientAdvancedSettings4 : public IMsRdpClientAdvancedSettings3 + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_AuthenticationLevel( + /* [in] */ unsigned int puiAuthLevel) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AuthenticationLevel( + /* [retval][out] */ unsigned int *puiAuthLevel) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientAdvancedSettings4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientAdvancedSettings4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientAdvancedSettings4 * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientAdvancedSettings4 * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_Compress )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pcompress); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_Compress )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pcompress); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPeristence )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbitmapPeristence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPeristence )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbitmapPeristence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_allowBackgroundInput )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pallowBackgroundInput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_allowBackgroundInput )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pallowBackgroundInput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyBoardLayoutStr )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PluginDlls )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconFile )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_IconIndex )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pContainerHandledFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ContainerHandledFullScreen )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pContainerHandledFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableRdpdr )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pDisableRdpdr); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableRdpdr )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pDisableRdpdr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmoothScroll )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long psmoothScroll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmoothScroll )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *psmoothScroll); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pacceleratorPassthrough); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AcceleratorPassthrough )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pacceleratorPassthrough); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ShadowBitmap )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pshadowBitmap); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ShadowBitmap )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pshadowBitmap); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_TransportType )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long ptransportType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_TransportType )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *ptransportType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SasSequence )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long psasSequence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SasSequence )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *psasSequence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EncryptionEnabled )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pencryptionEnabled); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EncryptionEnabled )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pencryptionEnabled); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DedicatedTerminal )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pdedicatedTerminal); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DedicatedTerminal )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pdedicatedTerminal); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RDPPort )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long prdpPort); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RDPPort )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *prdpPort); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableMouse )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long penableMouse); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableMouse )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *penableMouse); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pdisableCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisableCtrlAltDel )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pdisableCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableWindowsKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long penableWindowsKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableWindowsKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *penableWindowsKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DoubleClickDetect )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pdoubleClickDetect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DoubleClickDetect )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pdoubleClickDetect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaximizeShell )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pmaximizeShell); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaximizeShell )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pmaximizeShell); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyFullScreen )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyCtrlEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlEsc )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyCtrlEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyAltEsc); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltEsc )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyAltEsc); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltTab )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyAltTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltTab )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyAltTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyAltShiftTab); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltShiftTab )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyAltShiftTab); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyAltSpace); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyAltSpace )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyAltSpace); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long photKeyCtrlAltDel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HotKeyCtrlAltDel )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *photKeyCtrlAltDel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_orderDrawThreshold )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long porderDrawThreshold); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_orderDrawThreshold )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *porderDrawThreshold); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbitmapCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbitmapCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbitmapVirtualCacheSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCacheSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbitmapVirtualCacheSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbScale); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ScaleBitmapCachesByBPP )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbScale); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NumBitmapCaches )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pnumBitmapCaches); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NumBitmapCaches )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pnumBitmapCaches); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CachePersistenceActive )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pcachePersistenceActive); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CachePersistenceActive )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pcachePersistenceActive); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PersistCacheDirectory )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_brushSupportLevel )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbrushSupportLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_brushSupportLevel )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbrushSupportLevel); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_minInputSendInterval )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pminInputSendInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_minInputSendInterval )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pminInputSendInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pinputEventsAtOnce); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_InputEventsAtOnce )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pinputEventsAtOnce); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_maxEventCount )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pmaxEventCount); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_maxEventCount )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pmaxEventCount); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_keepAliveInterval )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pkeepAliveInterval); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_keepAliveInterval )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pkeepAliveInterval); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_shutdownTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pshutdownTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_shutdownTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pshutdownTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long poverallConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_overallConnectionTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *poverallConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long psingleConnectionTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_singleConnectionTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *psingleConnectionTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardType )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pkeyboardType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardType )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pkeyboardType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardSubType )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pkeyboardSubType); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardSubType )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pkeyboardSubType); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pkeyboardFunctionKey); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardFunctionKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pkeyboardFunctionKey); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WinceFixedPalette )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pwinceFixedPalette); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WinceFixedPalette )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pwinceFixedPalette); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pConnectToConsole); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectToServerConsole )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pConnectToConsole); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapPersistence )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pbitmapPersistence); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapPersistence )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pbitmapPersistence); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pminutesToIdleTimeout); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MinutesToIdleTimeout )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pminutesToIdleTimeout); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_SmartSizing )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfSmartSizing); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_SmartSizing )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfSmartSizing); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR pLocalPrintingDocName); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrLocalPrintingDocName )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ BSTR *pLocalPrintingDocName); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR clipCleanTempDirString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipCleanTempDirString )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ BSTR *clipCleanTempDirString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR clipPasteInfoString); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RdpdrClipPasteInfoString )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ BSTR *clipPasteInfoString); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ClearTextPassword )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pDisplayConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_DisplayConnectionBar )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pDisplayConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PinConnectionBar )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pPinConnectionBar); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PinConnectionBar )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pPinConnectionBar); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfGrabFocusOnConnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_GrabFocusOnConnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfGrabFocusOnConnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ BSTR pLBInfo); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LoadBalanceInfo )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ BSTR *pLBInfo); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectDrives )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pRedirectDrives); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectDrives )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectDrives); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPrinters )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pRedirectPrinters); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPrinters )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPrinters); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectPorts )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pRedirectPorts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectPorts )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectPorts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_RedirectSmartCards )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pRedirectSmartCards); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_RedirectSmartCards )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pRedirectSmartCards); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pBitmapVirtualCache16BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache16BppSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pBitmapVirtualCache16BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pBitmapVirtualCache24BppSize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapVirtualCache24BppSize )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pBitmapVirtualCache24BppSize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_PerformanceFlags )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pDisableList); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_PerformanceFlags )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pDisableList); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectWithEndpoint )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT *rhs); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NotifyTSPublicKey )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfNotify); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CanAutoReconnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfCanAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfEnableAutoReconnect); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_EnableAutoReconnect )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfEnableAutoReconnect); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ long pMaxReconnectAttempts); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MaxReconnectAttempts )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ long *pMaxReconnectAttempts); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectionBarShowMinimizeButton )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfShowMinimize); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectionBarShowMinimizeButton )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowMinimize); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_ConnectionBarShowRestoreButton )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ VARIANT_BOOL pfShowRestore); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_ConnectionBarShowRestoreButton )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ VARIANT_BOOL *pfShowRestore); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AuthenticationLevel )( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ unsigned int puiAuthLevel); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AuthenticationLevel )( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ unsigned int *puiAuthLevel); + + END_INTERFACE + } IMsRdpClientAdvancedSettings4Vtbl; + + interface IMsRdpClientAdvancedSettings4 + { + CONST_VTBL struct IMsRdpClientAdvancedSettings4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientAdvancedSettings4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientAdvancedSettings4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientAdvancedSettings4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientAdvancedSettings4_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientAdvancedSettings4_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientAdvancedSettings4_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientAdvancedSettings4_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientAdvancedSettings4_put_Compress(This,pcompress) \ + ( (This)->lpVtbl -> put_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings4_get_Compress(This,pcompress) \ + ( (This)->lpVtbl -> get_Compress(This,pcompress) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> put_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapPeristence(This,pbitmapPeristence) \ + ( (This)->lpVtbl -> get_BitmapPeristence(This,pbitmapPeristence) ) + +#define IMsRdpClientAdvancedSettings4_put_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> put_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings4_get_allowBackgroundInput(This,pallowBackgroundInput) \ + ( (This)->lpVtbl -> get_allowBackgroundInput(This,pallowBackgroundInput) ) + +#define IMsRdpClientAdvancedSettings4_put_KeyBoardLayoutStr(This,rhs) \ + ( (This)->lpVtbl -> put_KeyBoardLayoutStr(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_PluginDlls(This,rhs) \ + ( (This)->lpVtbl -> put_PluginDlls(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_IconFile(This,rhs) \ + ( (This)->lpVtbl -> put_IconFile(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_IconIndex(This,rhs) \ + ( (This)->lpVtbl -> put_IconIndex(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> put_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings4_get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) \ + ( (This)->lpVtbl -> get_ContainerHandledFullScreen(This,pContainerHandledFullScreen) ) + +#define IMsRdpClientAdvancedSettings4_put_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> put_DisableRdpdr(This,pDisableRdpdr) ) + +#define IMsRdpClientAdvancedSettings4_get_DisableRdpdr(This,pDisableRdpdr) \ + ( (This)->lpVtbl -> get_DisableRdpdr(This,pDisableRdpdr) ) + + +#define IMsRdpClientAdvancedSettings4_put_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> put_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings4_get_SmoothScroll(This,psmoothScroll) \ + ( (This)->lpVtbl -> get_SmoothScroll(This,psmoothScroll) ) + +#define IMsRdpClientAdvancedSettings4_put_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> put_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings4_get_AcceleratorPassthrough(This,pacceleratorPassthrough) \ + ( (This)->lpVtbl -> get_AcceleratorPassthrough(This,pacceleratorPassthrough) ) + +#define IMsRdpClientAdvancedSettings4_put_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> put_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings4_get_ShadowBitmap(This,pshadowBitmap) \ + ( (This)->lpVtbl -> get_ShadowBitmap(This,pshadowBitmap) ) + +#define IMsRdpClientAdvancedSettings4_put_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> put_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings4_get_TransportType(This,ptransportType) \ + ( (This)->lpVtbl -> get_TransportType(This,ptransportType) ) + +#define IMsRdpClientAdvancedSettings4_put_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> put_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings4_get_SasSequence(This,psasSequence) \ + ( (This)->lpVtbl -> get_SasSequence(This,psasSequence) ) + +#define IMsRdpClientAdvancedSettings4_put_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> put_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings4_get_EncryptionEnabled(This,pencryptionEnabled) \ + ( (This)->lpVtbl -> get_EncryptionEnabled(This,pencryptionEnabled) ) + +#define IMsRdpClientAdvancedSettings4_put_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> put_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings4_get_DedicatedTerminal(This,pdedicatedTerminal) \ + ( (This)->lpVtbl -> get_DedicatedTerminal(This,pdedicatedTerminal) ) + +#define IMsRdpClientAdvancedSettings4_put_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> put_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings4_get_RDPPort(This,prdpPort) \ + ( (This)->lpVtbl -> get_RDPPort(This,prdpPort) ) + +#define IMsRdpClientAdvancedSettings4_put_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> put_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings4_get_EnableMouse(This,penableMouse) \ + ( (This)->lpVtbl -> get_EnableMouse(This,penableMouse) ) + +#define IMsRdpClientAdvancedSettings4_put_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> put_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings4_get_DisableCtrlAltDel(This,pdisableCtrlAltDel) \ + ( (This)->lpVtbl -> get_DisableCtrlAltDel(This,pdisableCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings4_put_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> put_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings4_get_EnableWindowsKey(This,penableWindowsKey) \ + ( (This)->lpVtbl -> get_EnableWindowsKey(This,penableWindowsKey) ) + +#define IMsRdpClientAdvancedSettings4_put_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> put_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings4_get_DoubleClickDetect(This,pdoubleClickDetect) \ + ( (This)->lpVtbl -> get_DoubleClickDetect(This,pdoubleClickDetect) ) + +#define IMsRdpClientAdvancedSettings4_put_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> put_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings4_get_MaximizeShell(This,pmaximizeShell) \ + ( (This)->lpVtbl -> get_MaximizeShell(This,pmaximizeShell) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> put_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyFullScreen(This,photKeyFullScreen) \ + ( (This)->lpVtbl -> get_HotKeyFullScreen(This,photKeyFullScreen) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> put_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyCtrlEsc(This,photKeyCtrlEsc) \ + ( (This)->lpVtbl -> get_HotKeyCtrlEsc(This,photKeyCtrlEsc) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> put_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyAltEsc(This,photKeyAltEsc) \ + ( (This)->lpVtbl -> get_HotKeyAltEsc(This,photKeyAltEsc) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> put_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyAltTab(This,photKeyAltTab) \ + ( (This)->lpVtbl -> get_HotKeyAltTab(This,photKeyAltTab) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> put_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyAltShiftTab(This,photKeyAltShiftTab) \ + ( (This)->lpVtbl -> get_HotKeyAltShiftTab(This,photKeyAltShiftTab) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> put_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyAltSpace(This,photKeyAltSpace) \ + ( (This)->lpVtbl -> get_HotKeyAltSpace(This,photKeyAltSpace) ) + +#define IMsRdpClientAdvancedSettings4_put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> put_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings4_get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) \ + ( (This)->lpVtbl -> get_HotKeyCtrlAltDel(This,photKeyCtrlAltDel) ) + +#define IMsRdpClientAdvancedSettings4_put_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> put_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings4_get_orderDrawThreshold(This,porderDrawThreshold) \ + ( (This)->lpVtbl -> get_orderDrawThreshold(This,porderDrawThreshold) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> put_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapCacheSize(This,pbitmapCacheSize) \ + ( (This)->lpVtbl -> get_BitmapCacheSize(This,pbitmapCacheSize) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCacheSize(This,pbitmapVirtualCacheSize) ) + +#define IMsRdpClientAdvancedSettings4_put_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> put_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings4_get_ScaleBitmapCachesByBPP(This,pbScale) \ + ( (This)->lpVtbl -> get_ScaleBitmapCachesByBPP(This,pbScale) ) + +#define IMsRdpClientAdvancedSettings4_put_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> put_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings4_get_NumBitmapCaches(This,pnumBitmapCaches) \ + ( (This)->lpVtbl -> get_NumBitmapCaches(This,pnumBitmapCaches) ) + +#define IMsRdpClientAdvancedSettings4_put_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> put_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings4_get_CachePersistenceActive(This,pcachePersistenceActive) \ + ( (This)->lpVtbl -> get_CachePersistenceActive(This,pcachePersistenceActive) ) + +#define IMsRdpClientAdvancedSettings4_put_PersistCacheDirectory(This,rhs) \ + ( (This)->lpVtbl -> put_PersistCacheDirectory(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> put_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings4_get_brushSupportLevel(This,pbrushSupportLevel) \ + ( (This)->lpVtbl -> get_brushSupportLevel(This,pbrushSupportLevel) ) + +#define IMsRdpClientAdvancedSettings4_put_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> put_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings4_get_minInputSendInterval(This,pminInputSendInterval) \ + ( (This)->lpVtbl -> get_minInputSendInterval(This,pminInputSendInterval) ) + +#define IMsRdpClientAdvancedSettings4_put_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> put_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings4_get_InputEventsAtOnce(This,pinputEventsAtOnce) \ + ( (This)->lpVtbl -> get_InputEventsAtOnce(This,pinputEventsAtOnce) ) + +#define IMsRdpClientAdvancedSettings4_put_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> put_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings4_get_maxEventCount(This,pmaxEventCount) \ + ( (This)->lpVtbl -> get_maxEventCount(This,pmaxEventCount) ) + +#define IMsRdpClientAdvancedSettings4_put_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> put_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings4_get_keepAliveInterval(This,pkeepAliveInterval) \ + ( (This)->lpVtbl -> get_keepAliveInterval(This,pkeepAliveInterval) ) + +#define IMsRdpClientAdvancedSettings4_put_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> put_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings4_get_shutdownTimeout(This,pshutdownTimeout) \ + ( (This)->lpVtbl -> get_shutdownTimeout(This,pshutdownTimeout) ) + +#define IMsRdpClientAdvancedSettings4_put_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> put_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings4_get_overallConnectionTimeout(This,poverallConnectionTimeout) \ + ( (This)->lpVtbl -> get_overallConnectionTimeout(This,poverallConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings4_put_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> put_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings4_get_singleConnectionTimeout(This,psingleConnectionTimeout) \ + ( (This)->lpVtbl -> get_singleConnectionTimeout(This,psingleConnectionTimeout) ) + +#define IMsRdpClientAdvancedSettings4_put_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> put_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings4_get_KeyboardType(This,pkeyboardType) \ + ( (This)->lpVtbl -> get_KeyboardType(This,pkeyboardType) ) + +#define IMsRdpClientAdvancedSettings4_put_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> put_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings4_get_KeyboardSubType(This,pkeyboardSubType) \ + ( (This)->lpVtbl -> get_KeyboardSubType(This,pkeyboardSubType) ) + +#define IMsRdpClientAdvancedSettings4_put_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> put_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings4_get_KeyboardFunctionKey(This,pkeyboardFunctionKey) \ + ( (This)->lpVtbl -> get_KeyboardFunctionKey(This,pkeyboardFunctionKey) ) + +#define IMsRdpClientAdvancedSettings4_put_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> put_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings4_get_WinceFixedPalette(This,pwinceFixedPalette) \ + ( (This)->lpVtbl -> get_WinceFixedPalette(This,pwinceFixedPalette) ) + +#define IMsRdpClientAdvancedSettings4_put_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> put_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings4_get_ConnectToServerConsole(This,pConnectToConsole) \ + ( (This)->lpVtbl -> get_ConnectToServerConsole(This,pConnectToConsole) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> put_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapPersistence(This,pbitmapPersistence) \ + ( (This)->lpVtbl -> get_BitmapPersistence(This,pbitmapPersistence) ) + +#define IMsRdpClientAdvancedSettings4_put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> put_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings4_get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) \ + ( (This)->lpVtbl -> get_MinutesToIdleTimeout(This,pminutesToIdleTimeout) ) + +#define IMsRdpClientAdvancedSettings4_put_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> put_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings4_get_SmartSizing(This,pfSmartSizing) \ + ( (This)->lpVtbl -> get_SmartSizing(This,pfSmartSizing) ) + +#define IMsRdpClientAdvancedSettings4_put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> put_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings4_get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) \ + ( (This)->lpVtbl -> get_RdpdrLocalPrintingDocName(This,pLocalPrintingDocName) ) + +#define IMsRdpClientAdvancedSettings4_put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> put_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings4_get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) \ + ( (This)->lpVtbl -> get_RdpdrClipCleanTempDirString(This,clipCleanTempDirString) ) + +#define IMsRdpClientAdvancedSettings4_put_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> put_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings4_get_RdpdrClipPasteInfoString(This,clipPasteInfoString) \ + ( (This)->lpVtbl -> get_RdpdrClipPasteInfoString(This,clipPasteInfoString) ) + +#define IMsRdpClientAdvancedSettings4_put_ClearTextPassword(This,rhs) \ + ( (This)->lpVtbl -> put_ClearTextPassword(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> put_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings4_get_DisplayConnectionBar(This,pDisplayConnectionBar) \ + ( (This)->lpVtbl -> get_DisplayConnectionBar(This,pDisplayConnectionBar) ) + +#define IMsRdpClientAdvancedSettings4_put_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> put_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings4_get_PinConnectionBar(This,pPinConnectionBar) \ + ( (This)->lpVtbl -> get_PinConnectionBar(This,pPinConnectionBar) ) + +#define IMsRdpClientAdvancedSettings4_put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> put_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings4_get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) \ + ( (This)->lpVtbl -> get_GrabFocusOnConnect(This,pfGrabFocusOnConnect) ) + +#define IMsRdpClientAdvancedSettings4_put_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> put_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings4_get_LoadBalanceInfo(This,pLBInfo) \ + ( (This)->lpVtbl -> get_LoadBalanceInfo(This,pLBInfo) ) + +#define IMsRdpClientAdvancedSettings4_put_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> put_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings4_get_RedirectDrives(This,pRedirectDrives) \ + ( (This)->lpVtbl -> get_RedirectDrives(This,pRedirectDrives) ) + +#define IMsRdpClientAdvancedSettings4_put_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> put_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings4_get_RedirectPrinters(This,pRedirectPrinters) \ + ( (This)->lpVtbl -> get_RedirectPrinters(This,pRedirectPrinters) ) + +#define IMsRdpClientAdvancedSettings4_put_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> put_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings4_get_RedirectPorts(This,pRedirectPorts) \ + ( (This)->lpVtbl -> get_RedirectPorts(This,pRedirectPorts) ) + +#define IMsRdpClientAdvancedSettings4_put_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> put_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings4_get_RedirectSmartCards(This,pRedirectSmartCards) \ + ( (This)->lpVtbl -> get_RedirectSmartCards(This,pRedirectSmartCards) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache16BppSize(This,pBitmapVirtualCache16BppSize) ) + +#define IMsRdpClientAdvancedSettings4_put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> put_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings4_get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) \ + ( (This)->lpVtbl -> get_BitmapVirtualCache24BppSize(This,pBitmapVirtualCache24BppSize) ) + +#define IMsRdpClientAdvancedSettings4_put_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> put_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings4_get_PerformanceFlags(This,pDisableList) \ + ( (This)->lpVtbl -> get_PerformanceFlags(This,pDisableList) ) + +#define IMsRdpClientAdvancedSettings4_put_ConnectWithEndpoint(This,rhs) \ + ( (This)->lpVtbl -> put_ConnectWithEndpoint(This,rhs) ) + +#define IMsRdpClientAdvancedSettings4_put_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> put_NotifyTSPublicKey(This,pfNotify) ) + +#define IMsRdpClientAdvancedSettings4_get_NotifyTSPublicKey(This,pfNotify) \ + ( (This)->lpVtbl -> get_NotifyTSPublicKey(This,pfNotify) ) + + +#define IMsRdpClientAdvancedSettings4_get_CanAutoReconnect(This,pfCanAutoReconnect) \ + ( (This)->lpVtbl -> get_CanAutoReconnect(This,pfCanAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings4_put_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> put_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings4_get_EnableAutoReconnect(This,pfEnableAutoReconnect) \ + ( (This)->lpVtbl -> get_EnableAutoReconnect(This,pfEnableAutoReconnect) ) + +#define IMsRdpClientAdvancedSettings4_put_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> put_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + +#define IMsRdpClientAdvancedSettings4_get_MaxReconnectAttempts(This,pMaxReconnectAttempts) \ + ( (This)->lpVtbl -> get_MaxReconnectAttempts(This,pMaxReconnectAttempts) ) + + +#define IMsRdpClientAdvancedSettings4_put_ConnectionBarShowMinimizeButton(This,pfShowMinimize) \ + ( (This)->lpVtbl -> put_ConnectionBarShowMinimizeButton(This,pfShowMinimize) ) + +#define IMsRdpClientAdvancedSettings4_get_ConnectionBarShowMinimizeButton(This,pfShowMinimize) \ + ( (This)->lpVtbl -> get_ConnectionBarShowMinimizeButton(This,pfShowMinimize) ) + +#define IMsRdpClientAdvancedSettings4_put_ConnectionBarShowRestoreButton(This,pfShowRestore) \ + ( (This)->lpVtbl -> put_ConnectionBarShowRestoreButton(This,pfShowRestore) ) + +#define IMsRdpClientAdvancedSettings4_get_ConnectionBarShowRestoreButton(This,pfShowRestore) \ + ( (This)->lpVtbl -> get_ConnectionBarShowRestoreButton(This,pfShowRestore) ) + + +#define IMsRdpClientAdvancedSettings4_put_AuthenticationLevel(This,puiAuthLevel) \ + ( (This)->lpVtbl -> put_AuthenticationLevel(This,puiAuthLevel) ) + +#define IMsRdpClientAdvancedSettings4_get_AuthenticationLevel(This,puiAuthLevel) \ + ( (This)->lpVtbl -> get_AuthenticationLevel(This,puiAuthLevel) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [propput][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings4_put_AuthenticationLevel_Proxy( + IMsRdpClientAdvancedSettings4 * This, + /* [in] */ unsigned int puiAuthLevel); + + +void __RPC_STUB IMsRdpClientAdvancedSettings4_put_AuthenticationLevel_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [propget][id] */ HRESULT STDMETHODCALLTYPE IMsRdpClientAdvancedSettings4_get_AuthenticationLevel_Proxy( + IMsRdpClientAdvancedSettings4 * This, + /* [retval][out] */ unsigned int *puiAuthLevel); + + +void __RPC_STUB IMsRdpClientAdvancedSettings4_get_AuthenticationLevel_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IMsRdpClientAdvancedSettings4_INTERFACE_DEFINED__ */ + + +#ifndef __IMsTscSecuredSettings_INTERFACE_DEFINED__ +#define __IMsTscSecuredSettings_INTERFACE_DEFINED__ + +/* interface IMsTscSecuredSettings */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsTscSecuredSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("C9D65442-A0F9-45B2-8F73-D61D2DB8CBB6") + IMsTscSecuredSettings : public IDispatch + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_StartProgram( + /* [in] */ BSTR pStartProgram) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_StartProgram( + /* [retval][out] */ BSTR *pStartProgram) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_WorkDir( + /* [in] */ BSTR pWorkDir) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_WorkDir( + /* [retval][out] */ BSTR *pWorkDir) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_FullScreen( + /* [in] */ long pfFullScreen) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_FullScreen( + /* [retval][out] */ long *pfFullScreen) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscSecuredSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscSecuredSettings * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscSecuredSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscSecuredSettings * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscSecuredSettings * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscSecuredSettings * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscSecuredSettings * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscSecuredSettings * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartProgram )( + IMsTscSecuredSettings * This, + /* [in] */ BSTR pStartProgram); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartProgram )( + IMsTscSecuredSettings * This, + /* [retval][out] */ BSTR *pStartProgram); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WorkDir )( + IMsTscSecuredSettings * This, + /* [in] */ BSTR pWorkDir); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WorkDir )( + IMsTscSecuredSettings * This, + /* [retval][out] */ BSTR *pWorkDir); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsTscSecuredSettings * This, + /* [in] */ long pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsTscSecuredSettings * This, + /* [retval][out] */ long *pfFullScreen); + + END_INTERFACE + } IMsTscSecuredSettingsVtbl; + + interface IMsTscSecuredSettings + { + CONST_VTBL struct IMsTscSecuredSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscSecuredSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscSecuredSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscSecuredSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscSecuredSettings_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscSecuredSettings_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscSecuredSettings_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscSecuredSettings_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsTscSecuredSettings_put_StartProgram(This,pStartProgram) \ + ( (This)->lpVtbl -> put_StartProgram(This,pStartProgram) ) + +#define IMsTscSecuredSettings_get_StartProgram(This,pStartProgram) \ + ( (This)->lpVtbl -> get_StartProgram(This,pStartProgram) ) + +#define IMsTscSecuredSettings_put_WorkDir(This,pWorkDir) \ + ( (This)->lpVtbl -> put_WorkDir(This,pWorkDir) ) + +#define IMsTscSecuredSettings_get_WorkDir(This,pWorkDir) \ + ( (This)->lpVtbl -> get_WorkDir(This,pWorkDir) ) + +#define IMsTscSecuredSettings_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsTscSecuredSettings_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscSecuredSettings_INTERFACE_DEFINED__ */ + + +#ifndef __IMsRdpClientSecuredSettings_INTERFACE_DEFINED__ +#define __IMsRdpClientSecuredSettings_INTERFACE_DEFINED__ + +/* interface IMsRdpClientSecuredSettings */ +/* [object][oleautomation][dual][uuid] */ + + +EXTERN_C const IID IID_IMsRdpClientSecuredSettings; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("605BEFCF-39C1-45CC-A811-068FB7BE346D") + IMsRdpClientSecuredSettings : public IMsTscSecuredSettings + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_KeyboardHookMode( + /* [in] */ long pkeyboardHookMode) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_KeyboardHookMode( + /* [retval][out] */ long *pkeyboardHookMode) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_AudioRedirectionMode( + /* [in] */ long pAudioRedirectionMode) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AudioRedirectionMode( + /* [retval][out] */ long *pAudioRedirectionMode) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsRdpClientSecuredSettingsVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsRdpClientSecuredSettings * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsRdpClientSecuredSettings * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsRdpClientSecuredSettings * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsRdpClientSecuredSettings * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsRdpClientSecuredSettings * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsRdpClientSecuredSettings * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsRdpClientSecuredSettings * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_StartProgram )( + IMsRdpClientSecuredSettings * This, + /* [in] */ BSTR pStartProgram); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_StartProgram )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ BSTR *pStartProgram); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_WorkDir )( + IMsRdpClientSecuredSettings * This, + /* [in] */ BSTR pWorkDir); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_WorkDir )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ BSTR *pWorkDir); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_FullScreen )( + IMsRdpClientSecuredSettings * This, + /* [in] */ long pfFullScreen); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_FullScreen )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ long *pfFullScreen); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_KeyboardHookMode )( + IMsRdpClientSecuredSettings * This, + /* [in] */ long pkeyboardHookMode); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_KeyboardHookMode )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ long *pkeyboardHookMode); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_AudioRedirectionMode )( + IMsRdpClientSecuredSettings * This, + /* [in] */ long pAudioRedirectionMode); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_AudioRedirectionMode )( + IMsRdpClientSecuredSettings * This, + /* [retval][out] */ long *pAudioRedirectionMode); + + END_INTERFACE + } IMsRdpClientSecuredSettingsVtbl; + + interface IMsRdpClientSecuredSettings + { + CONST_VTBL struct IMsRdpClientSecuredSettingsVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsRdpClientSecuredSettings_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsRdpClientSecuredSettings_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsRdpClientSecuredSettings_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsRdpClientSecuredSettings_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsRdpClientSecuredSettings_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsRdpClientSecuredSettings_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsRdpClientSecuredSettings_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsRdpClientSecuredSettings_put_StartProgram(This,pStartProgram) \ + ( (This)->lpVtbl -> put_StartProgram(This,pStartProgram) ) + +#define IMsRdpClientSecuredSettings_get_StartProgram(This,pStartProgram) \ + ( (This)->lpVtbl -> get_StartProgram(This,pStartProgram) ) + +#define IMsRdpClientSecuredSettings_put_WorkDir(This,pWorkDir) \ + ( (This)->lpVtbl -> put_WorkDir(This,pWorkDir) ) + +#define IMsRdpClientSecuredSettings_get_WorkDir(This,pWorkDir) \ + ( (This)->lpVtbl -> get_WorkDir(This,pWorkDir) ) + +#define IMsRdpClientSecuredSettings_put_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> put_FullScreen(This,pfFullScreen) ) + +#define IMsRdpClientSecuredSettings_get_FullScreen(This,pfFullScreen) \ + ( (This)->lpVtbl -> get_FullScreen(This,pfFullScreen) ) + + +#define IMsRdpClientSecuredSettings_put_KeyboardHookMode(This,pkeyboardHookMode) \ + ( (This)->lpVtbl -> put_KeyboardHookMode(This,pkeyboardHookMode) ) + +#define IMsRdpClientSecuredSettings_get_KeyboardHookMode(This,pkeyboardHookMode) \ + ( (This)->lpVtbl -> get_KeyboardHookMode(This,pkeyboardHookMode) ) + +#define IMsRdpClientSecuredSettings_put_AudioRedirectionMode(This,pAudioRedirectionMode) \ + ( (This)->lpVtbl -> put_AudioRedirectionMode(This,pAudioRedirectionMode) ) + +#define IMsRdpClientSecuredSettings_get_AudioRedirectionMode(This,pAudioRedirectionMode) \ + ( (This)->lpVtbl -> get_AudioRedirectionMode(This,pAudioRedirectionMode) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsRdpClientSecuredSettings_INTERFACE_DEFINED__ */ + + +#ifndef __IMsTscDebug_INTERFACE_DEFINED__ +#define __IMsTscDebug_INTERFACE_DEFINED__ + +/* interface IMsTscDebug */ +/* [object][oleautomation][dual][hidden][uuid] */ + + +EXTERN_C const IID IID_IMsTscDebug; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("209D0EB9-6254-47B1-9033-A98DAE55BB27") + IMsTscDebug : public IDispatch + { + public: + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HatchBitmapPDU( + /* [in] */ long phatchBitmapPDU) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HatchBitmapPDU( + /* [retval][out] */ long *phatchBitmapPDU) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HatchSSBOrder( + /* [in] */ long phatchSSBOrder) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HatchSSBOrder( + /* [retval][out] */ long *phatchSSBOrder) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HatchMembltOrder( + /* [in] */ long phatchMembltOrder) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HatchMembltOrder( + /* [retval][out] */ long *phatchMembltOrder) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_HatchIndexPDU( + /* [in] */ long phatchIndexPDU) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_HatchIndexPDU( + /* [retval][out] */ long *phatchIndexPDU) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_LabelMemblt( + /* [in] */ long plabelMemblt) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_LabelMemblt( + /* [retval][out] */ long *plabelMemblt) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BitmapCacheMonitor( + /* [in] */ long pbitmapCacheMonitor) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitmapCacheMonitor( + /* [retval][out] */ long *pbitmapCacheMonitor) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MallocFailuresPercent( + /* [in] */ long pmallocFailuresPercent) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MallocFailuresPercent( + /* [retval][out] */ long *pmallocFailuresPercent) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MallocHugeFailuresPercent( + /* [in] */ long pmallocHugeFailuresPercent) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MallocHugeFailuresPercent( + /* [retval][out] */ long *pmallocHugeFailuresPercent) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_NetThroughput( + /* [in] */ long NetThroughput) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_NetThroughput( + /* [retval][out] */ long *NetThroughput) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_CLXCmdLine( + /* [in] */ BSTR pCLXCmdLine) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CLXCmdLine( + /* [retval][out] */ BSTR *pCLXCmdLine) = 0; + + virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_CLXDll( + /* [in] */ BSTR pCLXDll) = 0; + + virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CLXDll( + /* [retval][out] */ BSTR *pCLXDll) = 0; + + }; + +#else /* C style interface */ + + typedef struct IMsTscDebugVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IMsTscDebug * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ + __RPC__deref_out void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IMsTscDebug * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IMsTscDebug * This); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfoCount )( + IMsTscDebug * This, + /* [out] */ UINT *pctinfo); + + HRESULT ( STDMETHODCALLTYPE *GetTypeInfo )( + IMsTscDebug * This, + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ ITypeInfo **ppTInfo); + + HRESULT ( STDMETHODCALLTYPE *GetIDsOfNames )( + IMsTscDebug * This, + /* [in] */ REFIID riid, + /* [size_is][in] */ LPOLESTR *rgszNames, + /* [range][in] */ UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ DISPID *rgDispId); + + /* [local] */ HRESULT ( STDMETHODCALLTYPE *Invoke )( + IMsTscDebug * This, + /* [in] */ DISPID dispIdMember, + /* [in] */ REFIID riid, + /* [in] */ LCID lcid, + /* [in] */ WORD wFlags, + /* [out][in] */ DISPPARAMS *pDispParams, + /* [out] */ VARIANT *pVarResult, + /* [out] */ EXCEPINFO *pExcepInfo, + /* [out] */ UINT *puArgErr); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HatchBitmapPDU )( + IMsTscDebug * This, + /* [in] */ long phatchBitmapPDU); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HatchBitmapPDU )( + IMsTscDebug * This, + /* [retval][out] */ long *phatchBitmapPDU); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HatchSSBOrder )( + IMsTscDebug * This, + /* [in] */ long phatchSSBOrder); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HatchSSBOrder )( + IMsTscDebug * This, + /* [retval][out] */ long *phatchSSBOrder); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HatchMembltOrder )( + IMsTscDebug * This, + /* [in] */ long phatchMembltOrder); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HatchMembltOrder )( + IMsTscDebug * This, + /* [retval][out] */ long *phatchMembltOrder); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_HatchIndexPDU )( + IMsTscDebug * This, + /* [in] */ long phatchIndexPDU); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_HatchIndexPDU )( + IMsTscDebug * This, + /* [retval][out] */ long *phatchIndexPDU); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_LabelMemblt )( + IMsTscDebug * This, + /* [in] */ long plabelMemblt); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_LabelMemblt )( + IMsTscDebug * This, + /* [retval][out] */ long *plabelMemblt); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_BitmapCacheMonitor )( + IMsTscDebug * This, + /* [in] */ long pbitmapCacheMonitor); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_BitmapCacheMonitor )( + IMsTscDebug * This, + /* [retval][out] */ long *pbitmapCacheMonitor); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MallocFailuresPercent )( + IMsTscDebug * This, + /* [in] */ long pmallocFailuresPercent); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MallocFailuresPercent )( + IMsTscDebug * This, + /* [retval][out] */ long *pmallocFailuresPercent); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_MallocHugeFailuresPercent )( + IMsTscDebug * This, + /* [in] */ long pmallocHugeFailuresPercent); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_MallocHugeFailuresPercent )( + IMsTscDebug * This, + /* [retval][out] */ long *pmallocHugeFailuresPercent); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_NetThroughput )( + IMsTscDebug * This, + /* [in] */ long NetThroughput); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_NetThroughput )( + IMsTscDebug * This, + /* [retval][out] */ long *NetThroughput); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CLXCmdLine )( + IMsTscDebug * This, + /* [in] */ BSTR pCLXCmdLine); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CLXCmdLine )( + IMsTscDebug * This, + /* [retval][out] */ BSTR *pCLXCmdLine); + + /* [propput][id] */ HRESULT ( STDMETHODCALLTYPE *put_CLXDll )( + IMsTscDebug * This, + /* [in] */ BSTR pCLXDll); + + /* [propget][id] */ HRESULT ( STDMETHODCALLTYPE *get_CLXDll )( + IMsTscDebug * This, + /* [retval][out] */ BSTR *pCLXDll); + + END_INTERFACE + } IMsTscDebugVtbl; + + interface IMsTscDebug + { + CONST_VTBL struct IMsTscDebugVtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IMsTscDebug_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IMsTscDebug_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IMsTscDebug_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IMsTscDebug_GetTypeInfoCount(This,pctinfo) \ + ( (This)->lpVtbl -> GetTypeInfoCount(This,pctinfo) ) + +#define IMsTscDebug_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \ + ( (This)->lpVtbl -> GetTypeInfo(This,iTInfo,lcid,ppTInfo) ) + +#define IMsTscDebug_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) \ + ( (This)->lpVtbl -> GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId) ) + +#define IMsTscDebug_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \ + ( (This)->lpVtbl -> Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) ) + + +#define IMsTscDebug_put_HatchBitmapPDU(This,phatchBitmapPDU) \ + ( (This)->lpVtbl -> put_HatchBitmapPDU(This,phatchBitmapPDU) ) + +#define IMsTscDebug_get_HatchBitmapPDU(This,phatchBitmapPDU) \ + ( (This)->lpVtbl -> get_HatchBitmapPDU(This,phatchBitmapPDU) ) + +#define IMsTscDebug_put_HatchSSBOrder(This,phatchSSBOrder) \ + ( (This)->lpVtbl -> put_HatchSSBOrder(This,phatchSSBOrder) ) + +#define IMsTscDebug_get_HatchSSBOrder(This,phatchSSBOrder) \ + ( (This)->lpVtbl -> get_HatchSSBOrder(This,phatchSSBOrder) ) + +#define IMsTscDebug_put_HatchMembltOrder(This,phatchMembltOrder) \ + ( (This)->lpVtbl -> put_HatchMembltOrder(This,phatchMembltOrder) ) + +#define IMsTscDebug_get_HatchMembltOrder(This,phatchMembltOrder) \ + ( (This)->lpVtbl -> get_HatchMembltOrder(This,phatchMembltOrder) ) + +#define IMsTscDebug_put_HatchIndexPDU(This,phatchIndexPDU) \ + ( (This)->lpVtbl -> put_HatchIndexPDU(This,phatchIndexPDU) ) + +#define IMsTscDebug_get_HatchIndexPDU(This,phatchIndexPDU) \ + ( (This)->lpVtbl -> get_HatchIndexPDU(This,phatchIndexPDU) ) + +#define IMsTscDebug_put_LabelMemblt(This,plabelMemblt) \ + ( (This)->lpVtbl -> put_LabelMemblt(This,plabelMemblt) ) + +#define IMsTscDebug_get_LabelMemblt(This,plabelMemblt) \ + ( (This)->lpVtbl -> get_LabelMemblt(This,plabelMemblt) ) + +#define IMsTscDebug_put_BitmapCacheMonitor(This,pbitmapCacheMonitor) \ + ( (This)->lpVtbl -> put_BitmapCacheMonitor(This,pbitmapCacheMonitor) ) + +#define IMsTscDebug_get_BitmapCacheMonitor(This,pbitmapCacheMonitor) \ + ( (This)->lpVtbl -> get_BitmapCacheMonitor(This,pbitmapCacheMonitor) ) + +#define IMsTscDebug_put_MallocFailuresPercent(This,pmallocFailuresPercent) \ + ( (This)->lpVtbl -> put_MallocFailuresPercent(This,pmallocFailuresPercent) ) + +#define IMsTscDebug_get_MallocFailuresPercent(This,pmallocFailuresPercent) \ + ( (This)->lpVtbl -> get_MallocFailuresPercent(This,pmallocFailuresPercent) ) + +#define IMsTscDebug_put_MallocHugeFailuresPercent(This,pmallocHugeFailuresPercent) \ + ( (This)->lpVtbl -> put_MallocHugeFailuresPercent(This,pmallocHugeFailuresPercent) ) + +#define IMsTscDebug_get_MallocHugeFailuresPercent(This,pmallocHugeFailuresPercent) \ + ( (This)->lpVtbl -> get_MallocHugeFailuresPercent(This,pmallocHugeFailuresPercent) ) + +#define IMsTscDebug_put_NetThroughput(This,NetThroughput) \ + ( (This)->lpVtbl -> put_NetThroughput(This,NetThroughput) ) + +#define IMsTscDebug_get_NetThroughput(This,NetThroughput) \ + ( (This)->lpVtbl -> get_NetThroughput(This,NetThroughput) ) + +#define IMsTscDebug_put_CLXCmdLine(This,pCLXCmdLine) \ + ( (This)->lpVtbl -> put_CLXCmdLine(This,pCLXCmdLine) ) + +#define IMsTscDebug_get_CLXCmdLine(This,pCLXCmdLine) \ + ( (This)->lpVtbl -> get_CLXCmdLine(This,pCLXCmdLine) ) + +#define IMsTscDebug_put_CLXDll(This,pCLXDll) \ + ( (This)->lpVtbl -> put_CLXDll(This,pCLXDll) ) + +#define IMsTscDebug_get_CLXDll(This,pCLXDll) \ + ( (This)->lpVtbl -> get_CLXDll(This,pCLXDll) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __IMsTscDebug_INTERFACE_DEFINED__ */ + + +EXTERN_C const CLSID CLSID_MsTscAx; + +#ifdef __cplusplus + +class DECLSPEC_UUID("1FB464C8-09BB-4017-A2F5-EB742F04392F") +MsTscAx; +#endif + +EXTERN_C const CLSID CLSID_MsRdpClient; + +#ifdef __cplusplus + +class DECLSPEC_UUID("791FA017-2DE3-492E-ACC5-53C67A2B94D0") +MsRdpClient; +#endif + +EXTERN_C const CLSID CLSID_MsRdpClient2; + +#ifdef __cplusplus + +class DECLSPEC_UUID("9059F30F-4EB1-4BD2-9FDC-36F43A218F4A") +MsRdpClient2; +#endif + +EXTERN_C const CLSID CLSID_MsRdpClient3; + +#ifdef __cplusplus + +class DECLSPEC_UUID("7584C670-2274-4EFB-B00B-D6AABA6D3850") +MsRdpClient3; +#endif + +EXTERN_C const CLSID CLSID_MsRdpClient4; + +#ifdef __cplusplus + +class DECLSPEC_UUID("6AE29350-321B-42BE-BBE5-12FB5270C0DE") +MsRdpClient4; +#endif +#endif /* __MSTSCLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_i.c b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_i.c new file mode 100644 index 00000000000..eb8092fc8e4 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/mstsclib_redist_i.c @@ -0,0 +1,145 @@ + + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + + /* File created by MIDL compiler version 7.00.0493 */ +/* at Sun Aug 13 16:46:05 2006 + */ +/* Compiler settings for .\mstsclib_redist.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) + +#pragma warning( disable: 4049 ) /* more than 64k source lines */ + + +#ifdef __cplusplus +extern "C"{ +#endif + + +#include +#include + +#ifdef _MIDL_USE_GUIDDEF_ + +#ifndef INITGUID +#define INITGUID +#include +#undef INITGUID +#else +#include +#endif + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) + +#else // !_MIDL_USE_GUIDDEF_ + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +#endif !_MIDL_USE_GUIDDEF_ + +MIDL_DEFINE_GUID(IID, LIBID_MSTSCLib,0xAF586AAE,0xB62A,0x420E,0xB7,0x96,0x29,0x4E,0x7E,0xE6,0x4C,0x70); + + +MIDL_DEFINE_GUID(IID, DIID_IMsTscAxEvents,0x336D5562,0xEFA8,0x482E,0x8C,0xB3,0xC5,0xC0,0xFC,0x7A,0x7D,0xB6); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscAx,0x327BB5CD,0x834E,0x4400,0xAE,0xF2,0xB3,0x0E,0x15,0xE5,0xD6,0x82); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClient,0x92B4A539,0x7115,0x4B7C,0xA5,0xA9,0xE5,0xD9,0xEF,0xC2,0x78,0x0A); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClient2,0xE7E17DC4,0x3B71,0x4BA7,0xA8,0xE6,0x28,0x1F,0xFA,0xDC,0xA2,0x8F); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClient3,0x91B7CBC5,0xA72E,0x4FA0,0x93,0x00,0xD6,0x47,0xD7,0xE8,0x97,0xFF); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClient4,0x095E0738,0xD97D,0x488B,0xB9,0xF6,0xDD,0x0E,0x8D,0x66,0xC0,0xDE); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscNonScriptable,0xC1E6743A,0x41C1,0x4A74,0x83,0x2A,0x0D,0xD0,0x6C,0x1C,0x7A,0x0E); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientNonScriptable,0x2F079C4C,0x87B2,0x4AFD,0x97,0xAB,0x20,0xCD,0xB4,0x30,0x38,0xAE); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientNonScriptable2,0x17A5E535,0x4072,0x4FA4,0xAF,0x32,0xC8,0xD0,0xD4,0x73,0x45,0xE9); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscAdvancedSettings,0x809945CC,0x4B3B,0x4A92,0xA6,0xB0,0xDB,0xF9,0xB5,0xF2,0xEF,0x2D); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientAdvancedSettings,0x3C65B4AB,0x12B3,0x465B,0xAC,0xD4,0xB8,0xDA,0xD3,0xBF,0xF9,0xE2); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientAdvancedSettings2,0x9AC42117,0x2B76,0x4320,0xAA,0x44,0x0E,0x61,0x6A,0xB8,0x43,0x7B); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientAdvancedSettings3,0x19CD856B,0xC542,0x4C53,0xAC,0xEE,0xF1,0x27,0xE3,0xBE,0x1A,0x59); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientAdvancedSettings4,0xFBA7F64E,0x7345,0x4405,0xAE,0x50,0xFA,0x4A,0x76,0x3D,0xC0,0xDE); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscSecuredSettings,0xC9D65442,0xA0F9,0x45B2,0x8F,0x73,0xD6,0x1D,0x2D,0xB8,0xCB,0xB6); + + +MIDL_DEFINE_GUID(IID, IID_IMsRdpClientSecuredSettings,0x605BEFCF,0x39C1,0x45CC,0xA8,0x11,0x06,0x8F,0xB7,0xBE,0x34,0x6D); + + +MIDL_DEFINE_GUID(IID, IID_IMsTscDebug,0x209D0EB9,0x6254,0x47B1,0x90,0x33,0xA9,0x8D,0xAE,0x55,0xBB,0x27); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsTscAx,0x1FB464C8,0x09BB,0x4017,0xA2,0xF5,0xEB,0x74,0x2F,0x04,0x39,0x2F); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsRdpClient,0x791FA017,0x2DE3,0x492E,0xAC,0xC5,0x53,0xC6,0x7A,0x2B,0x94,0xD0); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsRdpClient2,0x9059F30F,0x4EB1,0x4BD2,0x9F,0xDC,0x36,0xF4,0x3A,0x21,0x8F,0x4A); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsRdpClient3,0x7584C670,0x2274,0x4EFB,0xB0,0x0B,0xD6,0xAA,0xBA,0x6D,0x38,0x50); + + +MIDL_DEFINE_GUID(CLSID, CLSID_MsRdpClient4,0x6AE29350,0x321B,0x42BE,0xBB,0xE5,0x12,0xFB,0x52,0x70,0xC0,0xDE); + +#undef MIDL_DEFINE_GUID + +#ifdef __cplusplus +} +#endif + + + diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp new file mode 100644 index 00000000000..29992767db0 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp @@ -0,0 +1,653 @@ +#include "stdafx.h" + +#include + +#include "rdesktop/rdesktop.h" +#include "rdesktop/proto.h" + +extern "C" +{ + /* ==== BEGIN POOP ==== */ + // Temporary implementations of stuff we totally positively need to make the Real Thing happy + /* produce a hex dump */ + void + hexdump(unsigned char *p, unsigned int len) + { + unsigned char *line = p; + int i, thisline; + unsigned int offset = 0; + + while (offset < len) + { + printf("%04x ", offset); + thisline = len - offset; + if (thisline > 16) + thisline = 16; + + for (i = 0; i < thisline; i++) + printf("%02x ", line[i]); + + for (; i < 16; i++) + printf(" "); + + for (i = 0; i < thisline; i++) + printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'); + + printf("\n"); + offset += thisline; + line += thisline; + } + } + + void generate_random(uint8 * random) + { + memcpy(random, "12345678901234567890123456789012", 32); + } + + /* report an error */ + void + error(char *format, ...) + { + va_list ap; + + fprintf(stderr, "ERROR: "); + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + } + + /* report a warning */ + void + warning(char *format, ...) + { + va_list ap; + + fprintf(stderr, "WARNING: "); + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + } + + /* report an unimplemented protocol feature */ + void + unimpl(char *format, ...) + { + va_list ap; + + fprintf(stderr, "NOT IMPLEMENTED: "); + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + } + + /* Create the bitmap cache directory */ + BOOL + rd_pstcache_mkdir(void) + { + char *home; + char bmpcache_dir[256]; + + home = getenv("HOME"); + + if (home == NULL) + return False; + + sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop"); + + if ((_mkdir(bmpcache_dir) == -1) && errno != EEXIST) + { + perror(bmpcache_dir); + return False; + } + + sprintf(bmpcache_dir, "%s/%s", home, ".rdesktop/cache"); + + if ((_mkdir(bmpcache_dir) == -1) && errno != EEXIST) + { + perror(bmpcache_dir); + return False; + } + + return True; + } + + /* open a file in the .rdesktop directory */ + int + rd_open_file(char *filename) + { + char *home; + char fn[256]; + int fd; + + home = getenv("HOME"); + if (home == NULL) + return -1; + sprintf(fn, "%s/.rdesktop/%s", home, filename); + fd = _open(fn, _O_RDWR | _O_CREAT, 0); + if (fd == -1) + perror(fn); + return fd; + } + + /* close file */ + void + rd_close_file(int fd) + { + _close(fd); + } + + /* read from file*/ + int + rd_read_file(int fd, void *ptr, int len) + { + return _read(fd, ptr, len); + } + + /* write to file */ + int + rd_write_file(int fd, void *ptr, int len) + { + return _write(fd, ptr, len); + } + + /* move file pointer */ + int + rd_lseek_file(int fd, int offset) + { + return _lseek(fd, offset, SEEK_SET); + } + + /* do a write lock on a file */ + BOOL + rd_lock_file(int fd, int start, int len) + { + // TODOOO... + return False; + } + + int + load_licence(RDPCLIENT * This, unsigned char **data) + { + return -1; + } + + void + save_licence(RDPCLIENT * This, unsigned char *data, int length) + { + } + + /* ==== END POOP ==== */ + + /* ==== UI ==== */ + // Globals are totally teh evil, but cut me some slack here + HWND hwnd; + HBITMAP hbmBuffer; + PVOID pBuffer; + HDC hdcBuffer; + UINT wmZMouseWheel; + +}; + +static +void +mstsc_mousewheel(RDPCLIENT * This, int value, LPARAM lparam) +{ + uint16 button; + + if(value < 0) + button = MOUSE_FLAG_BUTTON5; + else + button = MOUSE_FLAG_BUTTON4; + + if(value < 0) + value = - value; + + for(int click = 0; click < value; click += WHEEL_DELTA) + rdp_send_input(This, GetTickCount(), RDP_INPUT_MOUSE, button | MOUSE_FLAG_DOWN, LOWORD(lparam), HIWORD(lparam)); +} + +static +LRESULT +CALLBACK +mstsc_WndProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam) +{ + // BUGBUG: LongToPtr & PtrToLong will break on Win64 + + RDPCLIENT * This = reinterpret_cast(LongToPtr(GetWindowLongPtr(hwnd, GWLP_USERDATA))); + + switch(uMsg) + { + case WM_CLOSE: + DestroyWindow(hwnd); + break; + + // FIXME: temporary + case WM_DESTROY: + PostQuitMessage(0); + break; + + /* Initialization */ + case WM_CREATE: + This = static_cast(reinterpret_cast(lparam)->lpCreateParams); + SetWindowLongPtr(hwnd, GWLP_USERDATA, PtrToLong(This)); + break; + + /* Painting */ + case WM_PRINTCLIENT: + if(wparam == 0) + break; + + case WM_PAINT: + { + HDC hdc = (HDC)wparam; + + // A DC was provided: print the whole client area into it + if(hdc) + { + RECT rc; + GetClientRect(hwnd, &rc); + BitBlt(hdc, 0, 0, rc.right, rc.bottom, hdcBuffer, 0, 0, SRCCOPY); + } + // Otherwise, we're refreshing to screen + else + { + PAINTSTRUCT ps; + hdc = BeginPaint(hwnd, &ps); + + BitBlt + ( + hdc, + ps.rcPaint.left, + ps.rcPaint.top, + ps.rcPaint.right - ps.rcPaint.left, + ps.rcPaint.bottom - ps.rcPaint.top, + hdcBuffer, + ps.rcPaint.left, + ps.rcPaint.top, + SRCCOPY + ); + + EndPaint(hwnd, &ps); + } + } + + break; + + /* Keyboard stuff */ + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + rdp_send_input(This, GetMessageTime(), RDP_INPUT_SCANCODE, RDP_KEYPRESS | (lparam & 0x1000000 ? KBD_FLAG_EXT : 0), LOBYTE(HIWORD(lparam)), 0); + break; + + case WM_SYSKEYUP: + case WM_KEYUP: + rdp_send_input(This, GetMessageTime(), RDP_INPUT_SCANCODE, RDP_KEYRELEASE | (lparam & 0x1000000 ? KBD_FLAG_EXT : 0), LOBYTE(HIWORD(lparam)), 0); + break; + + /* Mouse stuff */ + // Cursor shape + case WM_SETCURSOR: + if(LOWORD(lparam) == HTCLIENT) + { + //SetCursor(hcursor); + return TRUE; + } + + break; + + // Movement + case WM_MOUSEMOVE: + //if(This->sendmotion || wparam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON | MK_XBUTTON1 | MK_XBUTTON2)) + rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, LOWORD(lparam), HIWORD(lparam)); + + break; + + // Buttons + // TODO: X buttons + case WM_LBUTTONDOWN: + rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1 | MOUSE_FLAG_DOWN, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_RBUTTONDOWN: + rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2 | MOUSE_FLAG_DOWN, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_MBUTTONDOWN: + rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3 | MOUSE_FLAG_DOWN, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_LBUTTONUP: + rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON1, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_RBUTTONUP: + rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON2, LOWORD(lparam), HIWORD(lparam)); + break; + + case WM_MBUTTONUP: + rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_BUTTON3, LOWORD(lparam), HIWORD(lparam)); + break; + + // Wheel + case WM_MOUSEWHEEL: + mstsc_mousewheel(This, (SHORT)HIWORD(wparam), lparam); + break; + + default: + /* Registered messages */ + // Z-Mouse wheel support - you know, just in case + if(uMsg == wmZMouseWheel) + { + mstsc_mousewheel(This, (int)wparam, lparam); + break; + } + + /* Unhandled messages */ + return DefWindowProc(hwnd, uMsg, wparam, lparam); + } + + return 0; +} + +static +DWORD +WINAPI +mstsc_ProtocolIOThread +( + LPVOID lpArgument +) +{ + RDPCLIENT * This = static_cast(lpArgument); + + WCHAR hostname[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD dw = ARRAYSIZE(hostname); + GetComputerNameW(hostname, &dw); + + uint32 flags = RDP_LOGON_NORMAL | RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2; + + rdp_connect(This, "10.0.0.3", flags, L"Administrator", L"", L"", L"", L"", hostname, ""); + //rdp_connect(This, "192.168.7.232", flags, "", "", "", ""); + + hdcBuffer = CreateCompatibleDC(NULL); + + BITMAPINFO bmi; + bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); + bmi.bmiHeader.biWidth = This->width; + bmi.bmiHeader.biHeight = This->height; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = This->server_depth; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = 0; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 0; // TODO! palette displays + bmi.bmiHeader.biClrImportant = 0; // TODO! palette displays + + hbmBuffer = CreateDIBSection(hdcBuffer, &bmi, DIB_RGB_COLORS, &pBuffer, NULL, 0); + + SelectObject(hdcBuffer, hbmBuffer); + +#if 0 + rcClip.left = 0; + rcClip.top = 0; + rcClip.right = This->width + 1; + rcClip.bottom = This->height + 1; +#endif + + BOOL deactivated; + uint32 ext_disc_reason; + + rdp_main_loop(This, &deactivated, &ext_disc_reason); + // TODO: handle redirection + // EVENT: OnDisconnect + + SendMessage(hwnd, WM_CLOSE, 0, 0); + + return 0; +} + +/* Virtual channel stuff */ +extern "C" void channel_process(RDPCLIENT * This, STREAM s, uint16 mcs_channel) +{ +} + +DWORD tlsIndex; + +typedef struct CHANNEL_HANDLE_ +{ + RDPCLIENT * client; + int channel; +} +CHANNEL_HANDLE; + +static +UINT +VCAPITYPE +VirtualChannelInit +( + LPVOID * ppInitHandle, + PCHANNEL_DEF pChannel, + INT channelCount, + ULONG versionRequested, + PCHANNEL_INIT_EVENT_FN pChannelInitEventProc +) +{ + if(channelCount <= 0) + return CHANNEL_RC_BAD_CHANNEL; + + if(ppInitHandle == NULL) + return CHANNEL_RC_BAD_INIT_HANDLE; + + if(pChannel == NULL) + return CHANNEL_RC_BAD_CHANNEL; + + if(pChannelInitEventProc == NULL) + return CHANNEL_RC_BAD_PROC; + + RDPCLIENT * This = (RDPCLIENT *)TlsGetValue(tlsIndex); + + if(This == NULL) + return CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY; + + if(This->num_channels + channelCount > CHANNEL_MAX_COUNT) + return CHANNEL_RC_TOO_MANY_CHANNELS; + + for(INT i = 0; i < channelCount; ++ i) + { + if(strlen(pChannel[i].name) > CHANNEL_NAME_LEN) + return CHANNEL_RC_BAD_CHANNEL; + } + + memcpy(This->channel_defs + This->num_channels, pChannel, sizeof(*pChannel) * channelCount); + +#if 0 // TODO + for(INT i = 0; i < channelCount; ++ i) + { + pChannel[i].options |= CHANNEL_OPTION_INITIALIZED; + + int j = This->num_channels + i; + This->channel_data[j].opened = 0; + This->channel_data[j].pChannelInitEventProc = pChannelInitEventProc; + This->channel_data[j].pChannelOpenEventProc = NULL; + } +#endif + + This->num_channels += channelCount; + + *ppInitHandle = This; + + return CHANNEL_RC_OK; +} + +UINT +VCAPITYPE +VirtualChannelOpen +( + LPVOID pInitHandle, + LPDWORD pOpenHandle, + PCHAR pChannelName, + PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc +) +{ + if(pInitHandle == NULL) + return CHANNEL_RC_BAD_INIT_HANDLE; + + if(pOpenHandle == NULL) + return CHANNEL_RC_BAD_CHANNEL_HANDLE; + + if(pChannelName == NULL) + return CHANNEL_RC_UNKNOWN_CHANNEL_NAME; + + if(pChannelOpenEventProc == NULL) + return CHANNEL_RC_BAD_PROC; + + RDPCLIENT * This = (RDPCLIENT *)pInitHandle; + +#if 0 // TODO + for(unsigned i = 0; i < This->num_channels; ++ i) + { + if(strcmp(pChannelName, This->channel_defs[i].name) == 0) + { + if(This->channel_data[i].opened) + return CHANNEL_RC_ALREADY_OPEN; + + This->channel_data[i].opened = 1; + This->channel_data[i].pChannelOpenEventProc = pChannelOpenEventProc; + + // TODO: allocate a handle here + *pOpenHandle = 0; + + break; + } + } +#endif + + return CHANNEL_RC_OK; +} + +UINT VCAPITYPE VirtualChannelClose +( + DWORD openHandle +) +{ + // TODO: channel handle management + return CHANNEL_RC_BAD_CHANNEL_HANDLE; +} + +UINT VCAPITYPE VirtualChannelWrite +( + DWORD openHandle, + LPVOID pData, + ULONG dataLength, + LPVOID pUserData +) +{ + // TODO + return CHANNEL_RC_BAD_CHANNEL_HANDLE; +} + +int wmain() +{ + WSADATA wsd; + WSAStartup(MAKEWORD(2, 2), &wsd); + + static RDPCLIENT This_; // NOTE: this is HUGE and would overflow the stack! + ZeroMemory(&This_, sizeof(This_)); + + RDPCLIENT * This = &This_; + + /* + Threading model for MissTosca: + - main thread is the GUI thread. Message loop maintained by caller + - protocol I/O is handled in an I/O thread (or thread pool) + - extra threads maintained by virtual channel handlers. Virtual channel writes are thread-neutral + + How we handle drawing: at the moment just an off-screen buffer we dump on-screen when asked to. + Still considering how to draw on-screen directly and *then* buffering off-screen (for example, + when running inside another remote session) + */ + + // FIXME: keyboard mess + This->keylayout = 0x409; + This->keyboard_type = 0x4; + This->keyboard_subtype = 0x0; + This->keyboard_functionkeys = 0xc; + This->width = 800; + This->height = 600; + This->server_depth = 24; + This->bitmap_compression = True; + //This->sendmotion = True; + This->bitmap_cache = True; + This->bitmap_cache_persist_enable = False; + This->bitmap_cache_precache = True; + This->encryption = True; + This->packet_encryption = True; + This->desktop_save = True; + This->polygon_ellipse_orders = False; // = True; + //This->fullscreen = False; + //This->grab_keyboard = True; + //This->hide_decorations = False; + This->use_rdp5 = True; + //This->rdpclip = True; + This->console_session = False; + //This->numlock_sync = False; + //This->seamless_rdp = False; + This->rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS; + This->tcp_port_rdp = TCP_PORT_RDP; + +#define NOT_SET -1 + This->cache.bmpcache_lru[0] = NOT_SET; + This->cache.bmpcache_lru[1] = NOT_SET; + This->cache.bmpcache_lru[2] = NOT_SET; + This->cache.bmpcache_mru[0] = NOT_SET; + This->cache.bmpcache_mru[1] = NOT_SET; + This->cache.bmpcache_mru[2] = NOT_SET; + + This->rdp.current_status = 1; + + //hcursor = NULL; + + WNDCLASS wc; + ZeroMemory(&wc, sizeof(wc)); + + wc.lpfnWndProc = mstsc_WndProc; + wc.hbrBackground = static_cast(GetStockObject(HOLLOW_BRUSH)); + wc.lpszClassName = TEXT("MissTosca_Desktop"); + + wmZMouseWheel = RegisterWindowMessage(MSH_MOUSEWHEEL); + + ATOM a = RegisterClass(&wc); + + hwnd = CreateWindow + ( + MAKEINTATOM(a), + NULL, + WS_POPUP | WS_VISIBLE, + CW_USEDEFAULT, + CW_USEDEFAULT, + This->width, + This->height, + NULL, + NULL, + NULL, + This + ); + + // The righ time to start the protocol thread + DWORD dwThreadId; + HANDLE hThread = CreateThread(NULL, 0, mstsc_ProtocolIOThread, This, 0, &dwThreadId); + + // Your standard, garden variety message loop + MSG msg; + + while(GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.vcproj b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.vcproj new file mode 100644 index 00000000000..3e91425b3b5 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/rdesktop-core-tester.vcproj @@ -0,0 +1,377 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/stdafx.cpp b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/stdafx.cpp new file mode 100644 index 00000000000..1e9dbf2c515 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/stdafx.cpp @@ -0,0 +1,3 @@ +#include "stdafx.h" + +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/stdafx.h b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/stdafx.h new file mode 100644 index 00000000000..87956e633cb --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/stdafx.h @@ -0,0 +1,32 @@ +#pragma once + +#define _CRT_SECURE_NO_DEPRECATE +#define _SECURE_SCL 0 + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include +#include +#include +#include +#include + +#include + +// EOF diff --git a/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/typelib.rh b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/typelib.rh new file mode 100644 index 00000000000..e14a7da2c05 --- /dev/null +++ b/rosapps/applications/net/tsclient/porting-tools/rdesktop-core-tester/typelib.rh @@ -0,0 +1,21 @@ +#define TOSTRING_(X) #X +#define TOSTRING(X) TOSTRING_(X) + +LANGUAGE 0, 0 + +#ifndef TYPELIB_PATH__ +#error TYPELIB_PATH__ not defined +#endif + +#ifndef TYPELIB_RESOURCEID__ +#error TYPELIB_RESOURCEID__ not defined +#endif + +/* + NOTE: + TYPELIB_PATH__ is defined on the command line (-D TYPELIB_PATH__=) + TYPELIB_RESOURCEID__ is defined before this file is included +*/ +TYPELIB_RESOURCEID__ TYPELIB TOSTRING(TYPELIB_PATH__) + +// EOF diff --git a/rosapps/applications/net/tsclient/rdesktop/COPYING b/rosapps/applications/net/tsclient/rdesktop/COPYING new file mode 100644 index 00000000000..416ee71e5ba --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/COPYING @@ -0,0 +1,346 @@ +This software is released under the GNU General Public License +(reproduced below) with the additional exemption that compiling, +linking, and/or using OpenSSL together with this software is +allowed. + +--- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/rosapps/applications/net/tsclient/rdesktop/Makefile.in b/rosapps/applications/net/tsclient/rdesktop/Makefile.in new file mode 100644 index 00000000000..17d5522fac3 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/Makefile.in @@ -0,0 +1,158 @@ +# +# rdesktop: A Remote Desktop Protocol client +# Makefile.in +# Copyright (C) Matthew Chapman 1999-2005 +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +mandir = @mandir@ +datadir = @datadir@ + +VERSION = @PACKAGE_VERSION@ +KEYMAP_PATH = $(datadir)/rdesktop/keymaps/ + +CC = @CC@ +INSTALL = @INSTALL@ +CFLAGS = @CFLAGS@ @X_CFLAGS@ @DEFS@ -DKEYMAP_PATH=\"$(KEYMAP_PATH)\" +LDFLAGS = @LDFLAGS@ @LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ +STRIP = @STRIP@ + +TARGETS = rdesktop @RDP2VNCTARGET@ +VNCINC = @VNCINC@ +LDVNC = @LDVNC@ +VNCLINK = @VNCLINK@ +SOUNDOBJ = @SOUNDOBJ@ + +RDPOBJ = tcp.o iso.o mcs.o secure.o licence.o rdp.o orders.o bitmap.o cache.o rdp5.o channels.o rdpdr.o serial.o printer.o disk.o parallel.o printercache.o mppc.o pstcache.o lspci.o seamless.o +X11OBJ = rdesktop.o xwin.o xkeymap.o ewmhints.o xclip.o cliprdr.o +VNCOBJ = vnc/rdp2vnc.o vnc/vnc.o vnc/xkeymap.o vnc/x11stubs.o + +.PHONY: all +all: $(TARGETS) + +rdesktop: $(X11OBJ) $(SOUNDOBJ) $(RDPOBJ) + $(CC) $(CFLAGS) -o rdesktop $(X11OBJ) $(SOUNDOBJ) $(RDPOBJ) $(LDFLAGS) -lX11 + +rdp2vnc: $(VNCOBJ) $(SOUNDOBJ) $(RDPOBJ) + $(VNCLINK) $(CFLAGS) -o rdp2vnc $(VNCOBJ) $(SOUNDOBJ) $(RDPOBJ) $(LDFLAGS) $(LDVNC) + +vnc/rdp2vnc.o: rdesktop.c + $(CC) $(CFLAGS) $(VNCINC) -DRDP2VNC -o vnc/rdp2vnc.o -c rdesktop.c + +vnc/vnc.o: vnc/vnc.c + $(CC) $(CFLAGS) $(VNCINC) -DRDP2VNC -o vnc/vnc.o -c vnc/vnc.c + +vnc/xkeymap.o: xkeymap.c + $(CC) $(CFLAGS) $(VNCINC) -DRDP2VNC -o vnc/xkeymap.o -c xkeymap.c + +vnc/x11stubs.o: vnc/x11stubs.c + $(CC) $(CFLAGS) $(VNCINC) -o vnc/x11stubs.o -c vnc/x11stubs.c + +.PHONY: install +install: installbin installkeymaps installman + +.PHONY: installbin +installbin: rdesktop + mkdir -p $(DESTDIR)$(bindir) + $(INSTALL) rdesktop $(DESTDIR)$(bindir) + $(STRIP) $(DESTDIR)$(bindir)/rdesktop + chmod 755 $(DESTDIR)$(bindir)/rdesktop + +.PHONY: installman +installman: doc/rdesktop.1 + mkdir -p $(DESTDIR)$(mandir)/man1 + cp doc/rdesktop.1 $(DESTDIR)$(mandir)/man1 + chmod 644 $(DESTDIR)$(mandir)/man1/rdesktop.1 + +.PHONY: installkeymaps +installkeymaps: + mkdir -p $(DESTDIR)$(KEYMAP_PATH) +# Prevent copying the CVS directory + cp keymaps/?? keymaps/??-?? $(DESTDIR)$(KEYMAP_PATH) + cp keymaps/common $(DESTDIR)$(KEYMAP_PATH) + cp keymaps/modifiers $(DESTDIR)$(KEYMAP_PATH) + chmod 644 $(DESTDIR)$(KEYMAP_PATH)/* + +.PHONY: proto +proto: + cat proto.head > proto.h + cproto -DMAKE_PROTO \ + bitmap.c cache.c channels.c cliprdr.c disk.c mppc.c ewmhints.c \ + iso.c licence.c mcs.c orders.c parallel.c printer.c printercache.c \ + pstcache.c rdesktop.c rdp5.c rdp.c rdpdr.c rdpsnd.c rdpsnd_oss.c \ + secure.c serial.c tcp.c xclip.c xkeymap.c xwin.c lspci.c seamless.c >> proto.h + cat proto.tail >> proto.h + +.PHONY: clean +clean: + rm -f *.o *~ vnc/*.o vnc/*~ rdesktop rdp2vnc + +.PHONY: distclean +distclean: clean + rm -rf autom4te.cache config.log config.status Makefile + +.PHONY: dist +dist: rdesktop-$(VERSION).tar.gz + +rdesktop-$(VERSION).tar.gz: Makefile configure + mkdir -p /tmp/rdesktop-make-dist-dir + ln -sf `pwd` /tmp/rdesktop-make-dist-dir/rdesktop-$(VERSION) + (cd /tmp/rdesktop-make-dist-dir; \ + tar zcvf rdesktop-$(VERSION)/rdesktop-$(VERSION).tar.gz \ + rdesktop-$(VERSION)/COPYING \ + rdesktop-$(VERSION)/README \ + rdesktop-$(VERSION)/configure \ + rdesktop-$(VERSION)/configure.ac \ + rdesktop-$(VERSION)/config.sub \ + rdesktop-$(VERSION)/config.guess \ + rdesktop-$(VERSION)/bootstrap \ + rdesktop-$(VERSION)/install-sh \ + rdesktop-$(VERSION)/Makefile.in \ + rdesktop-$(VERSION)/rdesktop.spec \ + rdesktop-$(VERSION)/*.c \ + rdesktop-$(VERSION)/*.h \ + rdesktop-$(VERSION)/proto.head \ + rdesktop-$(VERSION)/proto.tail \ + rdesktop-$(VERSION)/keymaps/?? \ + rdesktop-$(VERSION)/keymaps/??-?? \ + rdesktop-$(VERSION)/keymaps/common \ + rdesktop-$(VERSION)/keymaps/modifiers \ + rdesktop-$(VERSION)/keymaps/convert-map \ + rdesktop-$(VERSION)/doc/HACKING \ + rdesktop-$(VERSION)/doc/AUTHORS \ + rdesktop-$(VERSION)/doc/TODO \ + rdesktop-$(VERSION)/doc/ChangeLog \ + rdesktop-$(VERSION)/doc/keymapping.txt \ + rdesktop-$(VERSION)/doc/keymap-names.txt \ + rdesktop-$(VERSION)/doc/ipv6.txt \ + rdesktop-$(VERSION)/doc/licensing.txt \ + rdesktop-$(VERSION)/doc/patches.txt \ + rdesktop-$(VERSION)/doc/redirection.txt \ + rdesktop-$(VERSION)/doc/rdesktop.1 ) + rm -rf /tmp/rdesktop-make-dist-dir + +.PHONY: dist-noversion +dist-noversion: rdesktop.tar.gz + +rdesktop.tar.gz: rdesktop-$(VERSION).tar.gz + mkdir -p /tmp/rdesktop-make-dist-dir + tar zxvf $< -C /tmp/rdesktop-make-dist-dir + mv /tmp/rdesktop-make-dist-dir/rdesktop-$(VERSION) /tmp/rdesktop-make-dist-dir/rdesktop + ls /tmp/rdesktop-make-dist-dir/rdesktop + tar zcvf $@ -C /tmp/rdesktop-make-dist-dir rdesktop + rm -rf /tmp/rdesktop-make-dist-dir + +Makefile: Makefile.in configure + ./config.status + +configure: configure.ac + ./bootstrap + +.SUFFIXES: +.SUFFIXES: .c .o + +.c.o: + $(CC) $(CFLAGS) -o $@ -c $< + diff --git a/rosapps/applications/net/tsclient/rdesktop/README b/rosapps/applications/net/tsclient/rdesktop/README new file mode 100644 index 00000000000..d554582ba6d --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/README @@ -0,0 +1,32 @@ +=========================================== +rdesktop: A Remote Desktop Protocol client. +=========================================== + +rdesktop is a client for Microsoft Windows NT Terminal Server, Windows 2000 +Terminal Services, Windows 2003 Terminal Services/Remote Desktop, Windows XP +Remote Desktop, and possibly other Terminal Services products. +rdesktop currently implements the RDP version 4 and 5 protocols. + +Installation +------------ +rdesktop uses a typical GNU-style build procedure: + + % ./configure [options] + % make + % make install + +where documentation for [options] can be found by running "./configure --help". +Usually no options are necessary. The default is to install under /usr/local, +this can be changed with --prefix=directory. + +Invocation +---------- + + % rdesktop [options] server + +where server is the name of the Terminal Services machine. Note: if you +receive "Connection refused", this probably means that the server does not have +Terminal Services enabled, or there is a firewall blocking access. + +The rdesktop manual page lists the possible options ("man rdesktop"). + diff --git a/rosapps/applications/net/tsclient/rdesktop/bitmap.c b/rosapps/applications/net/tsclient/rdesktop/bitmap.c new file mode 100644 index 00000000000..d23a77c7c15 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/bitmap.c @@ -0,0 +1,1112 @@ +/* -*- c-basic-offset: 8 -*- + rdesktop: A Remote Desktop Protocol client. + Bitmap decompression routines + Copyright (C) Matthew Chapman 1999-2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* three seperate function for speed when decompressing the bitmaps */ +/* when modifing one function make the change in the others */ +/* comment out #define BITMAP_SPEED_OVER_SIZE below for one slower function */ +/* j@american-data.com */ + +#define BITMAP_SPEED_OVER_SIZE + +/* indent is confused by this file */ +/* *INDENT-OFF* */ + +#include "rdesktop.h" + +#define CVAL(p) (*(p++)) +#ifdef NEED_ALIGN +#ifdef L_ENDIAN +#define CVAL2(p, v) { v = (*(p++)); v |= (*(p++)) << 8; } +#else +#define CVAL2(p, v) { v = (*(p++)) << 8; v |= (*(p++)); } +#endif /* L_ENDIAN */ +#else +#define CVAL2(p, v) { v = (*((uint16*)p)); p += 2; } +#endif /* NEED_ALIGN */ + +#define UNROLL8(exp) { exp exp exp exp exp exp exp exp } + +#define REPEAT(statement) \ +{ \ + while((count & ~0x7) && ((x+8) < width)) \ + UNROLL8( statement; count--; x++; ); \ + \ + while((count > 0) && (x < width)) \ + { \ + statement; \ + count--; \ + x++; \ + } \ +} + +#define MASK_UPDATE() \ +{ \ + mixmask <<= 1; \ + if (mixmask == 0) \ + { \ + mask = fom_mask ? fom_mask : CVAL(input); \ + mixmask = 1; \ + } \ +} + +#ifdef BITMAP_SPEED_OVER_SIZE + +/* 1 byte bitmap decompress */ +static BOOL +bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size) +{ + uint8 *end = input + size; + uint8 *prevline = NULL; + int opcode, count, offset, isfillormix; + int lastopcode = -1, insertmix = False, bicolour = False; + uint8 code; + uint8 colour1 = 0, colour2 = 0; + uint8 mixmask, mask = 0; + uint8 mix = 0xff; + int fom_mask = 0; +#if 0 + uint8 *line = NULL; + int x = width; +#else + uint8 *line = output; + int x = 0; + int y = 0; +#endif + + while (input < end) + { + fom_mask = 0; + code = CVAL(input); + opcode = code >> 4; + /* Handle different opcode forms */ + switch (opcode) + { + case 0xc: + case 0xd: + case 0xe: + opcode -= 6; + count = code & 0xf; + offset = 16; + break; + case 0xf: + opcode = code & 0xf; + if (opcode < 9) + { + count = CVAL(input); + count |= CVAL(input) << 8; + } + else + { + count = (opcode < 0xb) ? 8 : 1; + } + offset = 0; + break; + default: + opcode >>= 1; + count = code & 0x1f; + offset = 32; + break; + } + /* Handle strange cases for counts */ + if (offset != 0) + { + isfillormix = ((opcode == 2) || (opcode == 7)); + if (count == 0) + { + if (isfillormix) + count = CVAL(input) + 1; + else + count = CVAL(input) + offset; + } + else if (isfillormix) + { + count <<= 3; + } + } + /* Read preliminary data */ + switch (opcode) + { + case 0: /* Fill */ + if ((lastopcode == opcode) && !((x == width) && (prevline == NULL))) + insertmix = True; + break; + case 8: /* Bicolour */ + colour1 = CVAL(input); + case 3: /* Colour */ + colour2 = CVAL(input); + break; + case 6: /* SetMix/Mix */ + case 7: /* SetMix/FillOrMix */ + mix = CVAL(input); + opcode -= 5; + break; + case 9: /* FillOrMix_1 */ + mask = 0x03; + opcode = 0x02; + fom_mask = 3; + break; + case 0x0a: /* FillOrMix_2 */ + mask = 0x05; + opcode = 0x02; + fom_mask = 5; + break; + } + lastopcode = opcode; + mixmask = 0; + /* Output body */ + while (count > 0) + { + if (x >= width) + { +#if 0 + if (height <= 0) +#else + if (y >= height) +#endif + return False; + x = 0; + +#if 0 + height--; +#else + y ++; +#endif + + prevline = line; + +#if 0 + line = output + height * width; +#else + line = output + y * width; +#endif + } + switch (opcode) + { + case 0: /* Fill */ + if (insertmix) + { + if (prevline == NULL) + line[x] = mix; + else + line[x] = prevline[x] ^ mix; + insertmix = False; + count--; + x++; + } + if (prevline == NULL) + { + REPEAT(line[x] = 0) + } + else + { + REPEAT(line[x] = prevline[x]) + } + break; + case 1: /* Mix */ + if (prevline == NULL) + { + REPEAT(line[x] = mix) + } + else + { + REPEAT(line[x] = prevline[x] ^ mix) + } + break; + case 2: /* Fill or Mix */ + if (prevline == NULL) + { + REPEAT + ( + MASK_UPDATE(); + if (mask & mixmask) + line[x] = mix; + else + line[x] = 0; + ) + } + else + { + REPEAT + ( + MASK_UPDATE(); + if (mask & mixmask) + line[x] = prevline[x] ^ mix; + else + line[x] = prevline[x]; + ) + } + break; + case 3: /* Colour */ + REPEAT(line[x] = colour2) + break; + case 4: /* Copy */ + REPEAT(line[x] = CVAL(input)) + break; + case 8: /* Bicolour */ + REPEAT + ( + if (bicolour) + { + line[x] = colour2; + bicolour = False; + } + else + { + line[x] = colour1; + bicolour = True; count++; + } + ) + break; + case 0xd: /* White */ + REPEAT(line[x] = 0xff) + break; + case 0xe: /* Black */ + REPEAT(line[x] = 0) + break; + default: + unimpl("bitmap opcode 0x%x\n", opcode); + return False; + } + } + } + return True; +} + +/* 2 byte bitmap decompress */ +static BOOL +bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int size) +{ + uint8 *end = input + size; + uint16 *prevline = NULL; + int opcode, count, offset, isfillormix; + int lastopcode = -1, insertmix = False, bicolour = False; + uint8 code; + uint16 colour1 = 0, colour2 = 0; + uint8 mixmask, mask = 0; + uint16 mix = 0xffff; + int fom_mask = 0; +#if 0 + uint8 *line = NULL; + int x = width; +#else + uint8 *line = output; + int x = 0; + int y = 0; +#endif + + while (input < end) + { + fom_mask = 0; + code = CVAL(input); + opcode = code >> 4; + /* Handle different opcode forms */ + switch (opcode) + { + case 0xc: + case 0xd: + case 0xe: + opcode -= 6; + count = code & 0xf; + offset = 16; + break; + case 0xf: + opcode = code & 0xf; + if (opcode < 9) + { + count = CVAL(input); + count |= CVAL(input) << 8; + } + else + { + count = (opcode < 0xb) ? 8 : 1; + } + offset = 0; + break; + default: + opcode >>= 1; + count = code & 0x1f; + offset = 32; + break; + } + /* Handle strange cases for counts */ + if (offset != 0) + { + isfillormix = ((opcode == 2) || (opcode == 7)); + if (count == 0) + { + if (isfillormix) + count = CVAL(input) + 1; + else + count = CVAL(input) + offset; + } + else if (isfillormix) + { + count <<= 3; + } + } + /* Read preliminary data */ + switch (opcode) + { + case 0: /* Fill */ + if ((lastopcode == opcode) && !((x == width) && (prevline == NULL))) + insertmix = True; + break; + case 8: /* Bicolour */ + CVAL2(input, colour1); + case 3: /* Colour */ + CVAL2(input, colour2); + break; + case 6: /* SetMix/Mix */ + case 7: /* SetMix/FillOrMix */ + CVAL2(input, mix); + opcode -= 5; + break; + case 9: /* FillOrMix_1 */ + mask = 0x03; + opcode = 0x02; + fom_mask = 3; + break; + case 0x0a: /* FillOrMix_2 */ + mask = 0x05; + opcode = 0x02; + fom_mask = 5; + break; + } + lastopcode = opcode; + mixmask = 0; + /* Output body */ + while (count > 0) + { + if (x >= width) + { +#if 0 + if (height <= 0) +#else + if (y >= height) +#endif + return False; + x = 0; + +#if 0 + height--; +#else + y ++; +#endif + + prevline = line; + +#if 0 + line = ((uint16 *) output) + height * width; +#else + line = ((uint16 *) output) + y * width; +#endif + } + switch (opcode) + { + case 0: /* Fill */ + if (insertmix) + { + if (prevline == NULL) + line[x] = mix; + else + line[x] = prevline[x] ^ mix; + insertmix = False; + count--; + x++; + } + if (prevline == NULL) + { + REPEAT(line[x] = 0) + } + else + { + REPEAT(line[x] = prevline[x]) + } + break; + case 1: /* Mix */ + if (prevline == NULL) + { + REPEAT(line[x] = mix) + } + else + { + REPEAT(line[x] = prevline[x] ^ mix) + } + break; + case 2: /* Fill or Mix */ + if (prevline == NULL) + { + REPEAT + ( + MASK_UPDATE(); + if (mask & mixmask) + line[x] = mix; + else + line[x] = 0; + ) + } + else + { + REPEAT + ( + MASK_UPDATE(); + if (mask & mixmask) + line[x] = prevline[x] ^ mix; + else + line[x] = prevline[x]; + ) + } + break; + case 3: /* Colour */ + REPEAT(line[x] = colour2) + break; + case 4: /* Copy */ + REPEAT(CVAL2(input, line[x])) + break; + case 8: /* Bicolour */ + REPEAT + ( + if (bicolour) + { + line[x] = colour2; + bicolour = False; + } + else + { + line[x] = colour1; + bicolour = True; + count++; + } + ) + break; + case 0xd: /* White */ + REPEAT(line[x] = 0xffff) + break; + case 0xe: /* Black */ + REPEAT(line[x] = 0) + break; + default: + unimpl("bitmap opcode 0x%x\n", opcode); + return False; + } + } + } + return True; +} + +/* 3 byte bitmap decompress */ +static BOOL +bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size) +{ + uint8 *end = input + size; + uint8 *prevline = NULL; + int opcode, count, offset, isfillormix; + int lastopcode = -1, insertmix = False, bicolour = False; + uint8 code; + uint8 colour1[3] = {0, 0, 0}, colour2[3] = {0, 0, 0}; + uint8 mixmask, mask = 0; + uint8 mix[3] = {0xff, 0xff, 0xff}; + int fom_mask = 0; +#if 0 + uint8 *line = NULL; + int x = width; +#else + uint8 *line = output; + int x = 0; + int y = 0; +#endif + + while (input < end) + { + fom_mask = 0; + code = CVAL(input); + opcode = code >> 4; + /* Handle different opcode forms */ + switch (opcode) + { + case 0xc: + case 0xd: + case 0xe: + opcode -= 6; + count = code & 0xf; + offset = 16; + break; + case 0xf: + opcode = code & 0xf; + if (opcode < 9) + { + count = CVAL(input); + count |= CVAL(input) << 8; + } + else + { + count = (opcode < + 0xb) ? 8 : 1; + } + offset = 0; + break; + default: + opcode >>= 1; + count = code & 0x1f; + offset = 32; + break; + } + /* Handle strange cases for counts */ + if (offset != 0) + { + isfillormix = ((opcode == 2) || (opcode == 7)); + if (count == 0) + { + if (isfillormix) + count = CVAL(input) + 1; + else + count = CVAL(input) + offset; + } + else if (isfillormix) + { + count <<= 3; + } + } + /* Read preliminary data */ + switch (opcode) + { + case 0: /* Fill */ + if ((lastopcode == opcode) && !((x == width) && (prevline == NULL))) + insertmix = True; + break; + case 8: /* Bicolour */ + colour1[0] = CVAL(input); + colour1[1] = CVAL(input); + colour1[2] = CVAL(input); + case 3: /* Colour */ + colour2[0] = CVAL(input); + colour2[1] = CVAL(input); + colour2[2] = CVAL(input); + break; + case 6: /* SetMix/Mix */ + case 7: /* SetMix/FillOrMix */ + mix[0] = CVAL(input); + mix[1] = CVAL(input); + mix[2] = CVAL(input); + opcode -= 5; + break; + case 9: /* FillOrMix_1 */ + mask = 0x03; + opcode = 0x02; + fom_mask = 3; + break; + case 0x0a: /* FillOrMix_2 */ + mask = 0x05; + opcode = 0x02; + fom_mask = 5; + break; + } + lastopcode = opcode; + mixmask = 0; + /* Output body */ + while (count > 0) + { + if (x >= width) + { +#if 0 + if (height <= 0) +#else + if (y >= height) +#endif + return False; + x = 0; + +#if 0 + height--; +#else + y ++; +#endif + + prevline = line; + +#if 0 + line = output + height * (width * 3); +#else + line = output + y * (width * 3); +#endif + } + switch (opcode) + { + case 0: /* Fill */ + if (insertmix) + { + if (prevline == NULL) + { + line[x * 3] = mix[0]; + line[x * 3 + 1] = mix[1]; + line[x * 3 + 2] = mix[2]; + } + else + { + line[x * 3] = + prevline[x * 3] ^ mix[0]; + line[x * 3 + 1] = + prevline[x * 3 + 1] ^ mix[1]; + line[x * 3 + 2] = + prevline[x * 3 + 2] ^ mix[2]; + } + insertmix = False; + count--; + x++; + } + if (prevline == NULL) + { + REPEAT + ( + line[x * 3] = 0; + line[x * 3 + 1] = 0; + line[x * 3 + 2] = 0; + ) + } + else + { + REPEAT + ( + line[x * 3] = prevline[x * 3]; + line[x * 3 + 1] = prevline[x * 3 + 1]; + line[x * 3 + 2] = prevline[x * 3 + 2]; + ) + } + break; + case 1: /* Mix */ + if (prevline == NULL) + { + REPEAT + ( + line[x * 3] = mix[0]; + line[x * 3 + 1] = mix[1]; + line[x * 3 + 2] = mix[2]; + ) + } + else + { + REPEAT + ( + line[x * 3] = + prevline[x * 3] ^ mix[0]; + line[x * 3 + 1] = + prevline[x * 3 + 1] ^ mix[1]; + line[x * 3 + 2] = + prevline[x * 3 + 2] ^ mix[2]; + ) + } + break; + case 2: /* Fill or Mix */ + if (prevline == NULL) + { + REPEAT + ( + MASK_UPDATE(); + if (mask & mixmask) + { + line[x * 3] = mix[0]; + line[x * 3 + 1] = mix[1]; + line[x * 3 + 2] = mix[2]; + } + else + { + line[x * 3] = 0; + line[x * 3 + 1] = 0; + line[x * 3 + 2] = 0; + } + ) + } + else + { + REPEAT + ( + MASK_UPDATE(); + if (mask & mixmask) + { + line[x * 3] = + prevline[x * 3] ^ mix [0]; + line[x * 3 + 1] = + prevline[x * 3 + 1] ^ mix [1]; + line[x * 3 + 2] = + prevline[x * 3 + 2] ^ mix [2]; + } + else + { + line[x * 3] = + prevline[x * 3]; + line[x * 3 + 1] = + prevline[x * 3 + 1]; + line[x * 3 + 2] = + prevline[x * 3 + 2]; + } + ) + } + break; + case 3: /* Colour */ + REPEAT + ( + line[x * 3] = colour2 [0]; + line[x * 3 + 1] = colour2 [1]; + line[x * 3 + 2] = colour2 [2]; + ) + break; + case 4: /* Copy */ + REPEAT + ( + line[x * 3] = CVAL(input); + line[x * 3 + 1] = CVAL(input); + line[x * 3 + 2] = CVAL(input); + ) + break; + case 8: /* Bicolour */ + REPEAT + ( + if (bicolour) + { + line[x * 3] = colour2[0]; + line[x * 3 + 1] = colour2[1]; + line[x * 3 + 2] = colour2[2]; + bicolour = False; + } + else + { + line[x * 3] = colour1[0]; + line[x * 3 + 1] = colour1[1]; + line[x * 3 + 2] = colour1[2]; + bicolour = True; + count++; + } + ) + break; + case 0xd: /* White */ + REPEAT + ( + line[x * 3] = 0xff; + line[x * 3 + 1] = 0xff; + line[x * 3 + 2] = 0xff; + ) + break; + case 0xe: /* Black */ + REPEAT + ( + line[x * 3] = 0; + line[x * 3 + 1] = 0; + line[x * 3 + 2] = 0; + ) + break; + default: + unimpl("bitmap opcode 0x%x\n", opcode); + return False; + } + } + } + return True; +} + +#else + +static uint32 +cvalx(uint8 **input, int Bpp) +{ + uint32 rv = 0; + memcpy(&rv, *input, Bpp); + *input += Bpp; + return rv; +} + +static void +setli(uint8 *input, int offset, uint32 value, int Bpp) +{ + input += offset * Bpp; + memcpy(input, &value, Bpp); +} + +static uint32 +getli(uint8 *input, int offset, int Bpp) +{ + uint32 rv = 0; + input += offset * Bpp; + memcpy(&rv, input, Bpp); + return rv; +} + +static BOOL +bitmap_decompressx(uint8 *output, int width, int height, uint8 *input, int size, int Bpp) +{ + uint8 *end = input + size; + uint8 *prevline = NULL; + int opcode, count, offset, isfillormix; + int lastopcode = -1, insertmix = False, bicolour = False; + uint8 code; + uint32 colour1 = 0, colour2 = 0; + uint8 mixmask, mask = 0; + uint32 mix = 0xffffffff; + int fom_mask = 0; +#if 0 + uint8 *line = NULL; + int x = width; +#else + uint8 *line = output; + int x = 0; + int y = 0; +#endif + + while (input < end) + { + fom_mask = 0; + code = CVAL(input); + opcode = code >> 4; + + /* Handle different opcode forms */ + switch (opcode) + { + case 0xc: + case 0xd: + case 0xe: + opcode -= 6; + count = code & 0xf; + offset = 16; + break; + + case 0xf: + opcode = code & 0xf; + if (opcode < 9) + { + count = CVAL(input); + count |= CVAL(input) << 8; + } + else + { + count = (opcode < 0xb) ? 8 : 1; + } + offset = 0; + break; + + default: + opcode >>= 1; + count = code & 0x1f; + offset = 32; + break; + } + + /* Handle strange cases for counts */ + if (offset != 0) + { + isfillormix = ((opcode == 2) || (opcode == 7)); + + if (count == 0) + { + if (isfillormix) + count = CVAL(input) + 1; + else + count = CVAL(input) + offset; + } + else if (isfillormix) + { + count <<= 3; + } + } + + /* Read preliminary data */ + switch (opcode) + { + case 0: /* Fill */ + if ((lastopcode == opcode) && !((x == width) && (prevline == NULL))) + insertmix = True; + break; + case 8: /* Bicolour */ + colour1 = cvalx(&input, Bpp); + case 3: /* Colour */ + colour2 = cvalx(&input, Bpp); + break; + case 6: /* SetMix/Mix */ + case 7: /* SetMix/FillOrMix */ + mix = cvalx(&input, Bpp); + opcode -= 5; + break; + case 9: /* FillOrMix_1 */ + mask = 0x03; + opcode = 0x02; + fom_mask = 3; + break; + case 0x0a: /* FillOrMix_2 */ + mask = 0x05; + opcode = 0x02; + fom_mask = 5; + break; + + } + + lastopcode = opcode; + mixmask = 0; + + /* Output body */ + while (count > 0) + { + if (x >= width) + { +#if 0 + if (height <= 0) +#else + if (y >= height) +#endif + return False; + + x = 0; + +#if 0 + height--; +#else + y ++; +#endif + + prevline = line; + +#if 0 + line = output + height * width * Bpp; +#else + line = output + y * width * Bpp; +#endif + } + + switch (opcode) + { + case 0: /* Fill */ + if (insertmix) + { + if (prevline == NULL) + setli(line, x, mix, Bpp); + else + setli(line, x, + getli(prevline, x, Bpp) ^ mix, Bpp); + + insertmix = False; + count--; + x++; + } + + if (prevline == NULL) + { + REPEAT(setli(line, x, 0, Bpp))} + else + { + REPEAT(setli + (line, x, getli(prevline, x, Bpp), Bpp)); + } + break; + + case 1: /* Mix */ + if (prevline == NULL) + { + REPEAT(setli(line, x, mix, Bpp)); + } + else + { + REPEAT(setli + (line, x, getli(prevline, x, Bpp) ^ mix, + Bpp)); + } + break; + + case 2: /* Fill or Mix */ + if (prevline == NULL) + { + REPEAT(MASK_UPDATE(); + if (mask & mixmask) setli(line, x, mix, Bpp); + else + setli(line, x, 0, Bpp);); + } + else + { + REPEAT(MASK_UPDATE(); + if (mask & mixmask) + setli(line, x, getli(prevline, x, Bpp) ^ mix, + Bpp); + else + setli(line, x, getli(prevline, x, Bpp), + Bpp);); + } + break; + + case 3: /* Colour */ + REPEAT(setli(line, x, colour2, Bpp)); + break; + + case 4: /* Copy */ + REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp)); + break; + + case 8: /* Bicolour */ + REPEAT(if (bicolour) + { + setli(line, x, colour2, Bpp); bicolour = False;} + else + { + setli(line, x, colour1, Bpp); bicolour = True; + count++;} + ); + break; + + case 0xd: /* White */ + REPEAT(setli(line, x, 0xffffffff, Bpp)); + break; + + case 0xe: /* Black */ + REPEAT(setli(line, x, 0, Bpp)); + break; + + default: + unimpl("bitmap opcode 0x%x\n", opcode); + return False; + } + } + } + + return True; +} + +#endif + +/* main decompress function */ +BOOL +bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp) +{ +#ifdef BITMAP_SPEED_OVER_SIZE + BOOL rv = False; + switch (Bpp) + { + case 1: + rv = bitmap_decompress1(output, width, height, input, size); + break; + case 2: + rv = bitmap_decompress2(output, width, height, input, size); + break; + case 3: + rv = bitmap_decompress3(output, width, height, input, size); + break; + } +#else + BOOL rv; + rv = bitmap_decompressx(output, width, height, input, size, Bpp); +#endif + return rv; +} + +/* *INDENT-ON* */ diff --git a/rosapps/applications/net/tsclient/rdesktop/bootstrap b/rosapps/applications/net/tsclient/rdesktop/bootstrap new file mode 100644 index 00000000000..73979144b4b --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/bootstrap @@ -0,0 +1,3 @@ +#!/bin/sh +rm -rf autom4te.cache +autoreconf -i diff --git a/rosapps/applications/net/tsclient/rdesktop/cache.c b/rosapps/applications/net/tsclient/rdesktop/cache.c new file mode 100644 index 00000000000..dd0bb491755 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/cache.c @@ -0,0 +1,414 @@ +/* -*- c-basic-offset: 8 -*- + rdesktop: A Remote Desktop Protocol client. + Cache routines + Copyright (C) Matthew Chapman 1999-2005 + Copyright (C) Jeroen Meijer 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "rdesktop.h" + +#undef IS_SET // !!!FIXME!!! + +/* BITMAP CACHE */ +#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(array[0])) +#define IS_PERSISTENT(id) (This->pstcache_fd[id] > 0) +#define TO_TOP -1 +#define NOT_SET -1 +#define IS_SET(idx) (idx >= 0) + +/* + * TODO: Test for optimal value of BUMP_COUNT. TO_TOP gives lowest cpu utilisation but using + * a positive value will hopefully result in less frequently used bitmaps having a greater chance + * of being evicted from the cache, and therby reducing the need to load bitmaps from disk. + * (Jeroen) + */ +#define BUMP_COUNT 40 + +/* Setup the bitmap cache lru/mru linked list */ +void +cache_rebuild_bmpcache_linked_list(RDPCLIENT * This, uint8 id, sint16 * idx, int count) +{ + int n = count, c = 0; + sint16 n_idx; + + /* find top, skip evicted bitmaps */ + while (--n >= 0 && This->cache.bmpcache[id][idx[n]].bitmap == NULL); + if (n < 0) + { + This->cache.bmpcache_mru[id] = This->cache.bmpcache_lru[id] = NOT_SET; + return; + } + + This->cache.bmpcache_mru[id] = idx[n]; + This->cache.bmpcache[id][idx[n]].next = NOT_SET; + n_idx = idx[n]; + c++; + + /* link list */ + while (n >= 0) + { + /* skip evicted bitmaps */ + while (--n >= 0 && This->cache.bmpcache[id][idx[n]].bitmap == NULL); + + if (n < 0) + break; + + This->cache.bmpcache[id][n_idx].previous = idx[n]; + This->cache.bmpcache[id][idx[n]].next = n_idx; + n_idx = idx[n]; + c++; + } + + This->cache.bmpcache[id][n_idx].previous = NOT_SET; + This->cache.bmpcache_lru[id] = n_idx; + + if (c != This->cache.bmpcache_count[id]) + { + error("Oops. %d in bitmap cache linked list, %d in ui cache...\n", c, + This->cache.bmpcache_count[id]); + exit(1); + } +} + +/* Move a bitmap to a new position in the linked list. */ +void +cache_bump_bitmap(RDPCLIENT * This, uint8 id, uint16 idx, int bump) +{ + int p_idx, n_idx, n; + + if (!IS_PERSISTENT(id)) + return; + + if (This->cache.bmpcache_mru[id] == idx) + return; + + DEBUG_RDP5(("bump bitmap: id=%d, idx=%d, bump=%d\n", id, idx, bump)); + + n_idx = This->cache.bmpcache[id][idx].next; + p_idx = This->cache.bmpcache[id][idx].previous; + + if (IS_SET(n_idx)) + { + /* remove */ + --This->cache.bmpcache_count[id]; + if (IS_SET(p_idx)) + This->cache.bmpcache[id][p_idx].next = n_idx; + else + This->cache.bmpcache_lru[id] = n_idx; + if (IS_SET(n_idx)) + This->cache.bmpcache[id][n_idx].previous = p_idx; + else + This->cache.bmpcache_mru[id] = p_idx; + } + else + { + p_idx = NOT_SET; + n_idx = This->cache.bmpcache_lru[id]; + } + + if (bump >= 0) + { + for (n = 0; n < bump && IS_SET(n_idx); n++) + { + p_idx = n_idx; + n_idx = This->cache.bmpcache[id][p_idx].next; + } + } + else + { + p_idx = This->cache.bmpcache_mru[id]; + n_idx = NOT_SET; + } + + /* insert */ + ++This->cache.bmpcache_count[id]; + This->cache.bmpcache[id][idx].previous = p_idx; + This->cache.bmpcache[id][idx].next = n_idx; + + if (p_idx >= 0) + This->cache.bmpcache[id][p_idx].next = idx; + else + This->cache.bmpcache_lru[id] = idx; + + if (n_idx >= 0) + This->cache.bmpcache[id][n_idx].previous = idx; + else + This->cache.bmpcache_mru[id] = idx; +} + +/* Evict the least-recently used bitmap from the cache */ +void +cache_evict_bitmap(RDPCLIENT * This, uint8 id) +{ + uint16 idx; + int n_idx; + + if (!IS_PERSISTENT(id)) + return; + + idx = This->cache.bmpcache_lru[id]; + n_idx = This->cache.bmpcache[id][idx].next; + DEBUG_RDP5(("evict bitmap: id=%d idx=%d n_idx=%d bmp=0x%x\n", id, idx, n_idx, + This->cache.bmpcache[id][idx].bitmap)); + + ui_destroy_bitmap(This, This->cache.bmpcache[id][idx].bitmap); + --This->cache.bmpcache_count[id]; + This->cache.bmpcache[id][idx].bitmap = 0; + + This->cache.bmpcache_lru[id] = n_idx; + This->cache.bmpcache[id][n_idx].previous = NOT_SET; + + pstcache_touch_bitmap(This, id, idx, 0); +} + +/* Retrieve a bitmap from the cache */ +HBITMAP +cache_get_bitmap(RDPCLIENT * This, uint8 id, uint16 idx) +{ + if ((id < NUM_ELEMENTS(This->cache.bmpcache)) && (idx < NUM_ELEMENTS(This->cache.bmpcache[0]))) + { + if (This->cache.bmpcache[id][idx].bitmap || pstcache_load_bitmap(This, id, idx)) + { + if (IS_PERSISTENT(id)) + cache_bump_bitmap(This, id, idx, BUMP_COUNT); + + return This->cache.bmpcache[id][idx].bitmap; + } + } + else if ((id < NUM_ELEMENTS(This->cache.volatile_bc)) && (idx == 0x7fff)) + { + return This->cache.volatile_bc[id]; + } + + error("get bitmap %d:%d\n", id, idx); + return NULL; +} + +/* Store a bitmap in the cache */ +void +cache_put_bitmap(RDPCLIENT * This, uint8 id, uint16 idx, HBITMAP bitmap) +{ + HBITMAP old; + + if ((id < NUM_ELEMENTS(This->cache.bmpcache)) && (idx < NUM_ELEMENTS(This->cache.bmpcache[0]))) + { + old = This->cache.bmpcache[id][idx].bitmap; + if (old != NULL) + ui_destroy_bitmap(This, old); + This->cache.bmpcache[id][idx].bitmap = bitmap; + + if (IS_PERSISTENT(id)) + { + if (old == NULL) + This->cache.bmpcache[id][idx].previous = This->cache.bmpcache[id][idx].next = NOT_SET; + + cache_bump_bitmap(This, id, idx, TO_TOP); + if (This->cache.bmpcache_count[id] > BMPCACHE2_C2_CELLS) + cache_evict_bitmap(This, id); + } + } + else if ((id < NUM_ELEMENTS(This->cache.volatile_bc)) && (idx == 0x7fff)) + { + old = This->cache.volatile_bc[id]; + if (old != NULL) + ui_destroy_bitmap(This, old); + This->cache.volatile_bc[id] = bitmap; + } + else + { + error("put bitmap %d:%d\n", id, idx); + } +} + +/* Updates the persistent bitmap cache MRU information on exit */ +void +cache_save_state(RDPCLIENT * This) +{ + uint32 id = 0, t = 0; + int idx; + + for (id = 0; id < NUM_ELEMENTS(This->cache.bmpcache); id++) + if (IS_PERSISTENT(id)) + { + DEBUG_RDP5(("Saving cache state for bitmap cache %d...", id)); + idx = This->cache.bmpcache_lru[id]; + while (idx >= 0) + { + pstcache_touch_bitmap(This, id, idx, ++t); + idx = This->cache.bmpcache[id][idx].next; + } + DEBUG_RDP5((" %d stamps written.\n", t)); + } +} + + +/* FONT CACHE */ +/* Retrieve a glyph from the font cache */ +FONTGLYPH * +cache_get_font(RDPCLIENT * This, uint8 font, uint16 character) +{ + FONTGLYPH *glyph; + + if ((font < NUM_ELEMENTS(This->cache.fontcache)) && (character < NUM_ELEMENTS(This->cache.fontcache[0]))) + { + glyph = &This->cache.fontcache[font][character]; + if (glyph->pixmap != NULL) + return glyph; + } + + error("get font %d:%d\n", font, character); + return NULL; +} + +/* Store a glyph in the font cache */ +void +cache_put_font(RDPCLIENT * This, uint8 font, uint16 character, uint16 offset, + uint16 baseline, uint16 width, uint16 height, HGLYPH pixmap) +{ + FONTGLYPH *glyph; + + if ((font < NUM_ELEMENTS(This->cache.fontcache)) && (character < NUM_ELEMENTS(This->cache.fontcache[0]))) + { + glyph = &This->cache.fontcache[font][character]; + if (glyph->pixmap != NULL) + ui_destroy_glyph(This, glyph->pixmap); + + glyph->offset = offset; + glyph->baseline = baseline; + glyph->width = width; + glyph->height = height; + glyph->pixmap = pixmap; + } + else + { + error("put font %d:%d\n", font, character); + } +} + + +/* TEXT CACHE */ +/* Retrieve a text item from the cache */ +DATABLOB * +cache_get_text(RDPCLIENT * This, uint8 cache_id) +{ + DATABLOB *text; + + text = &This->cache.textcache[cache_id]; + return text; +} + +/* Store a text item in the cache */ +void +cache_put_text(RDPCLIENT * This, uint8 cache_id, void *data, int length) +{ + DATABLOB *text; + void * p = malloc(length); + + if(p == NULL) + return; + + text = &This->cache.textcache[cache_id]; + if (text->data != NULL) + free(text->data); + text->data = p; + text->size = length; + memcpy(text->data, data, length); +} + + +/* DESKTOP CACHE */ +/* Retrieve desktop data from the cache */ +uint8 * +cache_get_desktop(RDPCLIENT * This, uint32 offset, int cx, int cy, int bytes_per_pixel) +{ + int length = cx * cy * bytes_per_pixel; + + if (offset > sizeof(This->cache.deskcache)) + offset = 0; + + if ((offset + length) <= sizeof(This->cache.deskcache)) + { + return &This->cache.deskcache[offset]; + } + + error("get desktop %d:%d\n", offset, length); + return NULL; +} + +/* Store desktop data in the cache */ +void +cache_put_desktop(RDPCLIENT * This, uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel, uint8 * data) +{ + int length = cx * cy * bytes_per_pixel; + + if (offset > sizeof(This->cache.deskcache)) + offset = 0; + + if ((offset + length) <= sizeof(This->cache.deskcache)) + { + cx *= bytes_per_pixel; + while (cy--) + { + memcpy(&This->cache.deskcache[offset], data, cx); + data += scanline; + offset += cx; + } + } + else + { + error("put desktop %d:%d\n", offset, length); + } +} + + +/* CURSOR CACHE */ +/* Retrieve cursor from cache */ +HCURSOR +cache_get_cursor(RDPCLIENT * This, uint16 cache_idx) +{ + HCURSOR cursor; + + if (cache_idx < NUM_ELEMENTS(This->cache.cursorcache)) + { + cursor = This->cache.cursorcache[cache_idx]; + if (cursor != NULL) + return cursor; + } + + error("get cursor %d\n", cache_idx); + return NULL; +} + +/* Store cursor in cache */ +void +cache_put_cursor(RDPCLIENT * This, uint16 cache_idx, HCURSOR cursor) +{ + HCURSOR old; + + if (cache_idx < NUM_ELEMENTS(This->cache.cursorcache)) + { + old = This->cache.cursorcache[cache_idx]; + if (old != NULL) + ui_destroy_cursor(This, old); + + This->cache.cursorcache[cache_idx] = cursor; + } + else + { + error("put cursor %d\n", cache_idx); + } +} diff --git a/rosapps/applications/net/tsclient/rdesktop/channels.c b/rosapps/applications/net/tsclient/rdesktop/channels.c new file mode 100644 index 00000000000..5c1f1bc696d --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/channels.c @@ -0,0 +1,177 @@ +/* -*- c-basic-offset: 8 -*- + rdesktop: A Remote Desktop Protocol client. + Protocol services - Virtual channels + Copyright (C) Erik Forsberg 2003 + Copyright (C) Matthew Chapman 2003-2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "rdesktop.h" + +// FIXME: header mess +#if 0 +#define CHANNEL_CHUNK_LENGTH 1600 +#define CHANNEL_FLAG_FIRST 0x01 +#define CHANNEL_FLAG_LAST 0x02 +#define CHANNEL_FLAG_SHOW_PROTOCOL 0x10 +#endif + +/* FIXME: We should use the information in TAG_SRV_CHANNELS to map RDP5 + channels to MCS channels. + + The format of TAG_SRV_CHANNELS seems to be + + global_channel_no (uint16le) + number_of_other_channels (uint16le) + ..followed by uint16les for the other channels. +*/ + +VCHANNEL * +channel_register(RDPCLIENT * This, char *name, uint32 flags, void (*callback) (RDPCLIENT *, STREAM)) +{ + VCHANNEL *channel; + + if (!This->use_rdp5) + return NULL; + + if (This->num_channels >= MAX_CHANNELS) + { + error("Channel table full, increase MAX_CHANNELS\n"); + return NULL; + } + + channel = &This->channels[This->num_channels]; + channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + This->num_channels; + strncpy(channel->name, name, 8); + channel->flags = flags; + channel->process = callback; + This->num_channels++; + return channel; +} + +STREAM +channel_init(RDPCLIENT * This, VCHANNEL * channel, uint32 length) +{ + STREAM s; + + s = sec_init(This, This->encryption ? SEC_ENCRYPT : 0, length + 8); + s_push_layer(s, channel_hdr, 8); + return s; +} + +void +channel_send(RDPCLIENT * This, STREAM s, VCHANNEL * channel) +{ + uint32 length, flags; + uint32 thislength, remaining; + uint8 *data; + + /* first fragment sent in-place */ + s_pop_layer(s, channel_hdr); + length = s->end - s->p - sizeof(CHANNEL_PDU_HEADER); + + DEBUG_CHANNEL(("channel_send, length = %d\n", length)); + + thislength = MIN(length, CHANNEL_CHUNK_LENGTH); +/* Note: In the original clipboard implementation, this number was + 1592, not 1600. However, I don't remember the reason and 1600 seems + to work so.. This applies only to *this* length, not the length of + continuation or ending packets. */ + remaining = length - thislength; + flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST; + if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL) + flags |= CHANNEL_FLAG_SHOW_PROTOCOL; + + out_uint32_le(s, length); + out_uint32_le(s, flags); + data = s->end = s->p + thislength; + DEBUG_CHANNEL(("Sending %d bytes with FLAG_FIRST\n", thislength)); + sec_send_to_channel(This, s, This->encryption ? SEC_ENCRYPT : 0, channel->mcs_id); + + /* subsequent segments copied (otherwise would have to generate headers backwards) */ + while (remaining > 0) + { + thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH); + remaining -= thislength; + flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0; + if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL) + flags |= CHANNEL_FLAG_SHOW_PROTOCOL; + + DEBUG_CHANNEL(("Sending %d bytes with flags %d\n", thislength, flags)); + + s = sec_init(This, This->encryption ? SEC_ENCRYPT : 0, thislength + 8); + out_uint32_le(s, length); + out_uint32_le(s, flags); + out_uint8p(s, data, thislength); + s_mark_end(s); + sec_send_to_channel(This, s, This->encryption ? SEC_ENCRYPT : 0, channel->mcs_id); + + data += thislength; + } +} + +void +channel_process(RDPCLIENT * This, STREAM s, uint16 mcs_channel) +{ + uint32 length, flags; + uint32 thislength; + VCHANNEL *channel = NULL; + unsigned int i; + STREAM in; + + for (i = 0; i < This->num_channels; i++) + { + channel = &This->channels[i]; + if (channel->mcs_id == mcs_channel) + break; + } + + if (i >= This->num_channels) + return; + + in_uint32_le(s, length); + in_uint32_le(s, flags); + if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST)) + { + /* single fragment - pass straight up */ + channel->process(This, s); + } + else + { + /* add fragment to defragmentation buffer */ + in = &channel->in; + if (flags & CHANNEL_FLAG_FIRST) + { + if (length > in->size) + { + in->data = (uint8 *) xrealloc(in->data, length); + in->size = length; + } + in->p = in->data; + } + + thislength = MIN(s->end - s->p, in->data + in->size - in->p); + memcpy(in->p, s->p, thislength); + in->p += thislength; + + if (flags & CHANNEL_FLAG_LAST) + { + in->end = in->p; + in->p = in->data; + channel->process(This, in); + } + } +} diff --git a/rosapps/applications/net/tsclient/rdesktop/cliprdr.c b/rosapps/applications/net/tsclient/rdesktop/cliprdr.c new file mode 100644 index 00000000000..01ef9055b14 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/cliprdr.c @@ -0,0 +1,182 @@ +/* -*- c-basic-offset: 8 -*- + rdesktop: A Remote Desktop Protocol client. + Protocol services - Clipboard functions + Copyright (C) Erik Forsberg 2003 + Copyright (C) Matthew Chapman 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "rdesktop.h" + +#define CLIPRDR_CONNECT 1 +#define CLIPRDR_FORMAT_ANNOUNCE 2 +#define CLIPRDR_FORMAT_ACK 3 +#define CLIPRDR_DATA_REQUEST 4 +#define CLIPRDR_DATA_RESPONSE 5 + +#define CLIPRDR_REQUEST 0 +#define CLIPRDR_RESPONSE 1 +#define CLIPRDR_ERROR 2 + +static void +cliprdr_send_packet(RDPCLIENT * This, uint16 type, uint16 status, uint8 * data, uint32 length) +{ + STREAM s; + + DEBUG_CLIPBOARD(("CLIPRDR send: type=%d, status=%d, length=%d\n", type, status, length)); + + s = channel_init(This, This->cliprdr.channel, length + 12); + out_uint16_le(s, type); + out_uint16_le(s, status); + out_uint32_le(s, length); + out_uint8p(s, data, length); + out_uint32(s, 0); /* pad? */ + s_mark_end(s); + channel_send(This, s, This->cliprdr.channel); +} + +/* Helper which announces our readiness to supply clipboard data + in a single format (such as CF_TEXT) to the RDP side. + To announce more than one format at a time, use + cliprdr_send_native_format_announce. + */ +void +cliprdr_send_simple_native_format_announce(RDPCLIENT * This, uint32 format) +{ + uint8 buffer[36]; + + DEBUG_CLIPBOARD(("cliprdr_send_simple_native_format_announce\n")); + + buf_out_uint32(buffer, format); + memset(buffer + 4, 0, sizeof(buffer) - 4); /* description */ + cliprdr_send_native_format_announce(This, buffer, sizeof(buffer)); +} + +/* Announces our readiness to supply clipboard data in multiple + formats, each denoted by a 36-byte format descriptor of + [ uint32 format + 32-byte description ]. + */ +void +cliprdr_send_native_format_announce(RDPCLIENT * This, uint8 * formats_data, uint32 formats_data_length) +{ + DEBUG_CLIPBOARD(("cliprdr_send_native_format_announce\n")); + + cliprdr_send_packet(This, CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, formats_data, + formats_data_length); + + if (formats_data != This->cliprdr.last_formats) + { + if (This->cliprdr.last_formats) + xfree(This->cliprdr.last_formats); + + This->cliprdr.last_formats = xmalloc(formats_data_length); + memcpy(This->cliprdr.last_formats, formats_data, formats_data_length); + This->cliprdr.last_formats_length = formats_data_length; + } +} + +void +cliprdr_send_data_request(RDPCLIENT * This, uint32 format) +{ + uint8 buffer[4]; + + DEBUG_CLIPBOARD(("cliprdr_send_data_request\n")); + buf_out_uint32(buffer, format); + cliprdr_send_packet(This, CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer)); +} + +void +cliprdr_send_data(RDPCLIENT * This, uint8 * data, uint32 length) +{ + DEBUG_CLIPBOARD(("cliprdr_send_data\n")); + cliprdr_send_packet(This, CLIPRDR_DATA_RESPONSE, CLIPRDR_RESPONSE, data, length); +} + +static void +cliprdr_process(RDPCLIENT * This, STREAM s) +{ + uint16 type, status; + uint32 length, format; + uint8 *data; + + in_uint16_le(s, type); + in_uint16_le(s, status); + in_uint32_le(s, length); + data = s->p; + + DEBUG_CLIPBOARD(("CLIPRDR recv: type=%d, status=%d, length=%d\n", type, status, length)); + + if (status == CLIPRDR_ERROR) + { + switch (type) + { + case CLIPRDR_FORMAT_ACK: + /* FIXME: We seem to get this when we send an announce while the server is + still processing a paste. Try sending another announce. */ + cliprdr_send_native_format_announce(This, This->cliprdr.last_formats, + This->cliprdr.last_formats_length); + break; + case CLIPRDR_DATA_RESPONSE: + ui_clip_request_failed(This); + break; + default: + DEBUG_CLIPBOARD(("CLIPRDR error (type=%d)\n", type)); + } + + return; + } + + switch (type) + { + case CLIPRDR_CONNECT: + ui_clip_sync(This); + break; + case CLIPRDR_FORMAT_ANNOUNCE: + ui_clip_format_announce(This, data, length); + cliprdr_send_packet(This, CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0); + return; + case CLIPRDR_FORMAT_ACK: + break; + case CLIPRDR_DATA_REQUEST: + in_uint32_le(s, format); + ui_clip_request_data(This, format); + break; + case CLIPRDR_DATA_RESPONSE: + ui_clip_handle_data(This, data, length); + break; + case 7: /* TODO: W2K3 SP1 sends this on connect with a value of 1 */ + break; + default: + unimpl("CLIPRDR packet type %d\n", type); + } +} + +void +cliprdr_set_mode(RDPCLIENT * This, const char *optarg) +{ + ui_clip_set_mode(This, optarg); +} + +BOOL +cliprdr_init(RDPCLIENT * This) +{ + This->cliprdr.channel = + channel_register(This, "cliprdr", + CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | + CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL, + cliprdr_process); + return (This->cliprdr.channel != NULL); +} diff --git a/rosapps/applications/net/tsclient/rdesktop/config.guess b/rosapps/applications/net/tsclient/rdesktop/config.guess new file mode 100644 index 00000000000..2fc3acce2ea --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/config.guess @@ -0,0 +1,1411 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-06-17' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +## for Red Hat Linux +if test -f /etc/redhat-release ; then + VENDOR=redhat ; +else + VENDOR= ; +fi + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha*:OpenVMS:*:*) + echo alpha-hp-vms + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && exit 0 + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + # avoid double evaluation of $set_cc_for_build + test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0 + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*|*:GNU/FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:[34]*) + echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + exit 0 ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR:-unknown}-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-${VENDOR:-unknown}-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-${VENDOR:-unknown}-linux-gnu + exit 0 ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-${VENDOR:-ibm}-linux-gnu + exit 0 ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-${VENDOR:-unknown}-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-${VENDOR:-pc}-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit 0 ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i*86:*:5:[78]*) + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit 0 ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + case `uname -p` in + *86) UNAME_PROCESSOR=i686 ;; + powerpc) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0 + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/rosapps/applications/net/tsclient/rdesktop/config.sub b/rosapps/applications/net/tsclient/rdesktop/config.sub new file mode 100644 index 00000000000..7cee3d6ec7f --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/config.sub @@ -0,0 +1,1500 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +timestamp='2003-06-18' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | msp430 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | s390 | s390x \ + | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | msp430-* \ + | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | s390-* | s390x-* \ + | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nv1) + basic_machine=nv1-cray + os=-unicosmp + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/rosapps/applications/net/tsclient/rdesktop/configure.ac b/rosapps/applications/net/tsclient/rdesktop/configure.ac new file mode 100644 index 00000000000..34a4e79c211 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/configure.ac @@ -0,0 +1,727 @@ +AC_INIT(rdesktop, 1.4.1) + +AC_CONFIG_SRCDIR([rdesktop.c]) + +AC_PROG_CC +if test "$GCC" = yes; then + CFLAGS="$CFLAGS -Wall" +fi + +AC_PROG_INSTALL +AC_LANG_C +AC_HEADER_STDC +AC_C_BIGENDIAN([AC_DEFINE(B_ENDIAN)], [AC_DEFINE(L_ENDIAN)]) +AC_PATH_XTRA + +AC_SEARCH_LIBS(socket, socket) +AC_SEARCH_LIBS(inet_aton, resolv) + +AC_CHECK_HEADER(sys/select.h, AC_DEFINE(HAVE_SYS_SELECT_H)) +AC_CHECK_HEADER(sys/modem.h, AC_DEFINE(HAVE_SYS_MODEM_H)) +AC_CHECK_HEADER(sys/filio.h, AC_DEFINE(HAVE_SYS_FILIO_H)) +AC_CHECK_HEADER(sys/strtio.h, AC_DEFINE(HAVE_SYS_STRTIO_H)) +AC_CHECK_HEADER(locale.h, AC_DEFINE(HAVE_LOCALE_H)) +AC_CHECK_HEADER(langinfo.h, AC_DEFINE(HAVE_LANGINFO_H)) + +AC_CHECK_TOOL(STRIP, strip, :) + +rpath="" + +# +# OpenSSL detection borrowed from stunnel +# +checkssldir() { : + if test -f "$1/include/openssl/ssl.h"; then + ssldir="$1" + return 0 + fi + return 1 +} +AC_MSG_CHECKING([for OpenSSL directory]) +AC_ARG_WITH(openssl, + [ --with-openssl=DIR look for OpenSSL at DIR/include, DIR/lib], + [ + dnl Check the specified location only + checkssldir "$withval" + ], + [ + dnl Search default locations of OpenSSL library + for maindir in /usr/local /usr/lib /usr/pkg /usr /var/ssl /opt; do + for dir in $maindir $maindir/openssl $maindir/ssl; do + checkssldir $dir && break 2 + done + done + ] +) +if test -z "$ssldir"; then + AC_MSG_RESULT([Not found]) + echo + echo "Couldn't find your OpenSSL library installation dir" + echo "Use --with-openssl option to fix this problem" + echo + exit 1 +fi +AC_MSG_RESULT([$ssldir]) +AC_SUBST(ssldir) +AC_DEFINE_UNQUOTED(ssldir, "$ssldir") + +dnl Add OpenSSL includes and libraries +CFLAGS="$CFLAGS -I$ssldir/include" +AC_ARG_ENABLE(static-openssl, + [ --enable-static-openssl link OpenSSL statically], + [ +LIBS="$LIBS $ssldir/lib/libcrypto.a" + ], + [ +LIBS="$LIBS -L$ssldir/lib -lcrypto" +rpath="$rpath:$ssldir/lib" + ]) + + +# +# Alignment +# +AC_MSG_CHECKING([if architecture needs alignment]) +AC_TRY_RUN([ +#include +#include +int main(int argc, char **argv) +{ + unsigned char test[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }; + signal(SIGBUS, exit); + signal(SIGABRT, exit); + signal(SIGSEGV, exit); + if (*((unsigned int *)(test + 1)) != 0x55443322 && *((unsigned int *)(test + 1)) != 0x22334455) { + return 1; + } + return 0; +}], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + AC_DEFINE(NEED_ALIGN)], + [AC_MSG_RESULT(assuming yes) + AC_DEFINE(NEED_ALIGN)]) + + +# +# EGD +# +AC_ARG_WITH(egd-socket, + [ --with-egd-socket=PATH look for Entropy Gathering Daemon socket at PATH], + [EGD_SOCKET="$withval"], + [EGD_SOCKET="/var/run/egd-pool"] +) +AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET") + + +# +# rdp2vnc +# +vncserverconfig=libvncserver-config +AC_ARG_WITH(libvncserver-config, + [ --with-libvncserver-config=CMD use CMD as libvncserver-config], + [vncserverconfig="$withval"] +) +AC_ARG_WITH(libvncserver, + [ --with-libvncserver make rdp2vnc], + [ + VNCINC=`$vncserverconfig --cflags` + AC_SUBST(VNCINC) + LDVNC=`$vncserverconfig --libs` + AC_SUBST(LDVNC) + VNCLINK=`$vncserverconfig --link` + AC_SUBST(VNCLINK) + RDP2VNCTARGET="rdp2vnc" + AC_SUBST(RDP2VNCTARGET) + ] +) + +# +# sound +# +AC_ARG_WITH(libao, + [ --with-libao=DIR look for libao at DIR/include, DIR/lib], + [ + CFLAGS="$CFLAGS -I$withval/include" + CPPFLAGS="$CPPFLAGS -I$withval/include" + LIBS="$LIBS -L$withval/lib" + rpath="$rpath:$withval/lib" + ] +) + +sound="yes" +AC_ARG_WITH(sound, + [ --with-sound select sound system ("oss", "sgi", "sun" or "libao") ], + [ + sound="$withval" + ]) +if test "$sound" = yes; then + AC_CHECK_HEADER(ao/ao.h, [sound=libao]) + AC_CHECK_HEADER(sys/soundcard.h, [sound=oss]) + AC_CHECK_HEADER(dmedia/audio.h, [sound=sgi]) + AC_CHECK_HEADER(sys/audioio.h, [sound=sun]) +fi +if test "$sound" = no; then + break +elif test "$sound" = oss; then + SOUNDOBJ="rdpsnd.o rdpsnd_oss.o" + AC_DEFINE(WITH_RDPSND) +elif test "$sound" = sgi; then + SOUNDOBJ="rdpsnd.o rdpsnd_sgi.o" + LDFLAGS="$LDFLAGS -laudio" + AC_DEFINE(WITH_RDPSND) +elif test "$sound" = sun; then + SOUNDOBJ="rdpsnd.o rdpsnd_sun.o" + AC_DEFINE(WITH_RDPSND) +elif test "$sound" = libao; then + SOUNDOBJ="rdpsnd.o rdpsnd_libao.o" + LDFLAGS="$LDFLAGS -lao" + AC_DEFINE(WITH_RDPSND) +else + AC_MSG_WARN([sound support disabled]) + AC_MSG_WARN([Currently supported systems are Open Sound System (oss), SGI AL (sgi), Sun/BSD (sun) and libao]) +fi +AC_SUBST(SOUNDOBJ) + +# +# dirfd +# +dnl Find out how to get the file descriptor associated with an open DIR*. +dnl From Jim Meyering + +AC_DEFUN([UTILS_FUNC_DIRFD], +[ + + AC_HEADER_DIRENT + dirfd_headers=' +#if HAVE_DIRENT_H +# include +#else /* not HAVE_DIRENT_H */ +# define dirent direct +# if HAVE_SYS_NDIR_H +# include +# endif /* HAVE_SYS_NDIR_H */ +# if HAVE_SYS_DIR_H +# include +# endif /* HAVE_SYS_DIR_H */ +# if HAVE_NDIR_H +# include +# endif /* HAVE_NDIR_H */ +#endif /* HAVE_DIRENT_H */ +' + AC_CHECK_FUNCS(dirfd) + AC_CHECK_DECLS([dirfd], , , $dirfd_headers) + + AC_CACHE_CHECK([whether dirfd is a macro], + jm_cv_func_dirfd_macro, + [AC_EGREP_CPP([dirent_header_defines_dirfd], [$dirfd_headers +#ifdef dirfd + dirent_header_defines_dirfd +#endif], + jm_cv_func_dirfd_macro=yes, + jm_cv_func_dirfd_macro=no)]) + + # Use the replacement only if we have no function, macro, + # or declaration with that name. + if test $ac_cv_func_dirfd,$ac_cv_have_decl_dirfd,$jm_cv_func_dirfd_macro \ + = no,no,no; then + AC_REPLACE_FUNCS([dirfd]) + AC_CACHE_CHECK( + [how to get the file descriptor associated with an open DIR*], + gl_cv_sys_dir_fd_member_name, + [ + dirfd_save_CFLAGS=$CFLAGS + for ac_expr in d_fd dd_fd; do + + CFLAGS="$CFLAGS -DDIR_FD_MEMBER_NAME=$ac_expr" + AC_TRY_COMPILE( + [$dirfd_headers + ], + [DIR *dir_p = opendir("."); (void) dir_p->DIR_FD_MEMBER_NAME;], + dir_fd_found=yes + ) + CFLAGS=$dirfd_save_CFLAGS + test "$dir_fd_found" = yes && break + done + test "$dir_fd_found" = yes || ac_expr=no_such_member + + gl_cv_sys_dir_fd_member_name=$ac_expr + ] + ) + if test $gl_cv_sys_dir_fd_member_name != no_such_member; then + AC_DEFINE_UNQUOTED(DIR_FD_MEMBER_NAME, + $gl_cv_sys_dir_fd_member_name, + [the name of the file descriptor member of DIR]) + fi + AH_VERBATIM(DIR_TO_FD, + [#ifdef DIR_FD_MEMBER_NAME +# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME) +#else +# define DIR_TO_FD(Dir_p) -1 +#endif +] + ) + fi +]) + +UTILS_FUNC_DIRFD + +# +# iconv +# + +dnl This macros shamelessly stolen from +dnl http://gcc.gnu.org/ml/gcc-bugs/2001-06/msg01398.html. +dnl Written by Bruno Haible. + +AC_DEFUN([UTILS_FUNC_ICONV], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + AC_ARG_WITH([libiconv-prefix], +[ --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib], [ + for dir in `echo "$withval" | tr : ' '`; do + if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi + if test -d $dir/lib; then LDFLAGS="$LDFLAGS -L$dir/lib"; fi + done + ]) + AC_CHECK_HEADER(iconv.h, AC_DEFINE(HAVE_ICONV_H)) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS -liconv" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi + LIBICONV= + if test "$am_cv_lib_iconv" = yes; then + LIBICONV="-liconv" + fi + AC_SUBST(LIBICONV) +]) + +UTILS_FUNC_ICONV +LIBS="$LIBS $LIBICONV" + +# +# socklen_t +# from curl + +dnl Check for socklen_t: historically on BSD it is an int, and in +dnl POSIX 1g it is a type of its own, but some platforms use different +dnl types for the argument to getsockopt, getpeername, etc. So we +dnl have to test to find something that will work. +AC_DEFUN([TYPE_SOCKLEN_T], +[ + AC_CHECK_TYPE([socklen_t], ,[ + AC_MSG_CHECKING([for socklen_t equivalent]) + AC_CACHE_VAL([socklen_t_equiv], + [ + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + socklen_t_equiv= + for arg2 in "struct sockaddr" void; do + for t in int size_t unsigned long "unsigned long"; do + AC_TRY_COMPILE([ + #include + #include + + int getpeername (int, $arg2 *, $t *); + ],[ + $t len; + getpeername(0,0,&len); + ],[ + socklen_t_equiv="$t" + break + ]) + done + done + + if test "x$socklen_t_equiv" = x; then + AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) + fi + ]) + AC_MSG_RESULT($socklen_t_equiv) + AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv, + [type to use in place of socklen_t if not defined])], + [#include +#include ]) +]) + +TYPE_SOCKLEN_T + +# +# statfs stuff +# +AC_CHECK_HEADERS(sys/vfs.h) +AC_CHECK_HEADERS(sys/statvfs.h) +AC_CHECK_HEADERS(sys/statfs.h) +AC_CHECK_HEADERS(sys/param.h) + +mount_includes="\ + $ac_includes_default + #if HAVE_SYS_PARAM_H + # include + #endif + " + +AC_CHECK_HEADERS(sys/mount.h,,,[$mount_includes]) + +################################################# +# these tests are taken from the GNU fileutils package +AC_CHECKING(how to get filesystem space usage) +space=no + +# Test for statvfs64. +if test $space = no; then + # SVR4 + AC_CACHE_CHECK([statvfs64 function (SVR4)], fu_cv_sys_stat_statvfs64, + [AC_TRY_RUN([ +#if defined(HAVE_UNISTD_H) +#include +#endif +#include +#include + main () + { + struct statvfs64 fsd; + exit (statvfs64 (".", &fsd)); + }], + fu_cv_sys_stat_statvfs64=yes, + fu_cv_sys_stat_statvfs64=no, + fu_cv_sys_stat_statvfs64=cross)]) + if test $fu_cv_sys_stat_statvfs64 = yes; then + space=yes + AC_DEFINE(STAT_STATVFS64,1,[Whether statvfs64() is available]) + fi +fi + +# Perform only the link test since it seems there are no variants of the +# statvfs function. This check is more than just AC_CHECK_FUNCS(statvfs) +# because that got a false positive on SCO OSR5. Adding the declaration +# of a `struct statvfs' causes this test to fail (as it should) on such +# systems. That system is reported to work fine with STAT_STATFS4 which +# is what it gets when this test fails. +if test $space = no; then + # SVR4 + AC_CACHE_CHECK([statvfs function (SVR4)], fu_cv_sys_stat_statvfs, + [AC_TRY_LINK([#include +#include ], + [struct statvfs fsd; statvfs (0, &fsd);], + fu_cv_sys_stat_statvfs=yes, + fu_cv_sys_stat_statvfs=no)]) + if test $fu_cv_sys_stat_statvfs = yes; then + space=yes + AC_DEFINE(STAT_STATVFS,1,[Whether statvfs() is available]) + fi +fi + +if test $space = no; then + # DEC Alpha running OSF/1 + AC_MSG_CHECKING([for 3-argument statfs function (DEC OSF/1)]) + AC_CACHE_VAL(fu_cv_sys_stat_statfs3_osf1, + [AC_TRY_RUN([ +#include +#include +#include + main () + { + struct statfs fsd; + fsd.f_fsize = 0; + exit (statfs (".", &fsd, sizeof (struct statfs))); + }], + fu_cv_sys_stat_statfs3_osf1=yes, + fu_cv_sys_stat_statfs3_osf1=no, + fu_cv_sys_stat_statfs3_osf1=no)]) + + +#C_MSG_RESULT($fu_cv_sys_stat_statfs3_osf1) + if test $fu_cv_sys_stat_statfs3_osf1 = yes; then + space=yes + AC_DEFINE(STAT_STATFS3_OSF1,1,[Whether statfs requires 3 arguments]) + fi +fi + +if test $space = no; then +# AIX + AC_MSG_CHECKING([for two-argument statfs with statfs.bsize dnl +member (AIX, 4.3BSD)]) + AC_CACHE_VAL(fu_cv_sys_stat_statfs2_bsize, + [AC_TRY_RUN([ +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif +#ifdef HAVE_SYS_VFS_H +#include +#endif + main () + { + struct statfs fsd; + fsd.f_bsize = 0; + exit (statfs (".", &fsd)); + }], + fu_cv_sys_stat_statfs2_bsize=yes, + fu_cv_sys_stat_statfs2_bsize=no, + fu_cv_sys_stat_statfs2_bsize=no)]) + AC_MSG_RESULT($fu_cv_sys_stat_statfs2_bsize) + if test $fu_cv_sys_stat_statfs2_bsize = yes; then + space=yes + AC_DEFINE(STAT_STATFS2_BSIZE,1,[Whether statfs requires two arguments and struct statfs has bsize property]) + fi +fi + +if test $space = no; then +# SVR3 + AC_MSG_CHECKING([for four-argument statfs (AIX-3.2.5, SVR3)]) + AC_CACHE_VAL(fu_cv_sys_stat_statfs4, + [AC_TRY_RUN([#include +#include + main () + { + struct statfs fsd; + exit (statfs (".", &fsd, sizeof fsd, 0)); + }], + fu_cv_sys_stat_statfs4=yes, + fu_cv_sys_stat_statfs4=no, + fu_cv_sys_stat_statfs4=no)]) + AC_MSG_RESULT($fu_cv_sys_stat_statfs4) + if test $fu_cv_sys_stat_statfs4 = yes; then + space=yes + AC_DEFINE(STAT_STATFS4,1,[Whether statfs requires 4 arguments]) + fi +fi + +if test $space = no; then +# 4.4BSD and NetBSD + AC_MSG_CHECKING([for two-argument statfs with statfs.fsize dnl +member (4.4BSD and NetBSD)]) + AC_CACHE_VAL(fu_cv_sys_stat_statfs2_fsize, + [AC_TRY_RUN([#include +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif + main () + { + struct statfs fsd; + fsd.f_fsize = 0; + exit (statfs (".", &fsd)); + }], + fu_cv_sys_stat_statfs2_fsize=yes, + fu_cv_sys_stat_statfs2_fsize=no, + fu_cv_sys_stat_statfs2_fsize=no)]) + AC_MSG_RESULT($fu_cv_sys_stat_statfs2_fsize) + if test $fu_cv_sys_stat_statfs2_fsize = yes; then + space=yes + AC_DEFINE(STAT_STATFS2_FSIZE,1,[Whether statfs requires 2 arguments and struct statfs has fsize]) + fi +fi + +if test $space = no; then + # Ultrix + AC_MSG_CHECKING([for two-argument statfs with struct fs_data (Ultrix)]) + AC_CACHE_VAL(fu_cv_sys_stat_fs_data, + [AC_TRY_RUN([#include +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif +#ifdef HAVE_SYS_FS_TYPES_H +#include +#endif + main () + { + struct fs_data fsd; + /* Ultrix's statfs returns 1 for success, + 0 for not mounted, -1 for failure. */ + exit (statfs (".", &fsd) != 1); + }], + fu_cv_sys_stat_fs_data=yes, + fu_cv_sys_stat_fs_data=no, + fu_cv_sys_stat_fs_data=no)]) + AC_MSG_RESULT($fu_cv_sys_stat_fs_data) + if test $fu_cv_sys_stat_fs_data = yes; then + space=yes + AC_DEFINE(STAT_STATFS2_FS_DATA,1,[Whether statfs requires 2 arguments and struct fs_data is available]) + fi +fi + + statxfs_includes="\ +$ac_includes_default +#if HAVE_SYS_STATVFS_H +# include +#endif +#if HAVE_SYS_VFS_H +# include +#endif +#if !HAVE_SYS_STATVFS_H && !HAVE_SYS_VFS_H +# if HAVE_SYS_MOUNT_H && HAVE_SYS_PARAM_H +/* NetBSD 1.5.2 needs these, for the declaration of struct statfs. */ +# include +# include +# elif HAVE_NETINET_IN_H && HAVE_NFS_NFS_CLNT_H && HAVE_NFS_VFS_H +/* Ultrix 4.4 needs these for the declaration of struct statfs. */ +# include +# include +# include +# endif +#endif +" + +AC_CHECK_MEMBERS([struct statfs.f_namemax],,,[$statxfs_includes]) +AC_CHECK_MEMBERS([struct statvfs.f_namemax],,,[$statxfs_includes]) +AC_CHECK_MEMBERS([struct statfs.f_namelen],,,[$statxfs_includes]) +AC_CHECK_MEMBERS([struct statvfs.f_namelen],,,[$statxfs_includes]) + +# +# Large file support +# +AC_SYS_LARGEFILE + +# +# mntent +# +AC_CHECK_HEADER(mntent.h, AC_DEFINE(HAVE_MNTENT_H)) +AC_CHECK_FUNCS(setmntent) + +# +# IPv6 +# +AC_ARG_WITH(ipv6, + [ --with-ipv6 enable IPv6-support], + [ + if test $withval != "no"; + then + AC_DEFINE(IPv6,1) + fi + ]) + + +# +# debugging +# +AC_ARG_WITH(debug, + [ --with-debug enable protocol debugging output], + [ + if test $withval != "no"; + then + AC_DEFINE(WITH_DEBUG,1) + fi + ]) + +AC_ARG_WITH(debug-kbd, + [ --with-debug-kbd enable debugging of keyboard handling], + [ + if test $withval != "no"; + then + AC_DEFINE(WITH_DEBUG_KBD,1) + fi + ]) + +AC_ARG_WITH(debug-rdp5, + [ --with-debug-rdp5 enable debugging of RDP5 code], + [ + if test $withval != "no"; + then + AC_DEFINE(WITH_DEBUG_RDP5,1) + fi + ]) + +AC_ARG_WITH(debug-clipboard, + [ --with-debug-clipboard enable debugging of clipboard code], + [ + if test $withval != "no"; + then + AC_DEFINE(WITH_DEBUG_CLIPBOARD,1) + fi + ]) + +AC_ARG_WITH(debug-channel, + [ --with-debug-channel enable debugging of virtual channel code], + [ + if test $withval != "no"; + then + AC_DEFINE(WITH_DEBUG_CHANNEL,1) + fi + ]) + + +# +# target-specific stuff +# +# strip leading colon from rpath +rpath=`echo $rpath |sed 's/^://'` +AC_CANONICAL_HOST +case "$host" in +*-*-solaris*) + LDFLAGS="$LDFLAGS -R$rpath" + ;; +*-dec-osf*) + LDFLAGS="$LDFLAGS -Wl,-rpath,$rpath" + ;; +*-*-hpux*) + CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED" + ;; +*-*-irix6.5*) + LIBS="$LIBS -L$ssldir/lib32 -lcrypto" + CFLAGS="$CFLAGS -D__SGI_IRIX__" + ;; +esac + + +AC_OUTPUT(Makefile) + +dnl Local Variables: +dnl comment-start: "dnl " +dnl comment-end: "" +dnl comment-start-skip: "\\bdnl\\b\\s *" +dnl compile-command: "autoconf" +dnl End: diff --git a/rosapps/applications/net/tsclient/rdesktop/constants.h b/rosapps/applications/net/tsclient/rdesktop/constants.h new file mode 100644 index 00000000000..fe940cca3c1 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/constants.h @@ -0,0 +1,430 @@ +/* + rdesktop: A Remote Desktop Protocol client. + Miscellaneous protocol constants + Copyright (C) Matthew Chapman 1999-2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +/* TCP port for Remote Desktop Protocol */ +#define TCP_PORT_RDP 3389 + +#define DEFAULT_CODEPAGE "UTF-8" +#define WINDOWS_CODEPAGE "UTF-16LE" + +/* ISO PDU codes */ +enum ISO_PDU_CODE +{ + ISO_PDU_CR = 0xE0, /* Connection Request */ + ISO_PDU_CC = 0xD0, /* Connection Confirm */ + ISO_PDU_DR = 0x80, /* Disconnect Request */ + ISO_PDU_DT = 0xF0, /* Data */ + ISO_PDU_ER = 0x70 /* Error */ +}; + +/* MCS PDU codes */ +enum MCS_PDU_TYPE +{ + MCS_EDRQ = 1, /* Erect Domain Request */ + MCS_DPUM = 8, /* Disconnect Provider Ultimatum */ + MCS_AURQ = 10, /* Attach User Request */ + MCS_AUCF = 11, /* Attach User Confirm */ + MCS_CJRQ = 14, /* Channel Join Request */ + MCS_CJCF = 15, /* Channel Join Confirm */ + MCS_SDRQ = 25, /* Send Data Request */ + MCS_SDIN = 26 /* Send Data Indication */ +}; + +#define MCS_CONNECT_INITIAL 0x7f65 +#define MCS_CONNECT_RESPONSE 0x7f66 + +#define BER_TAG_BOOLEAN 1 +#define BER_TAG_INTEGER 2 +#define BER_TAG_OCTET_STRING 4 +#define BER_TAG_RESULT 10 +#define MCS_TAG_DOMAIN_PARAMS 0x30 + +#define MCS_GLOBAL_CHANNEL 1003 +#define MCS_USERCHANNEL_BASE 1001 + +/* RDP secure transport constants */ +#define SEC_RANDOM_SIZE 32 +#define SEC_MODULUS_SIZE 64 +#define SEC_MAX_MODULUS_SIZE 256 +#define SEC_PADDING_SIZE 8 +#define SEC_EXPONENT_SIZE 4 + +#define SEC_CLIENT_RANDOM 0x0001 +#define SEC_ENCRYPT 0x0008 +#define SEC_LOGON_INFO 0x0040 +#define SEC_LICENCE_NEG 0x0080 +#define SEC_REDIRECT_ENCRYPT 0x0C00 + +#define SEC_TAG_SRV_INFO 0x0c01 +#define SEC_TAG_SRV_CRYPT 0x0c02 +#define SEC_TAG_SRV_CHANNELS 0x0c03 + +#define SEC_TAG_CLI_INFO 0xc001 +#define SEC_TAG_CLI_CRYPT 0xc002 +#define SEC_TAG_CLI_CHANNELS 0xc003 +#define SEC_TAG_CLI_4 0xc004 + +#define SEC_TAG_PUBKEY 0x0006 +#define SEC_TAG_KEYSIG 0x0008 + +#define SEC_RSA_MAGIC 0x31415352 /* RSA1 */ + +/* RDP licensing constants */ +#define LICENCE_TOKEN_SIZE 10 +#define LICENCE_HWID_SIZE 20 +#define LICENCE_SIGNATURE_SIZE 16 + +#define LICENCE_TAG_DEMAND 0x01 +#define LICENCE_TAG_AUTHREQ 0x02 +#define LICENCE_TAG_ISSUE 0x03 +#define LICENCE_TAG_REISSUE 0x04 +#define LICENCE_TAG_PRESENT 0x12 +#define LICENCE_TAG_REQUEST 0x13 +#define LICENCE_TAG_AUTHRESP 0x15 +#define LICENCE_TAG_RESULT 0xff + +#define LICENCE_TAG_USER 0x000f +#define LICENCE_TAG_HOST 0x0010 + +/* RDP PDU codes */ +enum RDP_PDU_TYPE +{ + RDP_PDU_DEMAND_ACTIVE = 1, + RDP_PDU_CONFIRM_ACTIVE = 3, + RDP_PDU_REDIRECT = 4, /* MS Server 2003 Session Redirect */ + RDP_PDU_DEACTIVATE = 6, + RDP_PDU_DATA = 7 +}; + +enum RDP_DATA_PDU_TYPE +{ + RDP_DATA_PDU_UPDATE = 2, + RDP_DATA_PDU_CONTROL = 20, + RDP_DATA_PDU_POINTER = 27, + RDP_DATA_PDU_INPUT = 28, + RDP_DATA_PDU_SYNCHRONISE = 31, + RDP_DATA_PDU_BELL = 34, + RDP_DATA_PDU_CLIENT_WINDOW_STATUS = 35, + RDP_DATA_PDU_LOGON = 38, + RDP_DATA_PDU_FONT2 = 39, + RDP_DATA_PDU_KEYBOARD_INDICATORS = 41, + RDP_DATA_PDU_DISCONNECT = 47 +}; + +enum RDP_CONTROL_PDU_TYPE +{ + RDP_CTL_REQUEST_CONTROL = 1, + RDP_CTL_GRANT_CONTROL = 2, + RDP_CTL_DETACH = 3, + RDP_CTL_COOPERATE = 4 +}; + +enum RDP_UPDATE_PDU_TYPE +{ + RDP_UPDATE_ORDERS = 0, + RDP_UPDATE_BITMAP = 1, + RDP_UPDATE_PALETTE = 2, + RDP_UPDATE_SYNCHRONIZE = 3 +}; + +enum RDP_POINTER_PDU_TYPE +{ + RDP_POINTER_SYSTEM = 1, + RDP_POINTER_MOVE = 3, + RDP_POINTER_COLOR = 6, + RDP_POINTER_CACHED = 7 +}; + +enum RDP_SYSTEM_POINTER_TYPE +{ + RDP_NULL_POINTER = 0, + RDP_DEFAULT_POINTER = 0x7F00 +}; + +enum RDP_INPUT_DEVICE +{ + RDP_INPUT_SYNCHRONIZE = 0, + RDP_INPUT_CODEPOINT = 1, + RDP_INPUT_VIRTKEY = 2, + RDP_INPUT_SCANCODE = 4, + RDP_INPUT_MOUSE = 0x8001 +}; + +/* Device flags */ +#define KBD_FLAG_RIGHT 0x0001 +#define KBD_FLAG_EXT 0x0100 +#define KBD_FLAG_QUIET 0x1000 +#define KBD_FLAG_DOWN 0x4000 +#define KBD_FLAG_UP 0x8000 + +/* These are for synchronization; not for keystrokes */ +#define KBD_FLAG_SCROLL 0x0001 +#define KBD_FLAG_NUMLOCK 0x0002 +#define KBD_FLAG_CAPITAL 0x0004 + +/* See T.128 */ +#define RDP_KEYPRESS 0 +#define RDP_KEYRELEASE (KBD_FLAG_DOWN | KBD_FLAG_UP) + +#define MOUSE_FLAG_MOVE 0x0800 +#define MOUSE_FLAG_BUTTON1 0x1000 +#define MOUSE_FLAG_BUTTON2 0x2000 +#define MOUSE_FLAG_BUTTON3 0x4000 +#define MOUSE_FLAG_BUTTON4 0x0280 +#define MOUSE_FLAG_BUTTON5 0x0380 +#define MOUSE_FLAG_DOWN 0x8000 + +/* Raster operation masks */ +#define ROP2_S(rop3) (rop3 & 0xf) +#define ROP2_P(rop3) ((rop3 & 0x3) | ((rop3 & 0x30) >> 2)) + +#define ROP2_COPY 0xc +#define ROP2_XOR 0x6 +#define ROP2_AND 0x8 +#define ROP2_NXOR 0x9 +#define ROP2_OR 0xe + +#define MIX_TRANSPARENT 0 +#define MIX_OPAQUE 1 + +#define TEXT2_VERTICAL 0x04 +#define TEXT2_IMPLICIT_X 0x20 + +#define ALTERNATE 1 +#define WINDING 2 + +/* RDP bitmap cache (version 2) constants */ +#define BMPCACHE2_C0_CELLS 0x78 +#define BMPCACHE2_C1_CELLS 0x78 +#define BMPCACHE2_C2_CELLS 0x150 +#define BMPCACHE2_NUM_PSTCELLS 0x9f6 + +#define PDU_FLAG_FIRST 0x01 +#define PDU_FLAG_LAST 0x02 + +/* RDP capabilities */ +#define RDP_CAPSET_GENERAL 1 /* Maps to generalCapabilitySet in T.128 page 138 */ +#define RDP_CAPLEN_GENERAL 0x18 +#define OS_MAJOR_TYPE_UNIX 4 +#define OS_MINOR_TYPE_XSERVER 7 + +#define RDP_CAPSET_BITMAP 2 +#define RDP_CAPLEN_BITMAP 0x1C + +#define RDP_CAPSET_ORDER 3 +#define RDP_CAPLEN_ORDER 0x58 +#define ORDER_CAP_NEGOTIATE 2 +#define ORDER_CAP_NOSUPPORT 4 + +#define RDP_CAPSET_BMPCACHE 4 +#define RDP_CAPLEN_BMPCACHE 0x28 + +#define RDP_CAPSET_CONTROL 5 +#define RDP_CAPLEN_CONTROL 0x0C + +#define RDP_CAPSET_ACTIVATE 7 +#define RDP_CAPLEN_ACTIVATE 0x0C + +#define RDP_CAPSET_POINTER 8 +#define RDP_CAPLEN_POINTER 0x08 + +#define RDP_CAPSET_SHARE 9 +#define RDP_CAPLEN_SHARE 0x08 + +#define RDP_CAPSET_COLCACHE 10 +#define RDP_CAPLEN_COLCACHE 0x08 + +#define RDP_CAPSET_BMPCACHE2 19 +#define RDP_CAPLEN_BMPCACHE2 0x28 +#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31) + +#define RDP_SOURCE "MSTSC" + +/* Logon flags */ +#define RDP_LOGON_AUTO 0x0008 +#define RDP_LOGON_NORMAL 0x0033 +#define RDP_LOGON_COMPRESSION 0x0080 /* mppc compression with 8kB histroy buffer */ +#define RDP_LOGON_BLOB 0x0100 +#define RDP_LOGON_COMPRESSION2 0x0200 /* rdp5 mppc compression with 64kB history buffer */ +#define RDP_LOGON_LEAVE_AUDIO 0x2000 + +#define RDP5_DISABLE_NOTHING 0x00 +#define RDP5_NO_WALLPAPER 0x01 +#define RDP5_NO_FULLWINDOWDRAG 0x02 +#define RDP5_NO_MENUANIMATIONS 0x04 +#define RDP5_NO_THEMING 0x08 +#define RDP5_NO_CURSOR_SHADOW 0x20 +#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */ + +/* compression types */ +#define RDP_MPPC_BIG 0x01 +#define RDP_MPPC_COMPRESSED 0x20 +#define RDP_MPPC_RESET 0x40 +#define RDP_MPPC_FLUSH 0x80 +#define RDP_MPPC_DICT_SIZE 65536 + +#define RDP5_COMPRESSED 0x80 + +/* Keymap flags */ +#define MapRightShiftMask (1<<0) +#define MapLeftShiftMask (1<<1) +#define MapShiftMask (MapRightShiftMask | MapLeftShiftMask) + +#define MapRightAltMask (1<<2) +#define MapLeftAltMask (1<<3) +#define MapAltGrMask MapRightAltMask + +#define MapRightCtrlMask (1<<4) +#define MapLeftCtrlMask (1<<5) +#define MapCtrlMask (MapRightCtrlMask | MapLeftCtrlMask) + +#define MapRightWinMask (1<<6) +#define MapLeftWinMask (1<<7) +#define MapWinMask (MapRightWinMask | MapLeftWinMask) + +#define MapNumLockMask (1<<8) +#define MapCapsLockMask (1<<9) + +#define MapLocalStateMask (1<<10) + +#define MapInhibitMask (1<<11) + +#define MASK_ADD_BITS(var, mask) (var |= mask) +#define MASK_REMOVE_BITS(var, mask) (var &= ~mask) +#define MASK_HAS_BITS(var, mask) ((var & mask)>0) +#define MASK_CHANGE_BIT(var, mask, active) (var = ((var & ~mask) | (active ? mask : 0))) + +/* Clipboard constants, "borrowed" from GCC system headers in + the w32 cross compiler */ + +#if 0 +#define CF_TEXT 1 +#define CF_BITMAP 2 +#define CF_METAFILEPICT 3 +#define CF_SYLK 4 +#define CF_DIF 5 +#define CF_TIFF 6 +#define CF_OEMTEXT 7 +#define CF_DIB 8 +#define CF_PALETTE 9 +#define CF_PENDATA 10 +#define CF_RIFF 11 +#define CF_WAVE 12 +#define CF_UNICODETEXT 13 +#define CF_ENHMETAFILE 14 +#define CF_HDROP 15 +#define CF_LOCALE 16 +#define CF_MAX 17 +#define CF_OWNERDISPLAY 128 +#define CF_DSPTEXT 129 +#define CF_DSPBITMAP 130 +#define CF_DSPMETAFILEPICT 131 +#define CF_DSPENHMETAFILE 142 +#define CF_PRIVATEFIRST 512 +#define CF_PRIVATELAST 767 +#define CF_GDIOBJFIRST 768 +#define CF_GDIOBJLAST 1023 + +/* Sound format constants */ +#define WAVE_FORMAT_PCM 1 +#define WAVE_FORMAT_ADPCM 2 +#define WAVE_FORMAT_ALAW 6 +#define WAVE_FORMAT_MULAW 7 + +/* Virtual channel options */ +#define CHANNEL_OPTION_INITIALIZED 0x80000000 +#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000 +#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000 +#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000 + +/* NT status codes for RDPDR */ +#define STATUS_SUCCESS 0x00000000 +#define STATUS_NOT_IMPLEMENTED 0x00000001 +#define STATUS_PENDING 0x00000103 + +#define STATUS_NO_MORE_FILES 0x80000006 +#define STATUS_DEVICE_PAPER_EMPTY 0x8000000e +#define STATUS_DEVICE_POWERED_OFF 0x8000000f +#define STATUS_DEVICE_OFF_LINE 0x80000010 +#define STATUS_DEVICE_BUSY 0x80000011 + +#define STATUS_INVALID_HANDLE 0xc0000008 +#define STATUS_INVALID_PARAMETER 0xc000000d +#define STATUS_NO_SUCH_FILE 0xc000000f +#define STATUS_INVALID_DEVICE_REQUEST 0xc0000010 +#define STATUS_ACCESS_DENIED 0xc0000022 +#define STATUS_OBJECT_NAME_COLLISION 0xc0000035 +#define STATUS_DISK_FULL 0xc000007f +#define STATUS_FILE_IS_A_DIRECTORY 0xc00000ba +#define STATUS_NOT_SUPPORTED 0xc00000bb +#define STATUS_TIMEOUT 0xc0000102 +#define STATUS_NOTIFY_ENUM_DIR 0xc000010c +#define STATUS_CANCELLED 0xc0000120 + +/* RDPDR constants */ +#define RDPDR_MAX_DEVICES 0x10 +#define DEVICE_TYPE_SERIAL 0x01 +#define DEVICE_TYPE_PARALLEL 0x02 +#define DEVICE_TYPE_PRINTER 0x04 +#define DEVICE_TYPE_DISK 0x08 +#define DEVICE_TYPE_SCARD 0x20 + +#define FILE_DIRECTORY_FILE 0x00000001 +#define FILE_NON_DIRECTORY_FILE 0x00000040 +#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 +#define FILE_DELETE_ON_CLOSE 0x00001000 +#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 + +/* RDP5 disconnect PDU */ +#define exDiscReasonNoInfo 0x0000 +#define exDiscReasonAPIInitiatedDisconnect 0x0001 +#define exDiscReasonAPIInitiatedLogoff 0x0002 +#define exDiscReasonServerIdleTimeout 0x0003 +#define exDiscReasonServerLogonTimeout 0x0004 +#define exDiscReasonReplacedByOtherConnection 0x0005 +#define exDiscReasonOutOfMemory 0x0006 +#define exDiscReasonServerDeniedConnection 0x0007 +#define exDiscReasonServerDeniedConnectionFips 0x0008 +#define exDiscReasonLicenseInternal 0x0100 +#define exDiscReasonLicenseNoLicenseServer 0x0101 +#define exDiscReasonLicenseNoLicense 0x0102 +#define exDiscReasonLicenseErrClientMsg 0x0103 +#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104 +#define exDiscReasonLicenseErrClientLicense 0x0105 +#define exDiscReasonLicenseCantFinishProtocol 0x0106 +#define exDiscReasonLicenseClientEndedProtocol 0x0107 +#define exDiscReasonLicenseErrClientEncryption 0x0108 +#define exDiscReasonLicenseCantUpgradeLicense 0x0109 +#define exDiscReasonLicenseNoRemoteConnections 0x010a +#endif + +#if 0 +/* SeamlessRDP constants */ +#define SEAMLESSRDP_NOTYETMAPPED -1 +#define SEAMLESSRDP_NORMAL 0 +#define SEAMLESSRDP_MINIMIZED 1 +#define SEAMLESSRDP_MAXIMIZED 2 +#define SEAMLESSRDP_POSITION_TIMER 200000 + +#define SEAMLESSRDP_CREATE_MODAL 0x0001 + +#define SEAMLESSRDP_HELLO_RECONNECT 0x0001 +#define SEAMLESSRDP_HELLO_HIDDEN 0x0002 +#endif diff --git a/rosapps/applications/net/tsclient/rdesktop/disk.c b/rosapps/applications/net/tsclient/rdesktop/disk.c new file mode 100644 index 00000000000..22f4114291e --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/disk.c @@ -0,0 +1,1246 @@ +/* -*- c-basic-offset: 8 -*- + rdesktop: A Remote Desktop Protocol client. + Disk Redirection + Copyright (C) Jeroen Meijer 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "disk.h" + +#include +#include +#include +#include /* open, close */ +#include /* opendir, closedir, readdir */ +#include +#include /* errno */ +#include + +#include +#include /* ctime */ + +#if (defined(HAVE_DIRFD) || (HAVE_DECL_DIRFD == 1)) +#define DIRFD(a) (dirfd(a)) +#else +#define DIRFD(a) ((a)->DIR_FD_MEMBER_NAME) +#endif + +/* TODO: Fix mntent-handling for solaris + * #include */ +#if (defined(HAVE_MNTENT_H) && defined(HAVE_SETMNTENT)) +#include +#define MNTENT_PATH "/etc/mtab" +#define USE_SETMNTENT +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#ifdef HAVE_SYS_STATFS_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_SYS_MOUNT_H +#include +#endif + +#include "rdesktop.h" + +#ifdef STAT_STATFS3_OSF1 +#define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf))) +#define STATFS_T statfs +#define USE_STATFS +#endif + +#ifdef STAT_STATVFS +#define STATFS_FN(path, buf) (statvfs(path,buf)) +#define STATFS_T statvfs +#define USE_STATVFS +#endif + +#ifdef STAT_STATVFS64 +#define STATFS_FN(path, buf) (statvfs64(path,buf)) +#define STATFS_T statvfs64 +#define USE_STATVFS +#endif + +#if (defined(STAT_STATFS2_FS_DATA) || defined(STAT_STATFS2_BSIZE) || defined(STAT_STATFS2_FSIZE)) +#define STATFS_FN(path, buf) (statfs(path,buf)) +#define STATFS_T statfs +#define USE_STATFS +#endif + +#ifdef STAT_STATFS4 +#define STATFS_FN(path, buf) (statfs(path,buf,sizeof(buf),0)) +#define STATFS_T statfs +#define USE_STATFS +#endif + +#if ((defined(USE_STATFS) && defined(HAVE_STRUCT_STATFS_F_NAMEMAX)) || (defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_NAMEMAX))) +#define F_NAMELEN(buf) ((buf).f_namemax) +#endif + +#if ((defined(USE_STATFS) && defined(HAVE_STRUCT_STATFS_F_NAMELEN)) || (defined(USE_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_NAMELEN))) +#define F_NAMELEN(buf) ((buf).f_namelen) +#endif + +#ifndef F_NAMELEN +#define F_NAMELEN(buf) (255) +#endif + +/* Dummy statfs fallback */ +#ifndef STATFS_T +struct dummy_statfs_t +{ + long f_bfree; + long f_bsize; + long f_blocks; + int f_namelen; + int f_namemax; +}; + +static int +dummy_statfs(struct dummy_statfs_t *buf) +{ + buf->f_blocks = 262144; + buf->f_bfree = 131072; + buf->f_bsize = 512; + buf->f_namelen = 255; + buf->f_namemax = 255; + + return 0; +} + +#define STATFS_T dummy_statfs_t +#define STATFS_FN(path,buf) (dummy_statfs(buf)) +#endif + +typedef struct +{ + char name[PATH_MAX]; + char label[PATH_MAX]; + unsigned long serial; + char type[PATH_MAX]; +} FsInfoType; + +static NTSTATUS NotifyInfo(RDPCLIENT * This, NTHANDLE handle, uint32 info_class, NOTIFY * p); + +static time_t +get_create_time(struct stat *st) +{ + time_t ret, ret1; + + ret = MIN(st->st_ctime, st->st_mtime); + ret1 = MIN(ret, st->st_atime); + + if (ret1 != (time_t) 0) + return ret1; + + return ret; +} + +/* Convert seconds since 1970 to a filetime */ +static void +seconds_since_1970_to_filetime(time_t seconds, uint32 * high, uint32 * low) +{ + unsigned long long ticks; + + ticks = (seconds + 11644473600LL) * 10000000; + *low = (uint32) ticks; + *high = (uint32) (ticks >> 32); +} + +/* Convert seconds since 1970 back to filetime */ +static time_t +convert_1970_to_filetime(uint32 high, uint32 low) +{ + unsigned long long ticks; + time_t val; + + ticks = low + (((unsigned long long) high) << 32); + ticks /= 10000000; + ticks -= 11644473600LL; + + val = (time_t) ticks; + return (val); + +} + +/* A wrapper for ftruncate which supports growing files, even if the + native ftruncate doesn't. This is needed on Linux FAT filesystems, + for example. */ +static int +ftruncate_growable(int fd, off_t length) +{ + int ret; + off_t pos; + static const char zero = 0; + + /* Try the simple method first */ + if ((ret = ftruncate(fd, length)) != -1) + { + return ret; + } + + /* + * Some kind of error. Perhaps we were trying to grow. Retry + * in a safe way. + */ + + /* Get current position */ + if ((pos = lseek(fd, 0, SEEK_CUR)) == -1) + { + perror("lseek"); + return -1; + } + + /* Seek to new size */ + if (lseek(fd, length, SEEK_SET) == -1) + { + perror("lseek"); + return -1; + } + + /* Write a zero */ + if (write(fd, &zero, 1) == -1) + { + perror("write"); + return -1; + } + + /* Truncate. This shouldn't fail. */ + if (ftruncate(fd, length) == -1) + { + perror("ftruncate"); + return -1; + } + + /* Restore position */ + if (lseek(fd, pos, SEEK_SET) == -1) + { + perror("lseek"); + return -1; + } + + return 0; +} + +/* Just like open(2), but if a open with O_EXCL fails, retry with + GUARDED semantics. This might be necessary because some filesystems + (such as NFS filesystems mounted from a unfsd server) doesn't + support O_EXCL. GUARDED semantics are subject to race conditions, + but we can live with that. +*/ +static int +open_weak_exclusive(const char *pathname, int flags, mode_t mode) +{ + int ret; + struct stat statbuf; + + ret = open(pathname, flags, mode); + if (ret != -1 || !(flags & O_EXCL)) + { + /* Success, or not using O_EXCL */ + return ret; + } + + /* An error occured, and we are using O_EXCL. In case the FS + doesn't support O_EXCL, some kind of error will be + returned. Unfortunately, we don't know which one. Linux + 2.6.8 seems to return 524, but I cannot find a documented + #define for this case. So, we'll return only on errors that + we know aren't related to O_EXCL. */ + switch (errno) + { + case EACCES: + case EEXIST: + case EINTR: + case EISDIR: + case ELOOP: + case ENAMETOOLONG: + case ENOENT: + case ENOTDIR: + return ret; + } + + /* Retry with GUARDED semantics */ + if (stat(pathname, &statbuf) != -1) + { + /* File exists */ + errno = EEXIST; + return -1; + } + else + { + return open(pathname, flags & ~O_EXCL, mode); + } +} + +/* Enumeration of devices from rdesktop.c */ +/* returns numer of units found and initialized. */ +/* optarg looks like ':h=/mnt/floppy,b=/mnt/usbdevice1' */ +/* when it arrives to this function. */ +int +disk_enum_devices(RDPCLIENT * This, uint32 * id, char *optarg) +{ + char *pos = optarg; + char *pos2; + int count = 0; + + /* skip the first colon */ + optarg++; + while ((pos = next_arg(optarg, ',')) && *id < RDPDR_MAX_DEVICES) + { + pos2 = next_arg(optarg, '='); + + strncpy(This->rdpdr_device[*id].name, optarg, sizeof(This->rdpdr_device[*id].name) - 1); + if (strlen(optarg) > (sizeof(This->rdpdr_device[*id].name) - 1)) + fprintf(stderr, "share name %s truncated to %s\n", optarg, + This->rdpdr_device[*id].name); + + This->rdpdr_device[*id].local_path = (char *) xmalloc(strlen(pos2) + 1); + strcpy(This->rdpdr_device[*id].local_path, pos2); + This->rdpdr_device[*id].device_type = DEVICE_TYPE_DISK; + count++; + (*id)++; + + optarg = pos; + } + return count; +} + +/* Opens or creates a file or directory */ +static NTSTATUS +disk_create(RDPCLIENT * This, uint32 device_id, uint32 accessmask, uint32 sharemode, uint32 create_disposition, + uint32 flags_and_attributes, char *filename, NTHANDLE * phandle) +{ + NTHANDLE handle; + DIR *dirp; + int flags, mode; + char path[PATH_MAX]; + struct stat filestat; + + handle = 0; + dirp = NULL; + flags = 0; + mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + + if (*filename && filename[strlen(filename) - 1] == '/') + filename[strlen(filename) - 1] = 0; + sprintf(path, "%s%s", This->rdpdr_device[device_id].local_path, filename); + + switch (create_disposition) + { + case CREATE_ALWAYS: + + /* Delete existing file/link. */ + unlink(path); + flags |= O_CREAT; + break; + + case CREATE_NEW: + + /* If the file already exists, then fail. */ + flags |= O_CREAT | O_EXCL; + break; + + case OPEN_ALWAYS: + + /* Create if not already exists. */ + flags |= O_CREAT; + break; + + case OPEN_EXISTING: + + /* Default behaviour */ + break; + + case TRUNCATE_EXISTING: + + /* If the file does not exist, then fail. */ + flags |= O_TRUNC; + break; + } + + /*printf("Open: \"%s\" flags: %X, accessmask: %X sharemode: %X create disp: %X\n", path, flags_and_attributes, accessmask, sharemode, create_disposition); */ + + /* Get information about file and set that flag ourselfs */ + if ((stat(path, &filestat) == 0) && (S_ISDIR(filestat.st_mode))) + { + if (flags_and_attributes & FILE_NON_DIRECTORY_FILE) + return STATUS_FILE_IS_A_DIRECTORY; + else + flags_and_attributes |= FILE_DIRECTORY_FILE; + } + + if (flags_and_attributes & FILE_DIRECTORY_FILE) + { + if (flags & O_CREAT) + { + mkdir(path, mode); + } + + dirp = opendir(path); + if (!dirp) + { + switch (errno) + { + case EACCES: + + return STATUS_ACCESS_DENIED; + + case ENOENT: + + return STATUS_NO_SUCH_FILE; + + default: + + perror("opendir"); + return STATUS_NO_SUCH_FILE; + } + } + handle = DIRFD(dirp); + } + else + { + + if (accessmask & GENERIC_ALL + || (accessmask & GENERIC_READ && accessmask & GENERIC_WRITE)) + { + flags |= O_RDWR; + } + else if ((accessmask & GENERIC_WRITE) && !(accessmask & GENERIC_READ)) + { + flags |= O_WRONLY; + } + else + { + flags |= O_RDONLY; + } + + handle = open_weak_exclusive(path, flags, mode); + if (handle == -1) + { + switch (errno) + { + case EISDIR: + + return STATUS_FILE_IS_A_DIRECTORY; + + case EACCES: + + return STATUS_ACCESS_DENIED; + + case ENOENT: + + return STATUS_NO_SUCH_FILE; + case EEXIST: + + return STATUS_OBJECT_NAME_COLLISION; + default: + + perror("open"); + return STATUS_NO_SUCH_FILE; + } + } + + /* all read and writes of files should be non blocking */ + if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1) + perror("fcntl"); + } + + if (handle >= MAX_OPEN_FILES) + { + error("Maximum number of open files (%s) reached. Increase MAX_OPEN_FILES!\n", + handle); + exit(1); + } + + if (dirp) + This->fileinfo[handle].pdir = dirp; + else + This->fileinfo[handle].pdir = NULL; + + This->fileinfo[handle].device_id = device_id; + This->fileinfo[handle].flags_and_attributes = flags_and_attributes; + This->fileinfo[handle].accessmask = accessmask; + strncpy(This->fileinfo[handle].path, path, PATH_MAX - 1); + This->fileinfo[handle].delete_on_close = False; + This->notify_stamp = True; + + *phandle = handle; + return STATUS_SUCCESS; +} + +static NTSTATUS +disk_close(RDPCLIENT * This, NTHANDLE handle) +{ + struct fileinfo *pfinfo; + + pfinfo = &(This->fileinfo[handle]); + + This->notify_stamp = True; + + rdpdr_abort_io(This, handle, 0, STATUS_CANCELLED); + + if (pfinfo->pdir) + { + if (closedir(pfinfo->pdir) < 0) + { + perror("closedir"); + return STATUS_INVALID_HANDLE; + } + + if (pfinfo->delete_on_close) + if (rmdir(pfinfo->path) < 0) + { + perror(pfinfo->path); + return STATUS_ACCESS_DENIED; + } + pfinfo->delete_on_close = False; + } + else + { + if (close(handle) < 0) + { + perror("close"); + return STATUS_INVALID_HANDLE; + } + if (pfinfo->delete_on_close) + if (unlink(pfinfo->path) < 0) + { + perror(pfinfo->path); + return STATUS_ACCESS_DENIED; + } + + pfinfo->delete_on_close = False; + } + + return STATUS_SUCCESS; +} + +static NTSTATUS +disk_read(RDPCLIENT * This, NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) +{ + int n; + +#if 0 + /* browsing dir ???? */ + /* each request is 24 bytes */ + if (This->fileinfo[handle].flags_and_attributes & FILE_DIRECTORY_FILE) + { + *result = 0; + return STATUS_SUCCESS; + } +#endif + + lseek(handle, offset, SEEK_SET); + + n = read(handle, data, length); + + if (n < 0) + { + *result = 0; + switch (errno) + { + case EISDIR: + /* Implement 24 Byte directory read ?? + with STATUS_NOT_IMPLEMENTED server doesn't read again */ + /* return STATUS_FILE_IS_A_DIRECTORY; */ + return STATUS_NOT_IMPLEMENTED; + default: + perror("read"); + return STATUS_INVALID_PARAMETER; + } + } + + *result = n; + + return STATUS_SUCCESS; +} + +static NTSTATUS +disk_write(RDPCLIENT * This, NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) +{ + int n; + + lseek(handle, offset, SEEK_SET); + + n = write(handle, data, length); + + if (n < 0) + { + perror("write"); + *result = 0; + switch (errno) + { + case ENOSPC: + return STATUS_DISK_FULL; + default: + return STATUS_ACCESS_DENIED; + } + } + + *result = n; + + return STATUS_SUCCESS; +} + +NTSTATUS +disk_query_information(RDPCLIENT * This, NTHANDLE handle, uint32 info_class, STREAM out) +{ + uint32 file_attributes, ft_high, ft_low; + struct stat filestat; + char *path, *filename; + + path = This->fileinfo[handle].path; + + /* Get information about file */ + if (fstat(handle, &filestat) != 0) + { + perror("stat"); + out_uint8(out, 0); + return STATUS_ACCESS_DENIED; + } + + /* Set file attributes */ + file_attributes = 0; + if (S_ISDIR(filestat.st_mode)) + file_attributes |= FILE_ATTRIBUTE_DIRECTORY; + + filename = 1 + strrchr(path, '/'); + if (filename && filename[0] == '.') + file_attributes |= FILE_ATTRIBUTE_HIDDEN; + + if (!file_attributes) + file_attributes |= FILE_ATTRIBUTE_NORMAL; + + if (!(filestat.st_mode & S_IWUSR)) + file_attributes |= FILE_ATTRIBUTE_READONLY; + + /* Return requested data */ + switch (info_class) + { + case FileBasicInformation: + seconds_since_1970_to_filetime(get_create_time(&filestat), &ft_high, + &ft_low); + out_uint32_le(out, ft_low); /* create_access_time */ + out_uint32_le(out, ft_high); + + seconds_since_1970_to_filetime(filestat.st_atime, &ft_high, &ft_low); + out_uint32_le(out, ft_low); /* last_access_time */ + out_uint32_le(out, ft_high); + + seconds_since_1970_to_filetime(filestat.st_mtime, &ft_high, &ft_low); + out_uint32_le(out, ft_low); /* last_write_time */ + out_uint32_le(out, ft_high); + + seconds_since_1970_to_filetime(filestat.st_ctime, &ft_high, &ft_low); + out_uint32_le(out, ft_low); /* last_change_time */ + out_uint32_le(out, ft_high); + + out_uint32_le(out, file_attributes); + break; + + case FileStandardInformation: + + out_uint32_le(out, filestat.st_size); /* Allocation size */ + out_uint32_le(out, 0); + out_uint32_le(out, filestat.st_size); /* End of file */ + out_uint32_le(out, 0); + out_uint32_le(out, filestat.st_nlink); /* Number of links */ + out_uint8(out, 0); /* Delete pending */ + out_uint8(out, S_ISDIR(filestat.st_mode) ? 1 : 0); /* Directory */ + break; + + case FileObjectIdInformation: + + out_uint32_le(out, file_attributes); /* File Attributes */ + out_uint32_le(out, 0); /* Reparse Tag */ + break; + + default: + + unimpl("IRP Query (File) Information class: 0x%x\n", info_class); + return STATUS_INVALID_PARAMETER; + } + return STATUS_SUCCESS; +} + +NTSTATUS +disk_set_information(RDPCLIENT * This, NTHANDLE handle, uint32 info_class, STREAM in, STREAM out) +{ + uint32 length, file_attributes, ft_high, ft_low, delete_on_close; + char newname[PATH_MAX], fullpath[PATH_MAX]; + struct fileinfo *pfinfo; + int mode; + struct stat filestat; + time_t write_time, change_time, access_time, mod_time; + struct utimbuf tvs; + struct STATFS_T stat_fs; + + pfinfo = &(This->fileinfo[handle]); + This->notify_stamp = True; + + switch (info_class) + { + case FileBasicInformation: + write_time = change_time = access_time = 0; + + in_uint8s(in, 4); /* Handle of root dir? */ + in_uint8s(in, 24); /* unknown */ + + /* CreationTime */ + in_uint32_le(in, ft_low); + in_uint32_le(in, ft_high); + + /* AccessTime */ + in_uint32_le(in, ft_low); + in_uint32_le(in, ft_high); + if (ft_low || ft_high) + access_time = convert_1970_to_filetime(ft_high, ft_low); + + /* WriteTime */ + in_uint32_le(in, ft_low); + in_uint32_le(in, ft_high); + if (ft_low || ft_high) + write_time = convert_1970_to_filetime(ft_high, ft_low); + + /* ChangeTime */ + in_uint32_le(in, ft_low); + in_uint32_le(in, ft_high); + if (ft_low || ft_high) + change_time = convert_1970_to_filetime(ft_high, ft_low); + + in_uint32_le(in, file_attributes); + + if (fstat(handle, &filestat)) + return STATUS_ACCESS_DENIED; + + tvs.modtime = filestat.st_mtime; + tvs.actime = filestat.st_atime; + if (access_time) + tvs.actime = access_time; + + + if (write_time || change_time) + mod_time = MIN(write_time, change_time); + else + mod_time = write_time ? write_time : change_time; + + if (mod_time) + tvs.modtime = mod_time; + + + if (access_time || write_time || change_time) + { +#if WITH_DEBUG_RDP5 + printf("FileBasicInformation access time %s", + ctime(&tvs.actime)); + printf("FileBasicInformation modification time %s", + ctime(&tvs.modtime)); +#endif + if (utime(pfinfo->path, &tvs) && errno != EPERM) + return STATUS_ACCESS_DENIED; + } + + if (!file_attributes) + break; /* not valid */ + + mode = filestat.st_mode; + + if (file_attributes & FILE_ATTRIBUTE_READONLY) + mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + else + mode |= S_IWUSR; + + mode &= 0777; +#if WITH_DEBUG_RDP5 + printf("FileBasicInformation set access mode 0%o", mode); +#endif + + if (fchmod(handle, mode)) + return STATUS_ACCESS_DENIED; + + break; + + case FileRenameInformation: + + in_uint8s(in, 4); /* Handle of root dir? */ + in_uint8s(in, 0x1a); /* unknown */ + in_uint32_le(in, length); + + if (length && (length / 2) < 256) + { + rdp_in_unistr(This, in, newname, length); + convert_to_unix_filename(newname); + } + else + { + return STATUS_INVALID_PARAMETER; + } + + sprintf(fullpath, "%s%s", This->rdpdr_device[pfinfo->device_id].local_path, + newname); + + if (rename(pfinfo->path, fullpath) != 0) + { + perror("rename"); + return STATUS_ACCESS_DENIED; + } + break; + + case FileDispositionInformation: + /* As far as I understand it, the correct + thing to do here is to *schedule* a delete, + so it will be deleted when the file is + closed. Subsequent + FileDispositionInformation requests with + DeleteFile set to FALSE should unschedule + the delete. See + http://www.osronline.com/article.cfm?article=245. */ + + in_uint32_le(in, delete_on_close); + + if (delete_on_close || + (pfinfo-> + accessmask & (FILE_DELETE_ON_CLOSE | FILE_COMPLETE_IF_OPLOCKED))) + { + pfinfo->delete_on_close = True; + } + + break; + + case FileAllocationInformation: + /* Fall through to FileEndOfFileInformation, + which uses ftrunc. This is like Samba with + "strict allocation = false", and means that + we won't detect out-of-quota errors, for + example. */ + + case FileEndOfFileInformation: + in_uint8s(in, 28); /* unknown */ + in_uint32_le(in, length); /* file size */ + + /* prevents start of writing if not enough space left on device */ + if (STATFS_FN(This->rdpdr_device[pfinfo->device_id].local_path, &stat_fs) == 0) + if (stat_fs.f_bfree * stat_fs.f_bsize < length) + return STATUS_DISK_FULL; + + if (ftruncate_growable(handle, length) != 0) + { + return STATUS_DISK_FULL; + } + + break; + default: + + unimpl("IRP Set File Information class: 0x%x\n", info_class); + return STATUS_INVALID_PARAMETER; + } + return STATUS_SUCCESS; +} + +NTSTATUS +disk_check_notify(RDPCLIENT * This, NTHANDLE handle) +{ + struct fileinfo *pfinfo; + NTSTATUS status = STATUS_PENDING; + + NOTIFY notify; + + pfinfo = &(This->fileinfo[handle]); + if (!pfinfo->pdir) + return STATUS_INVALID_DEVICE_REQUEST; + + + + status = NotifyInfo(This, handle, pfinfo->info_class, ¬ify); + + if (status != STATUS_PENDING) + return status; + + if (memcmp(&pfinfo->notify, ¬ify, sizeof(NOTIFY))) + { + /*printf("disk_check_notify found changed event\n"); */ + memcpy(&pfinfo->notify, ¬ify, sizeof(NOTIFY)); + status = STATUS_NOTIFY_ENUM_DIR; + } + + return status; + + +} + +NTSTATUS +disk_create_notify(RDPCLIENT * This, NTHANDLE handle, uint32 info_class) +{ + + struct fileinfo *pfinfo; + NTSTATUS ret = STATUS_PENDING; + + /* printf("start disk_create_notify info_class %X\n", info_class); */ + + pfinfo = &(This->fileinfo[handle]); + pfinfo->info_class = info_class; + + ret = NotifyInfo(This, handle, info_class, &pfinfo->notify); + + if (info_class & 0x1000) + { /* ???? */ + if (ret == STATUS_PENDING) + return STATUS_SUCCESS; + } + + /* printf("disk_create_notify: num_entries %d\n", pfinfo->notify.num_entries); */ + + + return ret; + +} + +static NTSTATUS +NotifyInfo(RDPCLIENT * This, NTHANDLE handle, uint32 info_class, NOTIFY * p) +{ + struct fileinfo *pfinfo; + struct stat buf; + struct dirent *dp; + char *fullname; + DIR *dpr; + + pfinfo = &(This->fileinfo[handle]); + if (fstat(handle, &buf) < 0) + { + perror("NotifyInfo"); + return STATUS_ACCESS_DENIED; + } + p->modify_time = buf.st_mtime; + p->status_time = buf.st_ctime; + p->num_entries = 0; + p->total_time = 0; + + + dpr = opendir(pfinfo->path); + if (!dpr) + { + perror("NotifyInfo"); + return STATUS_ACCESS_DENIED; + } + + + while ((dp = readdir(dpr))) + { + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) + continue; + p->num_entries++; + fullname = (char *) xmalloc(strlen(pfinfo->path) + strlen(dp->d_name) + 2); + sprintf(fullname, "%s/%s", pfinfo->path, dp->d_name); + + if (!stat(fullname, &buf)) + { + p->total_time += (buf.st_mtime + buf.st_ctime); + } + + xfree(fullname); + } + closedir(dpr); + + return STATUS_PENDING; +} + +static FsInfoType * +FsVolumeInfo(char *fpath) +{ + + static FsInfoType info; +#ifdef USE_SETMNTENT + FILE *fdfs; + struct mntent *e; +#endif + + /* initialize */ + memset(&info, 0, sizeof(info)); + strcpy(info.label, "RDESKTOP"); + strcpy(info.type, "RDPFS"); + +#ifdef USE_SETMNTENT + fdfs = setmntent(MNTENT_PATH, "r"); + if (!fdfs) + return &info; + + while ((e = getmntent(fdfs))) + { + if (str_startswith(e->mnt_dir, fpath)) + { + strcpy(info.type, e->mnt_type); + strcpy(info.name, e->mnt_fsname); + if (strstr(e->mnt_opts, "vfat") || strstr(e->mnt_opts, "iso9660")) + { + int fd = open(e->mnt_fsname, O_RDONLY); + if (fd >= 0) + { + unsigned char buf[512]; + memset(buf, 0, sizeof(buf)); + if (strstr(e->mnt_opts, "vfat")) + /*FAT*/ + { + strcpy(info.type, "vfat"); + read(fd, buf, sizeof(buf)); + info.serial = + (buf[42] << 24) + (buf[41] << 16) + + (buf[40] << 8) + buf[39]; + strncpy(info.label, buf + 43, 10); + info.label[10] = '\0'; + } + else if (lseek(fd, 32767, SEEK_SET) >= 0) /* ISO9660 */ + { + read(fd, buf, sizeof(buf)); + strncpy(info.label, buf + 41, 32); + info.label[32] = '\0'; + /* info.Serial = (buf[128]<<24)+(buf[127]<<16)+(buf[126]<<8)+buf[125]; */ + } + close(fd); + } + } + } + } + endmntent(fdfs); +#else + /* initialize */ + memset(&info, 0, sizeof(info)); + strcpy(info.label, "RDESKTOP"); + strcpy(info.type, "RDPFS"); + +#endif + return &info; +} + + +NTSTATUS +disk_query_volume_information(RDPCLIENT * This, NTHANDLE handle, uint32 info_class, STREAM out) +{ + struct STATFS_T stat_fs; + struct fileinfo *pfinfo; + FsInfoType *fsinfo; + + pfinfo = &(This->fileinfo[handle]); + + if (STATFS_FN(pfinfo->path, &stat_fs) != 0) + { + perror("statfs"); + return STATUS_ACCESS_DENIED; + } + + fsinfo = FsVolumeInfo(pfinfo->path); + + switch (info_class) + { + case FileFsVolumeInformation: + + out_uint32_le(out, 0); /* volume creation time low */ + out_uint32_le(out, 0); /* volume creation time high */ + out_uint32_le(out, fsinfo->serial); /* serial */ + + out_uint32_le(out, 2 * strlen(fsinfo->label)); /* length of string */ + + out_uint8(out, 0); /* support objects? */ + rdp_out_unistr(This, out, fsinfo->label, 2 * strlen(fsinfo->label) - 2); + break; + + case FileFsSizeInformation: + + out_uint32_le(out, stat_fs.f_blocks); /* Total allocation units low */ + out_uint32_le(out, 0); /* Total allocation high units */ + out_uint32_le(out, stat_fs.f_bfree); /* Available allocation units */ + out_uint32_le(out, 0); /* Available allowcation units */ + out_uint32_le(out, stat_fs.f_bsize / 0x200); /* Sectors per allocation unit */ + out_uint32_le(out, 0x200); /* Bytes per sector */ + break; + + case FileFsAttributeInformation: + + out_uint32_le(out, FS_CASE_SENSITIVE | FS_CASE_IS_PRESERVED); /* fs attributes */ + out_uint32_le(out, F_NAMELEN(stat_fs)); /* max length of filename */ + + out_uint32_le(out, 2 * strlen(fsinfo->type)); /* length of fs_type */ + rdp_out_unistr(This, out, fsinfo->type, 2 * strlen(fsinfo->type) - 2); + break; + + case FileFsLabelInformation: + case FileFsDeviceInformation: + case FileFsControlInformation: + case FileFsFullSizeInformation: + case FileFsObjectIdInformation: + case FileFsMaximumInformation: + + default: + + unimpl("IRP Query Volume Information class: 0x%x\n", info_class); + return STATUS_INVALID_PARAMETER; + } + return STATUS_SUCCESS; +} + +NTSTATUS +disk_query_directory(RDPCLIENT * This, NTHANDLE handle, uint32 info_class, char *pattern, STREAM out) +{ + uint32 file_attributes, ft_low, ft_high; + char *dirname, fullpath[PATH_MAX]; + DIR *pdir; + struct dirent *pdirent; + struct stat fstat; + struct fileinfo *pfinfo; + + pfinfo = &(This->fileinfo[handle]); + pdir = pfinfo->pdir; + dirname = pfinfo->path; + file_attributes = 0; + + switch (info_class) + { + case FileBothDirectoryInformation: + + /* If a search pattern is received, remember this pattern, and restart search */ + if (pattern[0] != 0) + { + strncpy(pfinfo->pattern, 1 + strrchr(pattern, '/'), PATH_MAX - 1); + rewinddir(pdir); + } + + /* find next dirent matching pattern */ + pdirent = readdir(pdir); + while (pdirent && fnmatch(pfinfo->pattern, pdirent->d_name, 0) != 0) + pdirent = readdir(pdir); + + if (pdirent == NULL) + return STATUS_NO_MORE_FILES; + + /* Get information for directory entry */ + sprintf(fullpath, "%s/%s", dirname, pdirent->d_name); + + if (stat(fullpath, &fstat)) + { + switch (errno) + { + case ENOENT: + case ELOOP: + case EACCES: + /* These are non-fatal errors. */ + memset(&fstat, 0, sizeof(fstat)); + break; + default: + /* Fatal error. By returning STATUS_NO_SUCH_FILE, + the directory list operation will be aborted */ + perror(fullpath); + out_uint8(out, 0); + return STATUS_NO_SUCH_FILE; + } + } + + if (S_ISDIR(fstat.st_mode)) + file_attributes |= FILE_ATTRIBUTE_DIRECTORY; + if (pdirent->d_name[0] == '.') + file_attributes |= FILE_ATTRIBUTE_HIDDEN; + if (!file_attributes) + file_attributes |= FILE_ATTRIBUTE_NORMAL; + if (!(fstat.st_mode & S_IWUSR)) + file_attributes |= FILE_ATTRIBUTE_READONLY; + + /* Return requested information */ + out_uint8s(out, 8); /* unknown zero */ + + seconds_since_1970_to_filetime(get_create_time(&fstat), &ft_high, &ft_low); + out_uint32_le(out, ft_low); /* create time */ + out_uint32_le(out, ft_high); + + seconds_since_1970_to_filetime(fstat.st_atime, &ft_high, &ft_low); + out_uint32_le(out, ft_low); /* last_access_time */ + out_uint32_le(out, ft_high); + + seconds_since_1970_to_filetime(fstat.st_mtime, &ft_high, &ft_low); + out_uint32_le(out, ft_low); /* last_write_time */ + out_uint32_le(out, ft_high); + + seconds_since_1970_to_filetime(fstat.st_ctime, &ft_high, &ft_low); + out_uint32_le(out, ft_low); /* change_write_time */ + out_uint32_le(out, ft_high); + + out_uint32_le(out, fstat.st_size); /* filesize low */ + out_uint32_le(out, 0); /* filesize high */ + out_uint32_le(out, fstat.st_size); /* filesize low */ + out_uint32_le(out, 0); /* filesize high */ + out_uint32_le(out, file_attributes); + out_uint8(out, 2 * strlen(pdirent->d_name) + 2); /* unicode length */ + out_uint8s(out, 7); /* pad? */ + out_uint8(out, 0); /* 8.3 file length */ + out_uint8s(out, 2 * 12); /* 8.3 unicode length */ + rdp_out_unistr(This, out, pdirent->d_name, 2 * strlen(pdirent->d_name)); + break; + + default: + /* FIXME: Support FileDirectoryInformation, + FileFullDirectoryInformation, and + FileNamesInformation */ + + unimpl("IRP Query Directory sub: 0x%x\n", info_class); + return STATUS_INVALID_PARAMETER; + } + + return STATUS_SUCCESS; +} + + + +static NTSTATUS +disk_device_control(RDPCLIENT * This, NTHANDLE handle, uint32 request, STREAM in, STREAM out) +{ + if (((request >> 16) != 20) || ((request >> 16) != 9)) + return STATUS_INVALID_PARAMETER; + + /* extract operation */ + request >>= 2; + request &= 0xfff; + + printf("DISK IOCTL %d\n", request); + + switch (request) + { + case 25: /* ? */ + case 42: /* ? */ + default: + unimpl("DISK IOCTL %d\n", request); + return STATUS_INVALID_PARAMETER; + } + + return STATUS_SUCCESS; +} + +DEVICE_FNS disk_fns = { + disk_create, + disk_close, + disk_read, + disk_write, + disk_device_control /* device_control */ +}; diff --git a/rosapps/applications/net/tsclient/rdesktop/disk.h b/rosapps/applications/net/tsclient/rdesktop/disk.h new file mode 100644 index 00000000000..447ebb59798 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/disk.h @@ -0,0 +1,139 @@ +/* + rdesktop: A Remote Desktop Protocol client. + Disk Redirection definitions + Copyright (C) Jeroen Meijer 2003 + Copyright (C) Peter Astrand 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#define FILE_ATTRIBUTE_READONLY 0x00000001 +#define FILE_ATTRIBUTE_HIDDEN 0x00000002 +#define FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define FILE_ATTRIBUTE_ARCHIVE 0x00000020 +#define FILE_ATTRIBUTE_DEVICE 0x00000040 +#define FILE_ATTRIBUTE_UNKNOWNXXX0 0x00000060 /* ??? ACTION i.e. 0x860 == compress this file ? */ +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200 +#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400 +#define FILE_ATTRIBUTE_COMPRESSED 0x00000800 +#define FILE_ATTRIBUTE_OFFLINE 0x00001000 +#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000 +#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000 + +#define FILE_FLAG_OPEN_NO_RECALL 0x00100000 +#define FILE_FLAG_OPEN_REPARSE_POINT 0x00200000 +#define FILE_FLAG_POSIX_SEMANTICS 0x01000000 +#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000 /* sometimes used to create a directory */ +#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000 +#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000 +#define FILE_FLAG_RANDOM_ACCESS 0x10000000 +#define FILE_FLAG_NO_BUFFERING 0x20000000 +#define FILE_FLAG_OVERLAPPED 0x40000000 +#define FILE_FLAG_WRITE_THROUGH 0x80000000 + +#define FILE_SHARE_READ 0x01 +#define FILE_SHARE_WRITE 0x02 +#define FILE_SHARE_DELETE 0x04 + +#define FILE_BASIC_INFORMATION 0x04 +#define FILE_STANDARD_INFORMATION 0x05 + +#define FS_CASE_SENSITIVE 0x00000001 +#define FS_CASE_IS_PRESERVED 0x00000002 +#define FS_UNICODE_STORED_ON_DISK 0x00000004 +#define FS_PERSISTENT_ACLS 0x00000008 +#define FS_FILE_COMPRESSION 0x00000010 +#define FS_VOLUME_QUOTAS 0x00000020 +#define FS_SUPPORTS_SPARSE_FILES 0x00000040 +#define FS_SUPPORTS_REPARSE_POINTS 0x00000080 +#define FS_SUPPORTS_REMOTE_STORAGE 0X00000100 +#define FS_VOL_IS_COMPRESSED 0x00008000 +#define FILE_READ_ONLY_VOLUME 0x00080000 + +#define OPEN_EXISTING 1 +#define CREATE_NEW 2 +#define OPEN_ALWAYS 3 +#define TRUNCATE_EXISTING 4 +#define CREATE_ALWAYS 5 + +#define GENERIC_READ 0x80000000 +#define GENERIC_WRITE 0x40000000 +#define GENERIC_EXECUTE 0x20000000 +#define GENERIC_ALL 0x10000000 + +#define ERROR_FILE_NOT_FOUND 2L +#define ERROR_ALREADY_EXISTS 183L + +typedef enum _FILE_INFORMATION_CLASS +{ + FileDirectoryInformation = 1, + FileFullDirectoryInformation, + FileBothDirectoryInformation, + FileBasicInformation, + FileStandardInformation, + FileInternalInformation, + FileEaInformation, + FileAccessInformation, + FileNameInformation, + FileRenameInformation, + FileLinkInformation, + FileNamesInformation, + FileDispositionInformation, + FilePositionInformation, + FileFullEaInformation, + FileModeInformation, + FileAlignmentInformation, + FileAllInformation, + FileAllocationInformation, + FileEndOfFileInformation, + FileAlternateNameInformation, + FileStreamInformation, + FilePipeInformation, + FilePipeLocalInformation, + FilePipeRemoteInformation, + FileMailslotQueryInformation, + FileMailslotSetInformation, + FileCompressionInformation, + FileCopyOnWriteInformation, + FileCompletionInformation, + FileMoveClusterInformation, + FileOleClassIdInformation, + FileOleStateBitsInformation, + FileNetworkOpenInformation, + FileObjectIdInformation, + FileOleAllInformation, + FileOleDirectoryInformation, + FileContentIndexInformation, + FileInheritContentIndexInformation, + FileOleInformation, + FileMaximumInformation +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; + +typedef enum _FSINFOCLASS +{ + FileFsVolumeInformation = 1, + FileFsLabelInformation, + FileFsSizeInformation, + FileFsDeviceInformation, + FileFsAttributeInformation, + FileFsControlInformation, + FileFsFullSizeInformation, + FileFsObjectIdInformation, + FileFsDriverPathInformation, + FileFsMaximumInformation +} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/AUTHORS b/rosapps/applications/net/tsclient/rdesktop/doc/AUTHORS new file mode 100644 index 00000000000..a0824584e49 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/AUTHORS @@ -0,0 +1,14 @@ +This is an attempt at a list of people who have made significant +contributions to the code. If you have been unintentionally omitted +please let one of the team members know. + +Matt Chapman +Peter Kallden +Hugo Trippaers +Jay Sorg +Peter Ĺstrand +Michal Mihalik +Norbert Federa +Erik Forsberg +Michael Gernoth +Jeroen Meijer diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/ChangeLog b/rosapps/applications/net/tsclient/rdesktop/doc/ChangeLog new file mode 100644 index 00000000000..4c096a03e43 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/ChangeLog @@ -0,0 +1,86 @@ +rdesktop (1.?.?) + * SeamlessRDP - seamless windows support + * Keymap fixes + * Fix connection issues with Windows XP RTM + * Keyboard handling improvements and fixes + * SGI/Irix sound-driver fixes + * Support for clipboard INCR protocol + * Session Directory support (patch from Brian Chapeau ) + * Support for long filenames on redirected drives + * XOR ellipse drawing fix + * Clipboard unicode support (Ilya Konstantinov) + * Refactoring of color depth code (Ilya Konstantinov) + +rdesktop (1.4.1) + * persistent bitmap cache optimisations + * support for more RDP-orders (ellipse, polygon) + * libao sound-driver (for Mac OSX and others) + * Unicode support for transmitted strings/filenames + * Added korean keymap + * Xembed fixes to work with krdc correctly + * Portability fixes + * Support for RDP-compression (all bpps) + * process RDP recv queue if send queue is full (Debian bug #246461) + * SGI/Irix sound-driver fixes + + -- Michael Gernoth Sun, 8 May 2005 19:55:35 +0200 (CEST) + +rdesktop (1.4.0) + * Basic disk-, parallel-, printer- and serial-redirection + * Fix timezone-redirection + * Backing-store fixes + * Fix client-IP sent to TS + * XEmbed support for embedding rdesktop in other applications (KRDC) + * Support for setting the RDP5 experience + * Keyboard and keymap fixes + * Performance improvements + * Report disconnect-reason + * Support for RDP-compression (currently only for 8bpp) + * Support for persistent bitmap caching + * Sound-driver for SGI/Irix + + -- Michael Gernoth Sun, 6 Mar 2005 22:09:55 +0100 (CET) + +rdesktop (1.3.1) + * Crypto fixes for RDP5 + * Keyboard and keymap fixes + * some endianess fixes for high color + * portability enhancements + + -- Matthew Chapman Tue, 21 Jan 2004 20:34 + +rdesktop (1.3.0) + + * RDP5 + * 15, 16 and 24 bit color depths + * Basic clipboard redirection + * Sound + * IPv6 + * Attaching to console on Windows 2003 + + -- Peter Astrand Wed, 29 Oct 2003 16:40:58 +0100 (CET) + +rdesktop (1.2.0) + + * new - more portable - key mapping code + * support for "high" (128-bit) encryption + * toggling out of full-screen mode with Ctrl-Alt-Enter + * a few extra options including host:port syntax + * many, many bug fixes and optimisations + + -- Matthew Chapman Thu, 30 Jan 2003 04:29 + +rdesktop (1.1.0) + + * solves arith.c licensing issue by taking big number routines from + OpenSSL + * keyboard support not merged from unified patches yet + * still no manpage + + -- Matthew Chapman Mon, 17 Sep 2001 23:14:28 +1000 (AEST) + +rdesktop (1.0.0) + + * initial release + + -- Matthew Chapman diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/HACKING b/rosapps/applications/net/tsclient/rdesktop/doc/HACKING new file mode 100644 index 00000000000..f7689763817 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/HACKING @@ -0,0 +1,28 @@ + +Code style / indentation +------------------------ +The file indent-all.sh contains information about the current code +style. Run this script before commits. + + +Variable argument macros +------------------------ +Variable argument macros are non-portable in general, and should be +avoided. Either use a second set of parentheses like DEBUG, or create +a variable argument function like error. + + +Structure +--------- +The core protocol stack should be system-independent (i.e. ANSI C +only) so that it is easy to port. This currently applies to the +following files: + +bitmap.c licence.c orders.c rdp.c rdp5.c cache.c iso.c mcs.c +secure.c mppc.c channels.c +rdesktop.c + + +RDP resources +------------- +http://dev.remotenetworktechnology.com/refdata.htm diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/TODO b/rosapps/applications/net/tsclient/rdesktop/doc/TODO new file mode 100644 index 00000000000..1aa830a4069 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/TODO @@ -0,0 +1,89 @@ + +* Clipboard: + + * Support other data types than plain text. + + * Conversion between different character sets. + + +* Drive Redirection: + + * Real support for file locking + + * Handle reconnections correctly. + + * Various deficiencies; see FIXMEs in source code. + + +* Serial Port Redirection: + + * More testing needed. + + +* Printer Redirection: + + * More testing needed. + + +* Keymapping: + + +* Sound redirection + + * Use timestamps in audio packets. + + * Add resampling to supported samplerates of audio-hardware. + + * Lower CPU-usage with an audio thread. + + +* Smartcard redirection + + * Merge patches currently implementing sc-redirection. + + +* Miscellaneous + + * Clean up header files. The current "proto.h" and "xproto.h" is far + from optimal. + + * Go through the many trackers (bugs/patches/RFEs) at SourceForge. + + * More fancy homepage. + + * Enhance documentation. Write a FAQ. + + +* SeamlessRDP mode + + * Add a client to server message for starting additional + applications. + + * Support cmd.exe. + + * Support for Input Contexts. + + * Enhanced support for WM_DELETE_WINDOW: Instead of terminating + rdesktop, close the window on the server side. + + * Systray support. + + * Support for transferring the application taskbar icon. + + * Better support for non-EWMH window managers. + + * Support for non-rectangular windows. + + * The focus handling of menus is a bit crude. + + * Support for sending focus information from client to server. + + * Implement something similiar to explhook.dll - support for running + explorer.exe in non-shell mode. + + * Better compatibility with Task Manager. + + * XINERAMA support. + + * When enumerating windows, make sure to send info about windows + that are transient for other windows after the referred window. diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/ipv6.txt b/rosapps/applications/net/tsclient/rdesktop/doc/ipv6.txt new file mode 100644 index 00000000000..1d3ef2341c2 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/ipv6.txt @@ -0,0 +1,29 @@ + +IPv6 support in rdesktop +======================== +The IPv6 support was developed by Mike Dawson : + + Attached is a patch to tcp.c to enable IPv6 support. Build with + 'IPv6' defined to enable it. It's so far only been tested on + Linux 2.4.21 connecting to Windows XP SP1. + + Since terminal services doesn't seem to bind to the ipv6 interface + on XP I had to run 'netsh interface portproxy add v6tov4 + listenport=3389 connectport=3389' from the windows command prompt + to get it to work. + + +rdesktop now supports numeric IPv6 addresses: + + It checks for two or more colons in an address to decide what it's + dealing with so you can now do: + + rdesktop 2001:1:2:3::4 + + without it getting confused with an ipv4:port specification. I've + also followed the square bracket convention used by browsers + (http://www.ietf.org/rfc/rfc2732.txt) so if you want to specify a + non-standard port with an ipv6 address you can use the format: + + rdesktop [2001:1:2:3::4]:3390 + diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/keymap-names.txt b/rosapps/applications/net/tsclient/rdesktop/doc/keymap-names.txt new file mode 100644 index 00000000000..3da698b2935 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/keymap-names.txt @@ -0,0 +1,124 @@ + +0x0436 af Afrikaans +0x041C sq Albanian +0x0001 ar Arabic +0x0401 ar-sa Arabic (Saudi Arabia) +0x0801 ar-iq Arabic (Iraq) +0x0C01 ar-eg Arabic (Egypt) +0x1001 ar-ly Arabic (Libya) +0x1401 ar-dz Arabic (Algeria) +0x1801 ar-ma Arabic (Morocco) +0x1C01 ar-tn Arabic (Tunisia) +0x2001 ar-om Arabic (Oman) +0x2401 ar-ye Arabic (Yemen) +0x2801 ar-sy Arabic (Syria) +0x2C01 ar-jo Arabic (Jordan) +0x3001 ar-lb Arabic (Lebanon) +0x3401 ar-kw Arabic (Kuwait) +0x3801 ar-ae Arabic (U.A.E.) +0x3C01 ar-bh Arabic (Bahrain) +0x4001 ar-qa Arabic (Qatar) +0x042D eu Basque +0x0402 bg Bulgarian +0x0423 be Belarusian +0x0403 ca Catalan +0x0004 zh Chinese +0x0404 zh-tw Chinese (Taiwan) +0x0804 zh-cn Chinese (China) +0x0C04 zh-hk Chinese (Hong Kong SAR) +0x1004 zh-sg Chinese (Singapore) +0x041A hr Croatian +0x0405 cs Czech +0x0406 da Danish +0x0413 nl Dutch (Netherlands) +0x0813 nl-be Dutch (Belgium) +0x0009 en English +0x0409 en-us English (United States) +0x0809 en-gb English (United Kingdom) +0x0C09 en-au English (Australia) +0x1009 en-ca English (Canada) +0x1409 en-nz English (New Zealand) +0x1809 en-ie English (Ireland) +0x1C09 en-za English (South Africa) +0x2009 en-jm English (Jamaica) +0x2809 en-bz English (Belize) +0x2C09 en-tt English (Trinidad) +0x0425 et Estonian +0x0438 fo Faeroese +0x0429 fa Farsi +0x040B fi Finnish +0x040C fr French (France) +0x080C fr-be French (Belgium) +0x0C0C fr-ca French (Canada) +0x100C fr-ch French (Switzerland) +0x140C fr-lu French (Luxembourg) +0x043C gd Gaelic +0x0407 de German (Germany) +0x0807 de-ch German (Switzerland) +0x0C07 de-at German (Austria) +0x1007 de-lu German (Luxembourg) +0x1407 de-li German (Liechtenstein) +0x0408 el Greek +0x040D he Hebrew +0x0439 hi Hindi +0x040E hu Hungarian +0x040F is Icelandic +0x0421 in Indonesian +0x0410 it Italian (Italy) +0x0810 it-ch Italian (Switzerland) +0x0411 ja Japanese +0x0412 ko Korean +0x0426 lv Latvian +0x0427 lt Lithuanian +0x042F mk FYRO Macedonian +0x043E ms Malay (Malaysia) +0x043A mt Maltese +0x0414 no Norwegian (Bokmal) +0x0814 no Norwegian (Nynorsk) +0x0415 pl Polish +0x0416 pt-br Portuguese (Brazil) +0x0816 pt Portuguese (Portugal) +0x0417 rm Rhaeto-Romanic +0x0418 ro Romanian +0x0818 ro-mo Romanian (Moldova) +0x0419 ru Russian +0x0819 ru-mo Russian (Moldova) +0x0C1A sr Serbian (Cyrillic) +0x081A sr Serbian (Latin) +0x041B sk Slovak +0x0424 sl Slovenian +0x042E sb Sorbian +0x040A es Spanish (Traditional Sort) +0x080A es-mx Spanish (Mexico) +0x0C0A es Spanish (International Sort) +0x100A es-gt Spanish (Guatemala) +0x140A es-cr Spanish (Costa Rica) +0x180A es-pa Spanish (Panama) +0x1C0A es-do Spanish (Dominican Republic) +0x200A es-ve Spanish (Venezuela) +0x240A es-co Spanish (Colombia) +0x280A es-pe Spanish (Peru) +0x2C0A es-ar Spanish (Argentina) +0x300A es-ec Spanish (Ecuador) +0x340A es-cl Spanish (Chile) +0x380A es-uy Spanish (Uruguay) +0x3C0A es-py Spanish (Paraguay) +0x400A es-bo Spanish (Bolivia) +0x440A es-sv Spanish (El Salvador) +0x480A es-hn Spanish (Honduras) +0x4C0A es-ni Spanish (Nicaragua) +0x500A es-pr Spanish (Puerto Rico) +0x0430 sx Sutu +0x041D sv Swedish +0x081D sv-fi Swedish (Finland) +0x041E th Thai +0x0431 ts Tsonga +0x0432 tn Tswana +0x041F tr Turkish +0x0422 uk Ukrainian +0x0420 ur Urdu +0x042A vi Vietnamese +0x0434 xh Xhosa +0x043D ji Yiddish +0x0435 zu Zulu + diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/keymapping.txt b/rosapps/applications/net/tsclient/rdesktop/doc/keymapping.txt new file mode 100644 index 00000000000..6d10eae5b87 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/keymapping.txt @@ -0,0 +1,243 @@ +Keyboard mapping +================ +This release of rdesktop uses a new, portable keyboard mapping +implementation. It should hopefully work on all X11 systems. This new +implementation only looks at X11 keysyms: Not on (nonportable) +keycodes or modifier status. This means that rdesktop will obey your +local keyboard configuration. For example, if you have swapped +CapsLock and Control, rdesktop will use this mapping. + +XKB is currently not used. It seems like a good idea to me, but since +some X servers (like Xvnc) does not support XKB, we still need to use +the plain old interface as well, at least. + +There are still some small problems. + +* CapsLock: CapsLock changes are never sent to the RDP + server. rdesktop does not know which keys that are modified by + CapsLock and which are not. So, the CapsLock indicator in Wordpad + etc will always be off. + +Composing/Multi_key is supported. For more information, see: + + MIT: $SRC/xc/nls/X11/locale/Compose/iso8859-1 + XFree86: /usr/X11R6/lib/X11/locale/*/Compose + Solaris' Openwin: /usr/openwin/include/X11/Suncompose.h + /usr/openwin/lib/locale/*/Compose + Irix6: compose(5) + + +Keymap files +============ +The names of the keymaps follows RFC1766. + +(You can find a translation from Windows keyboard layout numbers to +keymap names by looking at +HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\RFC1766 in the +registry.) + + +Contents of keymap files +======================== +The keymaps are line based. There are four different types of lines: + +1) include lines +Syntax: +include + +Example: +include common + + +2) map lines +Syntax: +map + +Example: +map 0x41d + +Map-lines specifies how the remote RDP server should interpret the +sent scancodes. + + +3) Translation lines +Syntax: + [flags..] + +Example: +onehalf 0x29 shift + +The scancode can be found in scancodes.h. Note: The scancode value for +extended keys can be calculated by OR:ing with 0x80. Example: The +Delete key have the scancode sequence 0xe0, 0x52. You can get the +scancode value to put into the map file by running: + +python -c "print hex(0x80 | 0x52)" + +If flags are "altgr", "shift", the scancode sent for this keysym will +be prefixed with AltGr, or Shift. + +If flags includes "addupper", a translation for this keysyms uppercase +name will be added as well, in addition to the non-uppercase +name. Example: + +x 2d addupper + +...will add an translation for "X" automatically, just like if you +would specify: + +X 2d shift + +If flags include "localstate", the modifier to send will be determined +by the local modifier state. + +If flags is "inhibit", nothing will be sent to the server. + +If flags is "numlock", rdesktop will make sure that the remote NumLock +state is on before generating the key event. Otherwise, it will make +sure NumLock is off. + + +4) enable_compose + +If any line starts with the keyword "enable_compose", rdesktop will +enable local Compose/Multi_key handling. Enabling this will often make +it impossible to compose characters with dead keys (on the remote +side). This is because when local compose support is enabled, dead +keys will not be sent to the remote side. + + +5) sequence lines +Syntax: +sequence ... + +Examples: +sequence eacute dead_acute e +sequence F12 f o o at e x a m p l e period c o m + +Sequence lines allows you to specify that multiple scancodes should be +sent to the RDP server, in response to one X11 keyboard event. Note: +The sequence is sent at the X11 KeyPress event. Nothing is sent at +KeyRelease. + + +6) keyboard_type lines +Syntax: +keyboard_type + +keyboard_type lines specifies the keyboard type. Default value is 0x4 +(en-us 101/104 keys keyboard). + + +7) keyboard_subtype lines +Syntax: +keyboard_subtype + +keyboard_subtype lines specifies the keyboard subtype. Default value +is 0x0 (en-us 101/104 keys keyboard). + + +8) keyboard_functionkeys lines +Syntax: +keyboard_functionkeys + +keyboard_functionkeys specifies the number of keyboard function +keys. Default value is 0xc (12, for standard 101/104 keys keyboard). + + + + +Suggested X11 keysym mapping on PCs +=================================== +Unfortunately, there is no standard for which keysyms a given key +should generate. If you have a PC-keyboard with Windows keys, I suggest this mapping: + +Keyboard keys: +CtrlLeft WinLeft AltLeft Space AltGr WinRight Menu CtrlRight + +...should generate keysyms: +Control_L Super_L Alt_L space Mode_switch Super_R Menu Control_R + +Additionally: +Shift-Alt should produce Meta_L +Shift-AltGr should produce Multi_Key. + +Use a modifier-map like this: + +shift Shift_L (0x32), Shift_R (0x3e) +lock Caps_Lock (0x25) +control Control_L (0x42), Control_R (0x6d) +mod1 Alt_L (0x40) +mod2 Num_Lock (0x4d) +mod3 Mode_switch (0x71) +mod4 Super_L (0x73), Super_R (0x74) +mod5 Scroll_Lock (0x4e) + + +Updating / writing keymap files +=============================== +When writing new or updating keymap files, please use comments and +blanks, to increase readability. The "sv" keymap is a good template. + +When you need to add a translation to a keymap file, do: + + 1. Get the "key number" for this key, by looking at keynums.png. + + 2. Take a look at scancodes.h, and look for + SCANCODE_KEY_. The scancode value is at the end of + the line. If the line contains (SCANCODE_EXTENDED | 0xsomething), + then you should OR 0x80 to this value. For example, you can do: + + python -c "print hex(0x80 | 0xsomething)" + + 3. Put the scancode (from step 2) and keysym name (found in the + error message) into the keymap file. + + +Special keys +============ + +* The combination Ctrl-Alt-Enter toggles between fullscreen and + non-fullscreen mode. + +* Meta, Hyper and Super are treated as windows keys. RDP4 does not + support the windows keys though, so if you are running RDP4, these + keys will translate to Ctrl-Esc. + + +Links +===== +http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html + + +Test cases +========== +When changing the keyboard code, make sure all these tests in Notepad +works: + +1. Ctrl+f should bring up Find dialog, with CapsLock both on and off. + +2. Ctrl+Shift+arrows should mark text, with CapsLock both on and off. + +3. Test a sequence, like egrave. + +4. Test a char generated with AltGr, such as @ on a swedish keyboard. + +5. Test Ctrl-Alt-Delete. + +6. Ctrl-Alt-Enter should toggle fullscreen. + +7. Test NumLock synchronization using the -N option. Excel is able to + indicate the current NumLock state. Verify that the status is + updated correctly on reconnects. + +8. Test the Windows keys, standalone as well as in combination with, + say, E. + +9. Make sure the system menu (via Alt-space) cannot be accessed in + single app mode. + +10. Make sure keymaps can be loaded from ~/.rdesktop/keymaps, + KEYMAP_PATH, $CWD/keymaps, and from an absolute path. + + diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/keynums.png b/rosapps/applications/net/tsclient/rdesktop/doc/keynums.png new file mode 100644 index 0000000000000000000000000000000000000000..401601b9e0610b1c666e5d2331d86ac3c714a80a GIT binary patch literal 9173 zcmV;`BP!g9P)d>G=E6|03ZNKL_t(|ob8=|a2)4(-`~AG-5t%v?NRVBNArX`O0r}(a=Z{VG54E7d-a$j(!S7N5#sugFOtRULL77Y z@YaPmE_oHI_L?nnYeh;u;Rv%TG~ykaOJd(69Dh@ zIm#$5QAQu0wjxBQv?fGilrpILA{AVq!;DEw zh?5gS#4O?nF}&djZGet2%6)j0pW=L?YL~$)Sxw%2z;hMvAseT!Euh-T3h^i-mZ5ee z-qjuOP-CjXJZc4ZHsFn~+Cn$*kH}7f=Mry(GAg#P6t7eccv+Dko^{n0no0E;);2tA zXFOy))XqZ&@vNQl48_ZA%gagLFnH+*FSL&`OygbWS?@8gx)YwYbKY#o8w+^%r^Z(w z+qcHNIN9fHxNcl0-k}tDZgza(OsY=2S?i>mC@jLhlX2_nW7eu^Waj$wvI_yv&HC=F zu{2+@F6PEpYr|~c@gd@^6kXT&?Tb0% z9R8jDyklQ60^Wi1?riR_iMLW3U!4nhgW1XPm8|RLUMJqV1>Vw~#5;DkQ5t{BIO(Rp zeLHx|#5?ng+V;HSQ_8-gMZ9mrKH@!g*ah!ciFnHvwI|zm1mn}a<*9{q_71Xdns|vU z>?@YfS^nZco!awr+qCCX^Qt|GXVi)JaprOV9T=hZd=b3670+@96whVeYv7Il8|uG- z)t&Hy_N-^e0^Y?*>Obo+^A0QCUBo*y!uA~i&ke^5+Os%upLKQ78a9o6^Yh#Ag7&PZ zz`L~E!rK?}?gTH#_U%)=dGKz(7yb9!BN(6HJ-#!ZRnOYQTPEJ(B--r4EO*|0rJs|#oLfVTkN z2J=2))AePN#^>PL&aP*4nYw}Nb@YCexT)*s&UnM^yy*Sty}4d@@LKM-@6r9}{|nxG zaK9Z6c=I=Z{|oZLTiUk&tf+nToHcQy_N7A}JrBBbsHO;>)3mQ5d1+)QULxSR!T8Kl zmJeP+wO4OmQO<|5&}xdeO1z{YbBU+9u1y&^IuRQM^@Svz2nr%2O+3n~`1E`YUbY`k zSG)|l1+|(jN>r^@_dJm%9#vbZ7AeDZL@qZZG-_vy3YxlY7fYo~(yecabHq#AanG+f zl=0Xt)xJFPX{3GRQt9OKY?R35se9!57&5m?E>Deoqs<&SO?4Xuw@fPNqhJjMiAPxu z`9@o2SYHp`H2Gc9zIOf~!=s!I?rPwpByZBB_GxEq0$&iX_uD7<+OM_UJUE&u{EUsO*O$yr!m@am0Rw!3?SWfxaDgN_VrQFpKA5r zAsuXm8Fn9Dr(V#mPiUb&F%{|)PCn2lWQNoyRK`{x-0rr!?QXll5Y=sCntED4c&laiN)ZIL)UFU0V?C$#z3 zgfQL=csWm`QGyRV$L|dA5=K9c(yx@M^hGLE=Ca8wr9JNm?W+hBd7~o48s0!1hu;1& z9rINxYJ8SzTcg^N$8$1S%vP-w)4b$%Ijudyc;iQ&q6p}a+a`(7b9Lg;GIP25|y6KF3ra$ zmK9G6UlfiRMaipxXH(G;w5LZr9m!ln20Vv&XPAc<6?E#^%A~jEY8Q!TR3vYWN~gh_ zE6trTu7x}uyb{@`Jx9C*Dt3sckCA;bYESJv@nSaF_pRDcR=22z!NT0U_7u0quo^D| z)Smk1hs4;J! zBY73wA>NmWm-hpnOT0-c{pEFP&!?9=d1d0I6;F38$rFAj56N?q=LPl+dakRz74jyg zFHmVy@|HSyDU6pws#HD*UMdl^ry+v&)WQ3C#miv4OfxTI1-wjw`tKO}FD1vzCQ8S_ zd!2YsKG?#`f@cvg&pg$CDYR!s@k0ADu zRD<3epWtcH@%b^u8`S1z#M8_h4CX`muvd5WE3ofn$y- z5B;Zu_j5F(V$545`xc`8M?7cM)vh$h3(r5ZiuqTZn~BVKzP@}2=!ob{mAKpS+F2#fQPCWDt95!F95R9$<{k?kqp;=p{?4Hr2`&Nq996n3^yHl2 z5&@3`I~Ghte1Jz4r%|-Ryt#l^udCXq25qhu#D`!j$?@sBjy#a}8)L@|Q&nlkBF%=xTaoCnIAY2;1mr>dg zK~M-sxab!|5ZHl=6Y4Oyh9ZaL*A5)N7+A5iEkf*nK|Y9gOk zO&Re)nXWx1awTD%T>XIup#846V@m6uDsSYD&fKx zt$Q*@tb`VH=pmtfQ%Vn+dh?pnCmOt)+Y;vHs4u462K@zLqH^6956@i?$<0wuoLEJ& zxgpF7m4DbR34QZ~BSuy^bOxUN1);x61@l+0$SO;oFs@z};yTof;%job1IFg7*k7BY z8qOVeL~f17?>ddAWN}@HW0#9Gz(%oj{x$VE9u z(awl|64o-!&x_>m8%LoZe3J&;09BP;u0S85IdYh8Ee}yLOB>l!tbPQ^bhOk%pkS~* zfqC#ysAgc9%1Wpga3GejHoag?%+Wxv&IiI)5AgwiKAoFL58>c-oMN(<0u(;Jr%K41xDBwWt0IsZwEohD!g@W5m1l zCFYfdKjCVBKn3?!CGRfc?LB4r^{)&soyq-v=--O$dGIQz_z61W+n%%h=@PZ)o(l2) za?Ew(e?!&WTOrLInCA>P2JEZ=>~f@ko_n}Ghiy9JXUV>S^Ok3y0uTL{rPB~AR87Js-a+a=@z1C|^44=l!@^o@Oo=H{97Lt<~FXxF@7$@EnWM8UG zyk7***pR$E)Smji&w|QC$$&QxUiPf)KaF~nc?XuIeQ3|U&_kZikbU2YjL-8CUJm2apN`Xf zNTEINr{oxT7RIOhvov1zl6}?~W)FB79-p~#<~*gaeL;J^rrL7>yw3R`xIIglfBy73 zjn6#ndz<<%iTN-B-rLlF`U>^m2zU+f@}6wZ49!2;e-+8Y{7Yc|oypMkr5w4wIN;q5 zo*}QFUi12rLUQ}{rPy&l$`<xgVjh*~h-l@sjIr zU+?zJspqAg*q0b8s`1iKpAc<&2&Gm%#l!O;IpC7VE0&}BNOOG3=a;Oq&r)ZQi|~}1 zu{77@$s?2@Y1Hr#gb5Q5n$?O*#$zSRCW%1CaO*#{tcQH~?P?yYUpCTImo216ALtWO`e0$= z2>$BSD~7^kA=+gOh!NZ9A;^*bgD#KQjPkVeB3SrxN(4(+ZWU^Mib`hnV^kjPNuD31 zMD+>gu|83b@?KFDA4Pc-W+4RbT>=FUi(q{UAId9el#Idkchy7qH)=L~p%%5swI=vZ zfm{=_CIX)j@5{BzDj6=Mj%4y%X+9wt6ZfhU)R9yv*BmJ)m4e(PI-vN-$wz)u@`9Lz zIaF1m>&NPkv`pT-JpX6@m%d;(YJdBpD2-nIKl*CJzuz>coTL8MPycAjefy37Hksdg zN9q;u-$OlQRsP+ohp=8CaZ)eX>Y*2OCi@*S0_zdo^@35QPvo1t*l43=``f9OB{E3* zsKS3;aai>Lo`W}9zTXj}`-^DmA)DRx5SBQkq%+lS7fTvFk~yi{`k(wpirVuU^dA3v z8xPy!5!ruQV_L)?#kE1`Tc$74KAr8gg`$)zN^2|BH923H)$2k$JXaFQbH^N!TU`-i z9Run50!@-HIi0){bZtYt#upc$hpaXA5U6kBwBzDi9W*AB$EeUTdU(^8Pt$etG$l{u z=sKN+E^(2PS7?+QchJq`AHmS&{lUSvKqj82iVw^y z9fVFQeU!3KLmtV4_XhRM#R>9Ckqp&DSg({t*Y9aO1bxB?^of;=ZTG*7bHvJsL(c~~ zND8;7McmGg6odPaNi#IZU-p0(d?YKAxjH3vv}}izKJjwf`v7@=FW*Q1J*0GyRP(+b z$|HC^q2!AAhWKb>f*t;#D2DroT$Op$hS? z)R0WPl1IEx#P?@o1w!pX41(cxx&Nq3tN?yq!-k%e1?}IcxUnX9{ zC*G0s*6Q>ywdbA(iTA+*jhDZs{!5n$br8GT3f*}hCf;Dy^4%vc5ic_z@?wuO?@r=P zmuje(`tQrci-UK&9q_b}cZvG1$;WQq4wlb4L}Ccw)P?;jIS`!VrM z@IFtxWC=W<+}*L+kqr0WXPiDf_TMe=tXBJU$%}(`FUIE#jh6-3w@5twEVbvoXwPMu z4+-MwmH0^U1K>?!d`?;2=ldTLPcML1Cf?VYJi5VvcRTT>-%q?fFVgh|y!elZcL#V! zFkY6aTkj|k?|)PO<-wc6q!{hao4yC_3EtBV^g5$`eBL*9s6M@k`B0^bc|L3rZ$Gu? z^pA;WqW?~KG+t;v$oAZe_8jQZo|h3Xg?OSf8#Mo3Yx0c9{JTQDgaus*{bvv_hxzxS zj$|W{w>}>7JjAT@nD08SFDMnyZg>66_PU;xyI((l((CoMyc@rMZgW4nFlfIx&!eVHK$b%@yqx&NL>jYewF-(+O#clxt!2EkK76~__BvygATGk4b^1o zyA2<%&qkN_Ec>D~WZG1!IA*rRYmoO-h7MA9l;FW~1^Hqdh{JHaFnKgkF^(vu!+~qp z?fV@ZuYpnyM?6GA|N3uSY1riw)i>=0f`?sAlH(SB!h`DEFa=Z-6Un0u?+7Qu z*W2Lk=)%jBmx-##3*G3{L%b2%X>jXVfT+^HF&YkSItc3$NZzlKS$^pD{SNBZX1qqi z33W%2S3wG2;gXCs7NBCtAN0sjBzbmam#%q|3Ry{;Y9GgljX^I&9 zEzmyl$X16w(Z-WirJL(l_;gJrZ8)tTI30z!64geUOI@_^G(%qSsnagJ(N_C-^-FUd zOsD1(+S*+HqDOdkcV26>j4Y(RNkd>`ims4X5dN_-ikOX8gt)@N8FW%pOPfNwaM%$8 z*S<%+ZFs>qOqVbsPVjyzfY7m~AMj2%A_+a@G}f=2J1xh(kkLrI`bDgr@hOK!y0Ml; zFbIM^E>guS5J8kSa+;IZXnrj5i0A!@V0;eqr&Z;KH8jVTl^)_Y^%tsJAE3WQkuQ2Qea(ig&M!*+^*yZr6y}ke^iT%?tDpu@vFa0UClJ<^6MZF^Dl34`W1>NRW`C z1U&)_%&6c`86v58uDX4T{(4A+H=}rm)W=FC?_vk9$h=}dUa#kucKdMaA8&p3U5vid z8Hl&>toM$GS9R|qFKo|;dh^~*`(_pc5vz}VJLaW#Zl8Tq{ij`w@LWBg(z99LnJsqV z>ELPLmB_x7L%fd@FIgmBk$CzgdKOJ16u_Tu<$Wu{yBy&y(R|Qz#9L_P=>~Xrf_KE8 zUDOc+bD%);!6lw?igdmw$kG72@fSA?7Aayw^he9%r80acF z+W4Y9vv^C2=HG|C!s_&|>jAF{-bEGT^CRM!Mer^&Z!yAKZ{rPgWsR@a*0f}V_sig2B3{1U%DbyOkNS_=^Yskz9%$idJU;KSgYlwes6F?1 zFFwtOgD(^BEZJv#pLqI5z|-%FwC9xw5Bf{8l2p82ab9ZY_ao*dTX~uH(7r-wUvYc;di0-3_GR1SHQIP?2e0{g(;Ma) zU3iqHBUXY}m1whcjDc|#Y87G32J?80$v{$(a&oVDc7%s_c%dG$4KJm5Q4xe=M9R$5 z6)9W9^QKy-Q|C{e%B@V#*ZH*6L$qXs2gd?>MZ@zgVJ7O1DCW|lR`;r!Y3klBezhc$ zwfbA)Le3ofCyrmeH9eqj{fb|N3lr>v@lxkcj|M#YoetNpwDLF>MCu!fI-)S3jrc9v zNIeMUXvT;HJTt;`qP!`^%TxWcDOd5ZW4%ISkBZANlH?P!V;9JAqxK$L)l!D~!T@!@hwi6LXH$QscsPem-fyt2zLXrgZXQcK z{4LdnJ=zFPt>^bV_>6S6FSQ=EFOW6#ut1M(gGt<+L8y%rv}d>;$P4Vvt7ByUrA`{E z|G;#&@GFVHneUmwZ0g*So1+c{Gz1srd?mmQP zc|GGrTh=FE_Dt@ZxDndtKqHY5SWI2ps_VvF2qgqIYX-}8`P{IF$AAGTxALl&Am z85{LkOc#rrc>J8x0SY$l40H^A0C!8{IE3%qQ9isZd1QBUy-ZL`u{~Y`BwlbsJhbGY zmwNI9?p7iuc?dQU#u4zc@_QbtVO$Rhf5o8y??$2Xr9`Lf=-sdRZ*iP)z2aHZ0;&&(B8(z$ezgzZ|#m?I^ z7%u^@M_vGL&8F*1wqk&{j`j?BA7$QZyM5Q0_m3`|ua0Ryu-kZ(ZM?ii z_T`hO&mA=Oe)=4EKejPmDk-eb!S^oAs^XpSF(2wr|5__=2)vWWnOAh$+VfNG{Z~$! z@xh~?C!YD~pF;mV%l4H8@$}Kzq3pqsmjkcjJiXbcQyTlv# zU;F0CzGodCFWKiLFL&T&#rsHs=fhXpc+Z5qviS4u#^*sB{g=3xc>8|%pXZP8e6X-S z2kWc;V`3<0`YrRJ>a@>?>zIGl;SzZ3?YvwY&+v)2FLwL6y+-D(b+l(W;5jFupQ-h6 z;NcZVwlX%8y4mYl+x2t2^?K%Zy`EK^ckOx|@+zI{Eq25k+Ziu%KROb*|Mj_EU;K%9 zGhKLP#mlwZH+J*)BYs|D6`_S!l;30NZeO*{zG8$|*%>c#{~O6k`(*#w5&ME#ig*ZX z`<{m=@|Q9!{{NViUn=*)>2u&EO`UmI5|A4)0{g7C^(&6zsrZnH9wMv~nx(=#=cV4y z^9ia^BnBi8R%Vaz;a0eQMSchbJWn1|sc?LV-Ta;h?flXZ-lA7a@IPM~?dh*TEfGUz zjrOIz$;U;kdc^$o|1s(lj}CI{TYr!BD=%P3^1E>OFYqX%>t*=8Fn^iDnS@hgpEY~X z8k-4zlRSVI$NoX~3y<*o>PqB$9!a@=#R<;ZsXz~LBJm+$OkywI;Lkk1)N{Cqgd_H8 zQl1b8MJ)C{o8v3+eU13D|4Mg6P7G=9OsVxNys;jF&Wz{}xVNX}u;GKCP2W0w+QOdiEiM>KD+uY8`GQg|B$GP3@||Na{b4Y_{B1S9%A53av0 zK1BM{wVnCXEE~wE0~w4V*MBsmJg_y|_y)e`@%0veI#fLZ9)3!hfg>dv(cyCc-~GkE zzdqG?Ve?lqabf@J&pEezCZkb-j4I%>ZWWK}1(M&Y7ewPH-lgq<%mZXV=40Zg-}w0X fcem<)Fx&qFT#Jez7GKgQ00000NkvXXu0mjfk~4;D literal 0 HcmV?d00001 diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/licensing.txt b/rosapps/applications/net/tsclient/rdesktop/doc/licensing.txt new file mode 100644 index 00000000000..d8006d2eb72 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/licensing.txt @@ -0,0 +1,56 @@ + +To be able to connect to Microsoft Windows 2000 Terminal Services (and +probably later versions), you'll need to deal with licensing. This is +complicated. This file is supposed to contain some information about +how rdesktop works with Microsofts license systems. + +There's a lot of information on the MS web site, for example, +http://support.microsoft.com/default.aspx?scid=kb;EN-US;287687. + +From the rdesktop mailing list: + +Peter Ĺstrand , 2003-02-06 + +> We are running rdesktop 1.2 on machine A and connects to a Windows 2000 +> Server (machine B). The W2K machine has 5 real licenses installed ("Windows +> 2000 Terminal Services Client Access License", "Open" type). This can be +> verifier by using "Terminal Services Licensing". The problem is that all +> issued licenses have an expire-date. The expire date for the license issued +> to A was reached today, and no more connections could be made until we +> changed the client name (by using -n). +> +> We also have another similiar systems, with Linux machine C and W2K server +> D. This server has 200 licenses installed of the type "Select". On this +> server, the issued licenses seems to be permanent: The expire date is set +> to "-", and we have no problem with this system. +> +> The question of course is why the first system issues license with +> expiration date, while the second system issues permanent licenses. + + +Darryn Capes-Davis, 2003-02-07 + +> I have been through the problems and can tell you what is going +> on. The main difference of Machine B (Server 1) and Machine D (Server +> 2) is that from what I see Machine B has Service Pack 3 installed and +> Machine D does not. You see in Service Pack 3 there was a change made +> to TS Licencing in that Microsoft introduced a licence recovery +> mechanism. To cut to the point (I don't know the details) rdesktop 1.2 +> with SAVE_LICENCE defined works fine. In the new lic method the +> terminal server expects a valid licence to be presented to renew +> it. Otherwise it just expires it - and a day later you will see it +> actually gone (it does housekeeping once a day)! So if SAVE_LICENCE +> code is not enabled then it just expires and you can't use the licence +> until it cleans it away - and this is where a little gotcha is - if +> you move from using an rdesktop without SAVE_LICENCE to one with +> SAVE_LICENCE then it still won't recover an 'expired' licence. You +> have to wait for the daily housekeeping to clean it up - this really +> had me going for half a day or so! This is exactly what happened to +> you. +> +> The Server pre Spk 3 has the old model where licences never expire. To +> recover a licence that you never wanted to use again you have to call +> the Microsoft Clearing House. That's why they introduced the new +> method. And if you upgrade a Pre Spk3 server to Spk3 then the licences +> granted still stay with the old method - only new licences granted +> will use the new expiry method. diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/lspci-channel.txt b/rosapps/applications/net/tsclient/rdesktop/doc/lspci-channel.txt new file mode 100644 index 00000000000..78645171e2a --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/lspci-channel.txt @@ -0,0 +1,39 @@ + +Protocol overview +================= + +The lspci virtual channel makes it possible for the remote RDP server +to enumerate the local PCI devices. The protocol on this channel is +text based and line oriented: One single line per request or +response. UNIX-style LF line breaks are used. The maximum line length +is 1023, newline included. + +rdesktop acts as a server, with only one request: + + LSPCI + +The response is several lines with this syntax: + +,,,,,, + +After the last line, a line with a single dot is sent. + +Example: + +0300,102b,0525,102b,0338,04,00 +0401,8086,24d5,1028,0174,02,8f +. + + +Usage +===== + +To enable to lspci virtual channel, run rdesktop with "-r lspci". + + +References +========== + +http://www.microsoft.com/msj/1099/terminal/terminal.aspx +http://msdn.microsoft.com/library/default.asp?url=/library/en-us/termserv/termserv/terminal_services_virtual_channels.asp + diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/patches.txt b/rosapps/applications/net/tsclient/rdesktop/doc/patches.txt new file mode 100644 index 00000000000..08ffe59f7a8 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/patches.txt @@ -0,0 +1,340 @@ +This file documents some of all patches for rdesktop, floating around +the net, and how they are related to the current (CVS) version of +rdesktop. Things left to do are marked with TBD (To Be Done). + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/Makefile.diff +Description: +Makefile changes which makes it possible to compile rdesktop on SunOS +and OSF1. +Status: +Applied (slightly modified) + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/assar_19-7-2.hostlen.patch +Description: +Fix for hostnames longer than 30 chars. +Status: +Applied (revision 1.11 of secure.c) + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/backingstore+privatecolormap-for-19-3-9.patch +Description: +This adds support for 1) Private color maps (useful for 8 bpp mode) +and 2) backingstore selection. +Status: +1) is not needed anymore; rdesktop automatically uses Private color +map in 8 bpp mode. 2) is, as far as I understand, also not +need. rdesktop automatically uses a software backing store if the +Xserver does not provide one. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/ben_xwin.c.diff +Description: +Fixes for CapsLock and NumLock. +Status: +Not needed anymore, with the new keyboard mapping implementation. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/ctrl1nohang.diff +Description: +Fixes problem with ctrl1 hangs. +Status: +Not needed anymore, with the new keyboard mapping implementation. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/downkeypatch.diff +Description: +Seems to keep track of the remote modifier status. +Status: +Not needed anymore, with the new keyboard mapping implementation. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/fasttext2+nobackpixmap.patch +Description: +(From http://mail.rdesktop.org/archive/2001/msg00218.html): + +1) Added --no-backpixmap option to disable the ugly double drawing in +xwin.c (I have a very robust backing storage in my X, so I don't need +it ;) + +2) More optimizations to text draw (previous fast-text patch was +included in 192-3-6-2). In text drawing with solid background the +glyphs are drawn with stippled fill instead of XCopyPlane (runs faster +on my S3Trio64 with XFree 3.3.6, please test it on other +configurations to validate this). The WinTach not show any improvement +with this change, it seems to use all transparent background text +draws, but with a old PC Magazine Winbench (3.1) doing the scroll text +test the speed gain is significative. + +3) My Previous patch to disable backing storage in fullscreen + +Status: +1) is not relevant any more, since rdesktop only uses backing store if +the Xserver does not provide backing store. +Need to examine if 2) and 3) are still useful. TBD. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/francisco_fix_patblt.html +Description: +The colors in patterns drawn with "pattern blt" order was inverted (fg +& bg). (See the background of the yellow help banners) +Status: +Applied (in revision 1.29, 2002/07/14) + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/frank_1linerfix.html +Description: +ui_create_glyph was not called with ipattern. +Status: +Applied (in revision 1.29, 2002/07/14). + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/frank_fasttext.patch.txt +Description: +Some kind of performence improvements. +Status: +From what I can tell, this patch is no longer necessary. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/hostname-patch +Description: +(From http://mail.rdesktop.org/archive/2001/msg00163.html): + +rdesktop uses gethostname to figure out the hostname, but gethostname +under linux returns an error when the hostname is longer than the +buffer. This hack gives gethostname a 64 char buffer and then strips +the first 16 chars or upto the first '.' and puts the result in +hostname[16]. + +Status: +Applied in version 1.10 of rdesktop.c. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/hove-19-7-2endian.diff +Description: +Includes a program for testing endianness. +Status: +rdesktop determines endianness at runtime. This patch is not needed +anymore. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/mmihalik_19-7-3-keyfix-4.patch +Description: +Some kind of new alternative keyboard mapping imlementation. +Status: +Not needed anymore, with the new keyboard mapping implementation. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_fullscreen.patch +Description: +Fullscreen mode. +Status: +Applied. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_percent.txt +Description: +Makes is possible to specify RDP geometry based a percent value of the +current desktop size. +Status: +Not applied. I don't think many people will need this. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/norbert_rdp_tcp_port.diff +Description: +Command line tcp port argument. +Status: +Applied. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/patch19-7-2.xyPos.emptyPassword.patch +Description: +This patch adds: +1) Support for empty passwords +2) Support for asking for password interactively +3) Support for ++ geometry. + +Status: +1) and 2) can be solved by the -P parameter; patch not needed. +Functionality for 3) is currently missing. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-19-7-1-mmihalik-3.diff +Description: +Defines DO_GLYPH() etc. +Status: +As far as I understand, this patch is applied. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-mmihalik-1.diff +Description: +Misc drawing changes. +Status: +As far as I understand, this patch is applied. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-1.0.0-pl19-7-2-mmihalik-1.diff +Description: +Some kind of new alternative keyboard mapping implementation. +Status: +Not needed anymore, with the new keyboard mapping implementation. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-gmp.patch +Description: +Use GMP for RSA crypto. +Status: +Not needed since rdesktop now use OpenSSL for all of the crypto. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-new_kb.patch +Description: +Modifies one of the old keyboard mapping implementations in some way. +Status: +Not needed anymore, with the new keyboard mapping implementation. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop-openssl.patch +Description: +Support for linking rdesktop with OpenSSL. +Status: +Not needed anymore, rdesktop can optionally use system +OpenSSL. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop.vncviewer_patch +Description: +Hack for making the old (broken) keyboard mapping implementation work +with the VNC Xserver. +Status: +Not needed anymore, with the new keyboard mapping implementation. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdesktop_keymap.patch +Description: +Some kind of new alternative keyboard mapping implementation. +Status: +Not needed anymore, with the new keyboard mapping implementation. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/rdp-srvr-19-6-6.diff +Description: +Basic RDP server. +Status: +Not applied. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/scroll-to-death-patch.txt +Description: +Fixes scroll-to-death problem in Excel and other applications. +Status: +Not needed; fixed in another way in recent versions of rdesktop. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark-manpage-patch-19.4 +Description: +Adds a manual page. +Status: +Not needed; rdesktop contains a manual page now. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark-manpage-patch-19.4-1 +Description: +Adds a manual page. +Status: +Not needed; rdesktop contains a manual page now. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/spark_xinerama-patch2 +Description: +Adds XINERAMA support to rdesktop. +Status: +Not applied yet. TBD. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/svenni_dis_wmkeybnds.patch +Description: +Commandline flag to disable keyboard grabbing. +Status: +Applied. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/svenni_disable_bs_in_x-tiny-patch +Description: +Disables backing store for TinyX. +Status: +As far as I understand, this patch is not need any longer. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-2.license.patch +Description: +TBD +Status: +Not yet examined. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-2.secure.patch +Description: +Fixes a problem during the connection to a French NT4 TSE (a French +NT4 TSE doesn't use encryptation). +Status: +Applied. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_19-7-3_excel.patch +Description: +Makes matrixes appear better, such as those found in Excel/toad etc. +Status: +Applied. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/vincent_8bpp.patch +Description: +Support a 8bpp display (256 colours). +Status: +An enhanced version is included in rdesktop; this patch is not needed any more. + + +URL: +http://bibl4.oru.se/projects/rdesktop/patch19/patches/vpypatch.txt +Description: +Various changes for one of the old keyboard stuff. +Status: +Not needed anymore, with the new keyboard mapping implementation. diff --git a/rosapps/applications/net/tsclient/rdesktop/doc/rdesktop.1 b/rosapps/applications/net/tsclient/rdesktop/doc/rdesktop.1 new file mode 100644 index 00000000000..585cf8ec376 --- /dev/null +++ b/rosapps/applications/net/tsclient/rdesktop/doc/rdesktop.1 @@ -0,0 +1,217 @@ +.TH rdesktop 1 "November 2005" +.SH NAME +.I rdesktop +\- Remote Desktop Protocol client +.SH SYNOPSIS +.B rdesktop [options] server[:port] +.br +.SH DESCRIPTION +.I rdesktop +is a client for Remote Desktop Protocol (RDP), used in a number of Microsoft +products including Windows NT Terminal Server, Windows 2000 Server, Windows XP +and Windows 2003 Server. + +.SH OPTIONS +.TP +.BR "-u " +Username for authentication on the server. +.TP +.BR "-d " +Domain for authentication. +.TP +.BR "-s " +Startup shell for the user - starts a specific application instead of Explorer. +.TP +.BR "-c " +The initial working directory for the user. Often used in combination with -s +to set up a fixed login environment. +.TP +.BR "-p " +The password to authenticate with. Note that this may have no effect if +"Always prompt for password" is enabled on the server. WARNING: if you specify +a password on the command line it may be visible to other users when they use +tools like ps. Use -p - to make rdesktop request a password at startup (from +standard input). +.TP +.BR "-n " +Client hostname. Normally rdesktop automatically obtains the hostname of the +client. +.TP +.BR "-k " +Keyboard layout to emulate. This requires a corresponding keymap file to be +installed. The standard keymaps provided with rdesktop follow the RFC1766 +naming scheme: a language code followed by a country code if necessary - e.g. +en-us, en-gb, de, fr, sv, etc. + +The default keyboard map depends on the current locale (LC_* and LANG +environment variables). If the current locale is unknown, the default +keyboard map is en-us (a US English keyboard). + +The keyboard maps are file names, which means that they are case +sensitive. The standard keymaps are all in lowercase. + +The keyboard maps are searched relative to the directories +$HOME/.rdesktop/keymaps, KEYMAP_PATH (specified at build time), and +$CWD/keymaps, in this order. The keyboard-map argument can also be an +absolute filename. + +The special value `none' can be used instead of a keyboard map. +In this case, rdesktop will guess the scancodes from the X11 event key +codes using an internal mapping method. This method only supports the +basic alphanumeric keys and may not work properly on all platforms +so its use is discouraged. +.TP +.BR "-g " +Desktop geometry (WxH). If geometry is the special word "workarea", the geometry +will be fetched from the extended window manager hints property _NET_WORKAREA, from +the root window. The geometry can also be specified as a percentage of the whole +screen, e.g. "-g 80%". +.TP +.BR "-f" +Enable fullscreen mode. This overrides the window manager and causes the +rdesktop window to fully cover the current screen. Fullscreen mode can be +toggled at any time using Ctrl-Alt-Enter. +.TP +.BR "-b" +Force the server to send screen updates as bitmaps rather than using +higher-level drawing operations. +.TP +.BR "-A" +Enable SeamlessRDP. In this mode, rdesktop creates a X11 window for +each window on the server side. This mode requires the SeamlessRDP +server side component. When using this option, you should specify a +startup shell which launches the desired application through +SeamlessRDP. Example: rdesktop -A -s 'seamlessrdpshell notepad'. +.TP +.BR "-B" +Use the BackingStore of the Xserver instead of the integrated one in +rdesktop. +.TP +.BR "-e" +Disable encryption. This option is only needed (and will only work) if you +have a French version of NT TSE. +.TP +.BR "-E" +Disable encryption from client to server. This sends an encrypted login packet, +but everything after this is unencrypted (including interactive logins). +.TP +.BR "-m" +Do not send mouse motion events. This saves bandwidth, although some Windows +applications may rely on receiving mouse motion. +.TP +.BR "-C" +Use private colourmap. This will improve colour accuracy on an 8-bit display, +but rdesktop will appear in false colour when not focused. +.TP +.BR "-D" +Hide window manager decorations, by using MWM hints. +.TP +.BR "-K" +Do not override window manager key bindings. By default rdesktop attempts +to grab all keyboard input when it is in focus. +.TP +.BR "-S