Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming * FILE: drivers/ksfilter/ks/api.c * PURPOSE: KS API functions * PROGRAMMER: Johannes Anderwald */
#include "precomp.h"
#define NDEBUG#include <debug.h>
const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsAcquireResetValue( IN PIRP Irp, OUT KSRESET* ResetValue){ PIO_STACK_LOCATION IoStack; KSRESET* Value; NTSTATUS Status = STATUS_SUCCESS;
/* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp);
/* check if there is reset value provided */ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSRESET)) return STATUS_INVALID_PARAMETER;
if (Irp->RequestorMode == UserMode) { /* need to probe the buffer */ _SEH2_TRY { ProbeForRead(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSRESET), sizeof(UCHAR)); Value = (KSRESET*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; *ResetValue = *Value; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Exception, get the error code */ Status = _SEH2_GetExceptionCode(); } _SEH2_END; } else { Value = (KSRESET*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; *ResetValue = *Value; }
return Status;}
/* @implemented*/KSDDKAPIVOIDNTAPIKsAcquireDeviceSecurityLock( IN KSDEVICE_HEADER DevHeader, IN BOOLEAN Exclusive){ PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader;
KeEnterCriticalRegion();
if (Exclusive) { ExAcquireResourceExclusiveLite(&Header->SecurityLock, TRUE); } else { ExAcquireResourceSharedLite(&Header->SecurityLock, TRUE); }}
/* @implemented*/KSDDKAPIVOIDNTAPIKsReleaseDeviceSecurityLock( IN KSDEVICE_HEADER DevHeader){ PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader;
DPRINT("KsReleaseDevice\n");
ExReleaseResourceLite(&Header->SecurityLock); KeLeaveCriticalRegion();}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsDefaultDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PIO_STACK_LOCATION IoStack; PDEVICE_OBJECT PnpDeviceObject; NTSTATUS Status; ULONG MinorFunction;
/* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp);
/* caller wants to add the target device */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get device header */ DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
/* backup PnpBaseObject */ PnpDeviceObject = DeviceHeader->PnpDeviceObject;
/* backup minor function code */ MinorFunction = IoStack->MinorFunction;
if(MinorFunction == IRP_MN_REMOVE_DEVICE) { /* remove the device */ KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader); }
/* skip current irp stack */ IoSkipCurrentIrpStackLocation(Irp);
/* call attached pnp device object */ Status = IoCallDriver(PnpDeviceObject, Irp);
if (MinorFunction == IRP_MN_REMOVE_DEVICE) { /* time is over */ IoDetachDevice(PnpDeviceObject); /* delete device */ IoDeleteDevice(DeviceObject); } /* done */ return Status;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsDefaultDispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PKSIOBJECT_HEADER ObjectHeader; //PIO_STACK_LOCATION IoStack; PLIST_ENTRY ListEntry; NTSTATUS Status;
/* get current irp stack */ //IoStack = IoGetCurrentIrpStackLocation(Irp);
/* caller wants to add the target device */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get device header */ DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
/* FIXME locks */
/* loop our power dispatch list and call registered notification functions */ ListEntry = DeviceHeader->PowerDispatchList.Flink; /* let's go */ while(ListEntry != &DeviceHeader->PowerDispatchList) { /* get object header */ ObjectHeader = (PKSIOBJECT_HEADER)CONTAINING_RECORD(ListEntry, KSIOBJECT_HEADER, PowerDispatchEntry);
/* does it have still a cb */ if (ObjectHeader->PowerDispatch) { /* call the power cb */ Status = ObjectHeader->PowerDispatch(ObjectHeader->PowerContext, Irp); ASSERT(NT_SUCCESS(Status)); }
/* iterate to next entry */ ListEntry = ListEntry->Flink; }
/* start next power irp */ PoStartNextPowerIrp(Irp);
/* skip current irp stack location */ IoSkipCurrentIrpStackLocation(Irp);
/* let's roll */ Status = PoCallDriver(DeviceHeader->PnpDeviceObject, Irp);
/* done */ return Status;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsDefaultForwardIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; //PIO_STACK_LOCATION IoStack; NTSTATUS Status;
/* get current irp stack */ //IoStack = IoGetCurrentIrpStackLocation(Irp);
/* caller wants to add the target device */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get device header */ DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
/* forward the request to the PDO */ Status = IoCallDriver(DeviceHeader->PnpDeviceObject, Irp);
return Status;}
/* @implemented*/KSDDKAPIVOIDNTAPIKsSetDevicePnpAndBaseObject( IN KSDEVICE_HEADER Header, IN PDEVICE_OBJECT PnpDeviceObject, IN PDEVICE_OBJECT BaseDevice){ PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
DeviceHeader->PnpDeviceObject = PnpDeviceObject; DeviceHeader->BaseDevice = BaseDevice;}
/* @implemented*/KSDDKAPIPDEVICE_OBJECTNTAPIKsQueryDevicePnpObject( IN KSDEVICE_HEADER Header){ PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
/* return PnpDeviceObject */ return DeviceHeader->PnpDeviceObject;
}
/* @implemented*/KSDDKAPIACCESS_MASKNTAPIKsQueryObjectAccessMask( IN KSOBJECT_HEADER Header){ PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header;
/* return access mask */ return ObjectHeader->AccessMask;
}
/* @unimplemented*/KSDDKAPIVOIDNTAPIKsRecalculateStackDepth( IN KSDEVICE_HEADER Header, IN BOOLEAN ReuseStackLocation){ UNIMPLEMENTED;}
/* @implemented*/KSDDKAPIVOIDNTAPIKsSetTargetState( IN KSOBJECT_HEADER Header, IN KSTARGET_STATE TargetState){ PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
/* set target state */ DeviceHeader->TargetState = TargetState;}
/* @implemented*/KSDDKAPIVOIDNTAPIKsSetTargetDeviceObject( IN KSOBJECT_HEADER Header, IN PDEVICE_OBJECT TargetDevice OPTIONAL){ PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header;
if(ObjectHeader->TargetDevice) { /* there is already a target device set */ if (!TargetDevice) { /* caller wants to remove the target device */ DeviceExtension = (PDEVICE_EXTENSION)ObjectHeader->TargetDevice->DeviceExtension;
/* get device header */ DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
/* acquire lock */ KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE);
/* remove entry */ RemoveEntryList(&ObjectHeader->TargetDeviceListEntry);
/* remove device pointer */ ObjectHeader->TargetDevice = NULL;
/* release lock */ KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader); } } else { /* no target device yet set */ if (TargetDevice) { /* caller wants to add the target device */ DeviceExtension = (PDEVICE_EXTENSION)TargetDevice->DeviceExtension;
/* get device header */ DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
/* acquire lock */ KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE);
/* insert list entry */ InsertTailList(&DeviceHeader->TargetDeviceList, &ObjectHeader->TargetDeviceListEntry);
/* store target device */ ObjectHeader->TargetDevice = TargetDevice;
/* release lock */ KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader); } }
}
/* @implemented*/KSDDKAPIVOIDNTAPIKsSetPowerDispatch( IN KSOBJECT_HEADER Header, IN PFNKSCONTEXT_DISPATCH PowerDispatch OPTIONAL, IN PVOID PowerContext OPTIONAL){ PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header;
/* caller wants to add the target device */ DeviceExtension = (PDEVICE_EXTENSION)ObjectHeader->ParentDeviceObject->DeviceExtension;
/* get device header */ DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
/* acquire lock */ KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE);
if (PowerDispatch) { /* add power dispatch entry */ InsertTailList(&DeviceHeader->PowerDispatchList, &ObjectHeader->PowerDispatchEntry);
/* store function and context */ ObjectHeader->PowerDispatch = PowerDispatch; ObjectHeader->PowerContext = PowerContext; } else { /* remove power dispatch entry */ RemoveEntryList(&ObjectHeader->PowerDispatchEntry);
/* store function and context */ ObjectHeader->PowerDispatch = NULL; ObjectHeader->PowerContext = NULL;
}
/* release lock */ KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader);}
/* @implemented*/KSDDKAPIPKSOBJECT_CREATE_ITEMNTAPIKsQueryObjectCreateItem( IN KSOBJECT_HEADER Header){ PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header; return ObjectHeader->OriginalCreateItem;}
NTSTATUSKspAddCreateItemToList( OUT PLIST_ENTRY ListHead, IN ULONG ItemsCount, IN PKSOBJECT_CREATE_ITEM ItemsList){ ULONG Index; PCREATE_ITEM_ENTRY Entry;
/* add the items */ for(Index = 0; Index < ItemsCount; Index++) { /* allocate item */ Entry = AllocateItem(NonPagedPool, sizeof(CREATE_ITEM_ENTRY)); if (!Entry) { /* no memory */ return STATUS_INSUFFICIENT_RESOURCES; }
/* initialize entry */ InitializeListHead(&Entry->ObjectItemList); Entry->CreateItem = &ItemsList[Index]; Entry->ReferenceCount = 0; Entry->ItemFreeCallback = NULL;
InsertTailList(ListHead, &Entry->Entry); } return STATUS_SUCCESS;}
VOIDKspFreeCreateItems( PLIST_ENTRY ListHead){ PCREATE_ITEM_ENTRY Entry;
while(!IsListEmpty(ListHead)) { /* remove create item from list */ Entry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(RemoveHeadList(ListHead), CREATE_ITEM_ENTRY, Entry);
/* caller shouldnt have any references */ //ASSERT(Entry->ReferenceCount == 0); //ASSERT(IsListEmpty(&Entry->ObjectItemList));
/* does the creator wish notification */ if (Entry->ItemFreeCallback) { /* notify creator */ Entry->ItemFreeCallback(Entry->CreateItem); }
/* free create item entry */ FreeItem(Entry); }
}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsAllocateDeviceHeader( OUT KSDEVICE_HEADER* OutHeader, IN ULONG ItemsCount, IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL){ NTSTATUS Status = STATUS_SUCCESS; PKSIDEVICE_HEADER Header;
if (!OutHeader) return STATUS_INVALID_PARAMETER;
/* allocate a device header */ Header = AllocateItem(PagedPool, sizeof(KSIDEVICE_HEADER));
/* check for success */ if (!Header) return STATUS_INSUFFICIENT_RESOURCES;
/* clear all memory */ RtlZeroMemory(Header, sizeof(KSIDEVICE_HEADER));
/* initialize device mutex */ KeInitializeMutex(&Header->DeviceMutex, 0);
/* initialize target device list */ InitializeListHead(&Header->TargetDeviceList); /* initialize power dispatch list */ InitializeListHead(&Header->PowerDispatchList); /* initialize object bag lists */ InitializeListHead(&Header->ObjectBags);
/* initialize create item list */ InitializeListHead(&Header->ItemList);
/* initialize basic header */ Header->BasicHeader.Type = KsObjectTypeDevice; Header->BasicHeader.KsDevice = &Header->KsDevice; Header->BasicHeader.Parent.KsDevice = &Header->KsDevice;
/* are there any create items provided */ if (ItemsCount && ItemsList) { Status = KspAddCreateItemToList(&Header->ItemList, ItemsCount, ItemsList);
if (NT_SUCCESS(Status)) { /* store item count */ Header->ItemListCount = ItemsCount; } else { /* release create items */ KspFreeCreateItems(&Header->ItemList); } }
/* store result */ *OutHeader = Header;
return Status;}
/* @implemented*/KSDDKAPIVOIDNTAPIKsFreeDeviceHeader( IN KSDEVICE_HEADER DevHeader){ PKSIDEVICE_HEADER Header;
Header = (PKSIDEVICE_HEADER)DevHeader;
if (!DevHeader) return;
KspFreeCreateItems(&Header->ItemList); FreeItem(Header);}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsAllocateObjectHeader( OUT KSOBJECT_HEADER *Header, IN ULONG ItemsCount, IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL, IN PIRP Irp, IN KSDISPATCH_TABLE* Table){ PIO_STACK_LOCATION IoStack; //PDEVICE_EXTENSION DeviceExtension; //PKSIDEVICE_HEADER DeviceHeader; PKSIOBJECT_HEADER ObjectHeader; //PKSOBJECT_CREATE_ITEM CreateItem; NTSTATUS Status;
if (!Header) return STATUS_INVALID_PARAMETER_1;
if (!Irp) return STATUS_INVALID_PARAMETER_4;
if (!Table) return STATUS_INVALID_PARAMETER_5;
/* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* get device extension */ //DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; /* get device header */ //DeviceHeader = DeviceExtension->DeviceHeader;
/* sanity check */ ASSERT(IoStack->FileObject); /* check for an file object */
/* allocate the object header */ ObjectHeader = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_HEADER)); if (!ObjectHeader) return STATUS_INSUFFICIENT_RESOURCES;
/* initialize object header */ RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER));
/* initialize create item list */ InitializeListHead(&ObjectHeader->ItemList);
/* get create item */ //CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* do we have a name */ if (IoStack->FileObject->FileName.Buffer) { /* copy object class */ ObjectHeader->ObjectClass.MaximumLength = IoStack->FileObject->FileName.MaximumLength; ObjectHeader->ObjectClass.Buffer = AllocateItem(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength); if (!ObjectHeader->ObjectClass.Buffer) { FreeItem(ObjectHeader); return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&ObjectHeader->ObjectClass, &IoStack->FileObject->FileName); }
/* copy dispatch table */ RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE));
/* store create items */ if (ItemsCount && ItemsList) { Status = KspAddCreateItemToList(&ObjectHeader->ItemList, ItemsCount, ItemsList);
if (NT_SUCCESS(Status)) { /* store item count */ ObjectHeader->ItemListCount = ItemsCount; } else { /* destroy header*/ KsFreeObjectHeader(ObjectHeader); return Status; } } /* store the object in the file object */ IoStack->FileObject->FsContext2 = ObjectHeader;
/* store parent device */ ObjectHeader->ParentDeviceObject = IoGetRelatedDeviceObject(IoStack->FileObject);
/* store originating create item */ ObjectHeader->OriginalCreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* FIXME store access mask see KsQueryObjectAccessMask */ ObjectHeader->AccessMask = IoStack->Parameters.Create.SecurityContext->DesiredAccess;
/* store result */ *Header = ObjectHeader;
DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader->ObjectClass.Buffer, IoStack->FileObject, ObjectHeader);
return STATUS_SUCCESS;
}
/* @implemented*/KSDDKAPIVOIDNTAPIKsFreeObjectHeader( IN PVOID Header){ PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER) Header;
DPRINT("KsFreeObjectHeader Header %p Class %wZ\n", Header, &ObjectHeader->ObjectClass);
if (ObjectHeader->ObjectClass.Buffer) { /* release object class buffer */ FreeItem(ObjectHeader->ObjectClass.Buffer); }
if (ObjectHeader->Unknown) { /* release associated object */ ObjectHeader->Unknown->lpVtbl->Release(ObjectHeader->Unknown); }
/* free create items */ KspFreeCreateItems(&ObjectHeader->ItemList);
/* free object header */ FreeItem(ObjectHeader);
}
NTSTATUSKspAddObjectCreateItemToList( PLIST_ENTRY ListHead, IN PDRIVER_DISPATCH Create, IN PVOID Context, IN PWCHAR ObjectClass, IN PSECURITY_DESCRIPTOR SecurityDescriptor){ PLIST_ENTRY Entry; PCREATE_ITEM_ENTRY CreateEntry;
/* point to first entry */ Entry = ListHead->Flink;
while(Entry != ListHead) { /* get create entry */ CreateEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry); /* if the create item has no create routine, then it is free to use */ if (CreateEntry->CreateItem->Create == NULL) { /* sanity check */ ASSERT(IsListEmpty(&CreateEntry->ObjectItemList)); ASSERT(CreateEntry->ReferenceCount == 0); /* use free entry */ CreateEntry->CreateItem->Context = Context; CreateEntry->CreateItem->Create = Create; RtlInitUnicodeString(&CreateEntry->CreateItem->ObjectClass, ObjectClass); CreateEntry->CreateItem->SecurityDescriptor = SecurityDescriptor;
return STATUS_SUCCESS; }
if (!_wcsicmp(ObjectClass, CreateEntry->CreateItem->ObjectClass.Buffer)) { /* the same object class already exists */ return STATUS_OBJECT_NAME_COLLISION; }
/* iterate to next entry */ Entry = Entry->Flink; } return STATUS_ALLOTTED_SPACE_EXCEEDED;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsAddObjectCreateItemToDeviceHeader( IN KSDEVICE_HEADER DevHeader, IN PDRIVER_DISPATCH Create, IN PVOID Context, IN PWCHAR ObjectClass, IN PSECURITY_DESCRIPTOR SecurityDescriptor){ PKSIDEVICE_HEADER Header; NTSTATUS Status;
Header = (PKSIDEVICE_HEADER)DevHeader;
DPRINT("KsAddObjectCreateItemToDeviceHeader entered\n");
/* check if a device header has been provided */ if (!DevHeader) return STATUS_INVALID_PARAMETER_1;
/* check if a create item has been provided */ if (!Create) return STATUS_INVALID_PARAMETER_2;
/* check if a object class has been provided */ if (!ObjectClass) return STATUS_INVALID_PARAMETER_4;
/* let others do the work */ Status = KspAddObjectCreateItemToList(&Header->ItemList, Create, Context, ObjectClass, SecurityDescriptor);
if (NT_SUCCESS(Status)) { /* increment create item count */ InterlockedIncrement(&Header->ItemListCount); } DPRINT("KsAddObjectCreateItemToDeviceHeader Status %x\n", Status); return Status;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsAddObjectCreateItemToObjectHeader( IN KSOBJECT_HEADER ObjectHeader, IN PDRIVER_DISPATCH Create, IN PVOID Context, IN PWCHAR ObjectClass, IN PSECURITY_DESCRIPTOR SecurityDescriptor){ PKSIOBJECT_HEADER Header; NTSTATUS Status;
Header = (PKSIOBJECT_HEADER)ObjectHeader;
DPRINT("KsAddObjectCreateItemToDeviceHeader entered\n");
/* check if a device header has been provided */ if (!Header) return STATUS_INVALID_PARAMETER_1;
/* check if a create item has been provided */ if (!Create) return STATUS_INVALID_PARAMETER_2;
/* check if a object class has been provided */ if (!ObjectClass) return STATUS_INVALID_PARAMETER_4;
/* let's work */ Status = KspAddObjectCreateItemToList(&Header->ItemList, Create, Context, ObjectClass, SecurityDescriptor);
if (NT_SUCCESS(Status)) { /* increment create item count */ InterlockedIncrement(&Header->ItemListCount); }
return Status;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsAllocateObjectCreateItem( IN KSDEVICE_HEADER DevHeader, IN PKSOBJECT_CREATE_ITEM CreateItem, IN BOOLEAN AllocateEntry, IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL){ PCREATE_ITEM_ENTRY CreateEntry; PKSIDEVICE_HEADER Header; PKSOBJECT_CREATE_ITEM Item;
Header = (PKSIDEVICE_HEADER)DevHeader;
if (!DevHeader) return STATUS_INVALID_PARAMETER_1;
if (!CreateItem) return STATUS_INVALID_PARAMETER_2;
/* first allocate a create entry */ CreateEntry = AllocateItem(NonPagedPool, sizeof(CREATE_ITEM_ENTRY));
/* check for allocation success */ if (!CreateEntry) { /* not enough resources */ return STATUS_INSUFFICIENT_RESOURCES; }
if (AllocateEntry) { /* allocate create item */ Item = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); if (!Item) { /* no memory */ FreeItem(CreateEntry); return STATUS_INSUFFICIENT_RESOURCES; }
/* initialize descriptor */ Item->Context = CreateItem->Context; Item->Create = CreateItem->Create; Item->Flags = CreateItem->Flags; Item->SecurityDescriptor = CreateItem->SecurityDescriptor; Item->ObjectClass.Length = 0; Item->ObjectClass.MaximumLength = CreateItem->ObjectClass.MaximumLength;
/* copy object class */ Item->ObjectClass.Buffer = AllocateItem(NonPagedPool, Item->ObjectClass.MaximumLength); if (!Item->ObjectClass.Buffer) { /* release resources */ FreeItem(Item); FreeItem(CreateEntry);
return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&Item->ObjectClass, &CreateItem->ObjectClass); } else { if (ItemFreeCallback) { /* callback is only accepted when the create item is copied */ ItemFreeCallback = NULL; } /* use passed create item */ Item = CreateItem; }
/* initialize create item entry */ InitializeListHead(&CreateEntry->ObjectItemList); CreateEntry->ItemFreeCallback = ItemFreeCallback; CreateEntry->CreateItem = Item; CreateEntry->ReferenceCount = 0;
/* now insert the create item entry */ InsertTailList(&Header->ItemList, &CreateEntry->Entry);
/* increment item count */ InterlockedIncrement(&Header->ItemListCount);
return STATUS_SUCCESS;}
NTSTATUSKspObjectFreeCreateItems( IN KSDEVICE_HEADER Header, IN PKSOBJECT_CREATE_ITEM CreateItem){ UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsFreeObjectCreateItem( IN KSDEVICE_HEADER Header, IN PUNICODE_STRING CreateItem){ KSOBJECT_CREATE_ITEM Item;
RtlZeroMemory(&Item, sizeof(KSOBJECT_CREATE_ITEM)); RtlInitUnicodeString(&Item.ObjectClass, CreateItem->Buffer);
return KspObjectFreeCreateItems(Header, &Item);}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsFreeObjectCreateItemsByContext( IN KSDEVICE_HEADER Header, IN PVOID Context){ KSOBJECT_CREATE_ITEM Item;
RtlZeroMemory(&Item, sizeof(KSOBJECT_CREATE_ITEM));
Item.Context = Context;
return KspObjectFreeCreateItems(Header, &Item);}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsCreateDefaultSecurity( IN PSECURITY_DESCRIPTOR ParentSecurity OPTIONAL, OUT PSECURITY_DESCRIPTOR* DefaultSecurity){ PGENERIC_MAPPING Mapping; SECURITY_SUBJECT_CONTEXT SubjectContext; NTSTATUS Status;
/* start capturing security context of calling thread */ SeCaptureSubjectContext(&SubjectContext); /* get generic mapping */ Mapping = IoGetFileObjectGenericMapping(); /* build new descriptor */ Status = SeAssignSecurity(ParentSecurity, NULL, DefaultSecurity, FALSE, &SubjectContext, Mapping, NonPagedPool); /* release security descriptor */ SeReleaseSubjectContext(&SubjectContext); /* done */ return Status;}
/* @unimplemented*/KSDDKAPINTSTATUSNTAPIKsForwardIrp( IN PIRP Irp, IN PFILE_OBJECT FileObject, IN BOOLEAN ReuseStackLocation){ UNIMPLEMENTED; return STATUS_UNSUCCESSFUL;}
/* @unimplemented*/KSDDKAPINTSTATUSNTAPIKsForwardAndCatchIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PFILE_OBJECT FileObject, IN KSSTACK_USE StackUse){ UNIMPLEMENTED; return STATUS_UNSUCCESSFUL;}
NTSTATUSNTAPIKspSynchronousIoControlDeviceCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context){ PIO_STATUS_BLOCK IoStatusBlock = (PIO_STATUS_BLOCK)Context;
IoStatusBlock->Information = Irp->IoStatus.Information; IoStatusBlock->Status = Irp->IoStatus.Status;
return STATUS_SUCCESS;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsSynchronousIoControlDevice( IN PFILE_OBJECT FileObject, IN KPROCESSOR_MODE RequestorMode, IN ULONG IoControl, IN PVOID InBuffer, IN ULONG InSize, OUT PVOID OutBuffer, IN ULONG OutSize, OUT PULONG BytesReturned){ PKSIOBJECT_HEADER ObjectHeader; PDEVICE_OBJECT DeviceObject; KEVENT Event; PIRP Irp; IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION IoStack; NTSTATUS Status;
/* check for valid file object */ if (!FileObject) return STATUS_INVALID_PARAMETER;
/* get device object to send the request to */ DeviceObject = IoGetRelatedDeviceObject(FileObject); if (!DeviceObject) return STATUS_UNSUCCESSFUL;
/* get object header */ ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext2;
/* check if there is fast device io function */ if (ObjectHeader && ObjectHeader->DispatchTable.FastDeviceIoControl) { IoStatusBlock.Status = STATUS_UNSUCCESSFUL; IoStatusBlock.Information = 0;
/* send the request */ Status = ObjectHeader->DispatchTable.FastDeviceIoControl(FileObject, TRUE, InBuffer, InSize, OutBuffer, OutSize, IoControl, &IoStatusBlock, DeviceObject); /* check if the request was handled */ //DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information); if (Status) { /* store bytes returned */ *BytesReturned = (ULONG)IoStatusBlock.Information; /* return status */ return IoStatusBlock.Status; } }
/* initialize the event */ KeInitializeEvent(&Event, NotificationEvent, FALSE);
/* create the irp */ Irp = IoBuildDeviceIoControlRequest(IoControl, DeviceObject, InBuffer, InSize, OutBuffer, OutSize, FALSE, &Event, &IoStatusBlock);
if (!Irp) { /* no memory to allocate the irp */ return STATUS_INSUFFICIENT_RESOURCES; }
/* Store Fileobject */ IoStack = IoGetNextIrpStackLocation(Irp); IoStack->FileObject = FileObject;
if (IoControl == IOCTL_KS_WRITE_STREAM) { Irp->AssociatedIrp.SystemBuffer = OutBuffer; } else if (IoControl == IOCTL_KS_READ_STREAM) { Irp->AssociatedIrp.SystemBuffer = InBuffer; }
IoSetCompletionRoutine(Irp, KspSynchronousIoControlDeviceCompletion, (PVOID)&IoStatusBlock, TRUE, TRUE, TRUE);
Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, RequestorMode, FALSE, NULL); Status = IoStatusBlock.Status; }
*BytesReturned = (ULONG)IoStatusBlock.Information; return Status;}
/* @unimplemented*/KSDDKAPINTSTATUSNTAPIKsUnserializeObjectPropertiesFromRegistry( IN PFILE_OBJECT FileObject, IN HANDLE ParentKey OPTIONAL, IN PUNICODE_STRING RegistryPath OPTIONAL){ UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsCacheMedium( IN PUNICODE_STRING SymbolicLink, IN PKSPIN_MEDIUM Medium, IN ULONG PinDirection){ HANDLE hKey; UNICODE_STRING Path; UNICODE_STRING BasePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediumCache\\"); UNICODE_STRING GuidString; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; BOOLEAN PathAdjusted = FALSE; ULONG Value = 0;
/* first check if the medium is standard */ if (IsEqualGUIDAligned(&KSMEDIUMSETID_Standard, &Medium->Set) || IsEqualGUIDAligned(&GUID_NULL, &Medium->Set)) { /* no need to cache that */ return STATUS_SUCCESS; }
/* convert guid to string */ Status = RtlStringFromGUID(&Medium->Set, &GuidString); if (!NT_SUCCESS(Status)) return Status;
/* allocate path buffer */ Path.Length = 0; Path.MaximumLength = BasePath.MaximumLength + GuidString.MaximumLength + 10 * sizeof(WCHAR); Path.Buffer = AllocateItem(PagedPool, Path.MaximumLength); if (!Path.Buffer) { /* not enough resources */ RtlFreeUnicodeString(&GuidString); return STATUS_INSUFFICIENT_RESOURCES; }
RtlAppendUnicodeStringToString(&Path, &BasePath); RtlAppendUnicodeStringToString(&Path, &GuidString); RtlAppendUnicodeToString(&Path, L"-"); /* FIXME append real instance id */ RtlAppendUnicodeToString(&Path, L"0"); RtlAppendUnicodeToString(&Path, L"-"); /* FIXME append real instance id */ RtlAppendUnicodeToString(&Path, L"0");
/* free guid string */ RtlFreeUnicodeString(&GuidString);
/* initialize object attributes */ InitializeObjectAttributes(&ObjectAttributes, &Path, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); /* create the key */ Status = ZwCreateKey(&hKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
/* free path buffer */ FreeItem(Path.Buffer);
if (NT_SUCCESS(Status)) { /* store symbolic link */ if (SymbolicLink->Buffer[1] == L'?' && SymbolicLink->Buffer[2] == L'?') { /* replace kernel path with user mode path */ SymbolicLink->Buffer[1] = L'\\'; PathAdjusted = TRUE; }
/* store the key */ Status = ZwSetValueKey(hKey, SymbolicLink, 0, REG_DWORD, &Value, sizeof(ULONG));
if (PathAdjusted) { /* restore kernel path */ SymbolicLink->Buffer[1] = L'?'; }
ZwClose(hKey); }
/* done */ return Status;}
/* @implemented*/NTSTATUSNTAPIDllInitialize( PUNICODE_STRING RegistryPath){ return STATUS_SUCCESS;}
NTSTATUSNTAPIKopDispatchClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PKO_OBJECT_HEADER Header; PIO_STACK_LOCATION IoStack; PDEVICE_EXTENSION DeviceExtension;
/* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp);
/* get ko object header */ Header = (PKO_OBJECT_HEADER)IoStack->FileObject->FsContext2;
/* free ks object header */ KsFreeObjectHeader(Header->ObjectHeader);
/* free ko object header */ FreeItem(Header);
/* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* release bus object */ KsDereferenceBusObject((KSDEVICE_HEADER)DeviceExtension->DeviceHeader);
/* complete request */ Irp->IoStatus.Status = STATUS_SUCCESS; CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;}
static KSDISPATCH_TABLE KoDispatchTable ={ KsDispatchInvalidDeviceRequest, KsDispatchInvalidDeviceRequest, KsDispatchInvalidDeviceRequest, KsDispatchInvalidDeviceRequest, KopDispatchClose, KsDispatchQuerySecurity, KsDispatchSetSecurity, KsDispatchFastIoDeviceControlFailure, KsDispatchFastReadFailure, KsDispatchFastReadFailure,};
NTSTATUSNTAPIKopDispatchCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PKO_OBJECT_HEADER Header = NULL; PIO_STACK_LOCATION IoStack; PKO_DRIVER_EXTENSION DriverObjectExtension; NTSTATUS Status;
/* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp);
if (!IoStack->FileObject) { DPRINT1("FileObject not attached!\n"); Status = STATUS_UNSUCCESSFUL; goto cleanup; }
/* get driver object extension */ DriverObjectExtension = (PKO_DRIVER_EXTENSION)IoGetDriverObjectExtension(DeviceObject->DriverObject, (PVOID)KoDriverInitialize); if (!DriverObjectExtension) { DPRINT1("No DriverObjectExtension!\n"); Status = STATUS_UNSUCCESSFUL; goto cleanup; }
/* allocate ko object header */ Header = (PKO_OBJECT_HEADER)AllocateItem(NonPagedPool, sizeof(KO_OBJECT_HEADER)); if (!Header) { DPRINT1("failed to allocate KO_OBJECT_HEADER\n"); Status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; }
/* initialize create item */ Header->CreateItem.Create = KopDispatchCreate; RtlInitUnicodeString(&Header->CreateItem.ObjectClass, KOSTRING_CreateObject);
/* now allocate the object header */ Status = KsAllocateObjectHeader(&Header->ObjectHeader, 1, &Header->CreateItem, Irp, &KoDispatchTable); if (!NT_SUCCESS(Status)) { /* failed */ goto cleanup; }
/* FIXME * extract clsid and interface id from irp * call the standard create handler */
UNIMPLEMENTED;
IoStack->FileObject->FsContext2 = (PVOID)Header;
Irp->IoStatus.Status = Status; CompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
cleanup:
if (Header && Header->ObjectHeader) KsFreeObjectHeader(Header->ObjectHeader);
if (Header) FreeItem(Header);
Irp->IoStatus.Status = Status; CompleteRequest(Irp, IO_NO_INCREMENT); return Status;}
NTSTATUSNTAPIKopAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject){ NTSTATUS Status = STATUS_DEVICE_REMOVED; PDEVICE_OBJECT FunctionalDeviceObject= NULL; PDEVICE_OBJECT NextDeviceObject; PDEVICE_EXTENSION DeviceExtension; PKSOBJECT_CREATE_ITEM CreateItem;
/* create the device object */ Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_KS, FILE_DEVICE_SECURE_OPEN, FALSE, &FunctionalDeviceObject); if (!NT_SUCCESS(Status)) return Status;
/* allocate the create item */ CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
if (!CreateItem) { /* not enough memory */ IoDeleteDevice(FunctionalDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; }
/* initialize create item */ CreateItem->Create = KopDispatchCreate; RtlInitUnicodeString(&CreateItem->ObjectClass, KOSTRING_CreateObject);
/* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
/* now allocate the device header */ Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader, 1, CreateItem); if (!NT_SUCCESS(Status)) { /* failed */ IoDeleteDevice(FunctionalDeviceObject); FreeItem(CreateItem); return Status; }
/* now attach to device stack */ NextDeviceObject = IoAttachDeviceToDeviceStack(FunctionalDeviceObject, PhysicalDeviceObject); if (NextDeviceObject) { /* store pnp base object */ KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER)DeviceExtension->DeviceHeader, NextDeviceObject, FunctionalDeviceObject); /* set device flags */ FunctionalDeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; FunctionalDeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING; } else { /* failed */ KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceExtension->DeviceHeader); FreeItem(CreateItem); IoDeleteDevice(FunctionalDeviceObject); Status = STATUS_DEVICE_REMOVED; }
/* return result */ return Status;}
/* @implemented*/COMDDKAPINTSTATUSNTAPIKoDeviceInitialize( IN PDEVICE_OBJECT DeviceObject){ PDEVICE_EXTENSION DeviceExtension;
/* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
return KsAddObjectCreateItemToDeviceHeader((KSDEVICE_HEADER)DeviceExtension->DeviceHeader, KopDispatchCreate, NULL, KOSTRING_CreateObject, NULL);}
/* @implemented*/COMDDKAPINTSTATUSNTAPIKoDriverInitialize( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPathName, IN KoCreateObjectHandler CreateObjectHandler){ PKO_DRIVER_EXTENSION DriverObjectExtension; NTSTATUS Status;
/* allocate driver object extension */ Status = IoAllocateDriverObjectExtension(DriverObject, (PVOID)KoDriverInitialize, sizeof(KO_DRIVER_EXTENSION), (PVOID*)&DriverObjectExtension);
/* did it work */ if (NT_SUCCESS(Status)) { /* store create handler */ DriverObjectExtension->CreateObjectHandler = CreateObjectHandler;
/* Setting our IRP handlers */ DriverObject->MajorFunction[IRP_MJ_PNP] = KsDefaultDispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
/* The driver unload routine */ DriverObject->DriverUnload = KsNullDriverUnload;
/* The driver-supplied AddDevice */ DriverObject->DriverExtension->AddDevice = KopAddDevice;
/* KS handles these */ DPRINT1("Setting KS function handlers\n"); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
}
return Status;}
/* @unimplemented*/COMDDKAPIVOIDNTAPIKoRelease( IN REFCLSID ClassId){
}
/* @implemented*/KSDDKAPIVOIDNTAPIKsAcquireControl( IN PVOID Object){ PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
/* sanity check */ ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
KeWaitForSingleObject(BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL);
}
/* @implemented*/VOIDNTAPIKsReleaseControl( IN PVOID Object){ PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
/* sanity check */ ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
KeReleaseMutex(BasicHeader->ControlMutex, FALSE);}
/* @implemented*/KSDDKAPIVOIDNTAPIKsAcquireDevice( IN PKSDEVICE Device){ IKsDevice *KsDevice; PKSIDEVICE_HEADER DeviceHeader;
DPRINT("KsAcquireDevice\n"); DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
/* get device interface*/ KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* acquire device mutex */ KsDevice->lpVtbl->AcquireDevice(KsDevice);}
/* @implemented*/VOIDNTAPIKsReleaseDevice( IN PKSDEVICE Device){ IKsDevice *KsDevice; PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
/* get device interface*/ KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* release device mutex */ KsDevice->lpVtbl->ReleaseDevice(KsDevice);}
/* @implemented*/KSDDKAPIVOIDNTAPIKsTerminateDevice( IN PDEVICE_OBJECT DeviceObject){ IKsDevice *KsDevice; PKSIDEVICE_HEADER DeviceHeader; PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get device header */ DeviceHeader = DeviceExtension->DeviceHeader;
/* get device interface*/ KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown;
/* now free device header */ KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader);
/* release interface when available */ if (KsDevice) { /* delete IKsDevice interface */ KsDevice->lpVtbl->Release(KsDevice); }}
/* @implemented*/KSDDKAPIVOIDNTAPIKsCompletePendingRequest( IN PIRP Irp){ PIO_STACK_LOCATION IoStack;
/* get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp);
/* sanity check */ ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
if (IoStack->MajorFunction != IRP_MJ_CLOSE) { /* can be completed immediately */ CompleteRequest(Irp, IO_NO_INCREMENT); return; }
/* did close operation fail */ if (!NT_SUCCESS(Irp->IoStatus.Status)) { /* closing failed, complete irp */ CompleteRequest(Irp, IO_NO_INCREMENT); return; }
/* FIXME * delete object / device header * remove dead pin / filter instance */ UNIMPLEMENTED;
}
NTSTATUSNTAPIKspSetGetBusDataCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context){ /* signal completion */ KeSetEvent((PRKEVENT)Context, IO_NO_INCREMENT, FALSE);
/* more work needs be done, so dont free the irp */ return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUSKspDeviceSetGetBusData( IN PDEVICE_OBJECT DeviceObject, IN ULONG DataType, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length, IN BOOL bGet){ PIO_STACK_LOCATION IoStack; PIRP Irp; NTSTATUS Status; KEVENT Event;
/* allocate the irp */ Irp = IoAllocateIrp(1, /*FIXME */ FALSE);
if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
/* initialize the event */ KeInitializeEvent(&Event, NotificationEvent, FALSE);
/* get next stack location */ IoStack = IoGetNextIrpStackLocation(Irp);
/* setup a completion routine */ IoSetCompletionRoutine(Irp, KspSetGetBusDataCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
/* setup parameters */ IoStack->Parameters.ReadWriteConfig.Buffer = Buffer; IoStack->Parameters.ReadWriteConfig.Length = Length; IoStack->Parameters.ReadWriteConfig.Offset = Offset; IoStack->Parameters.ReadWriteConfig.WhichSpace = DataType; /* setup function code */ IoStack->MajorFunction = IRP_MJ_PNP; IoStack->MinorFunction = (bGet ? IRP_MN_READ_CONFIG : IRP_MN_WRITE_CONFIG);
/* lets call the driver */ Status = IoCallDriver(DeviceObject, Irp);
/* is the request still pending */ if (Status == STATUS_PENDING) { /* have a nap */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); /* update status */ Status = Irp->IoStatus.Status; }
/* free the irp */ IoFreeIrp(Irp); /* done */ return Status;}
/* @implemented*/KSDDKAPIULONGNTAPIKsDeviceSetBusData( IN PKSDEVICE Device, IN ULONG DataType, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length){ return KspDeviceSetGetBusData(Device->PhysicalDeviceObject, /* is this right? */ DataType, Buffer, Offset, Length, FALSE);}
/* @implemented*/KSDDKAPIULONGNTAPIKsDeviceGetBusData( IN PKSDEVICE Device, IN ULONG DataType, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length){ return KspDeviceSetGetBusData(Device->PhysicalDeviceObject, /* is this right? */ DataType, Buffer, Offset, Length, TRUE);
}
/* @implemented*/KSDDKAPIvoidNTAPIKsDeviceRegisterAdapterObject( IN PKSDEVICE Device, IN PADAPTER_OBJECT AdapterObject, IN ULONG MaxMappingsByteCount, IN ULONG MappingTableStride){ PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
DeviceHeader->AdapterObject = AdapterObject; DeviceHeader->MaxMappingsByteCount = MaxMappingsByteCount; DeviceHeader->MappingTableStride = MappingTableStride;
}
/* @implemented*/KSDDKAPIPVOIDNTAPIKsGetFirstChild( IN PVOID Object){ PKSBASIC_HEADER BasicHeader;
/* get the basic header */ BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
/* type has to be either a device or a filter factory */ ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory);
return (PVOID)BasicHeader->FirstChild.Filter;}
/* @implemented*/KSDDKAPIPVOIDNTAPIKsGetNextSibling( IN PVOID Object){ PKSBASIC_HEADER BasicHeader;
/* get the basic header */ BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
return (PVOID)BasicHeader->Next.Pin;}
ULONGKspCountMethodSets( IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL){ ULONG Index, SubIndex, Count; BOOL bFound;
if (!AutomationTableA) return AutomationTableB->MethodSetsCount;
if (!AutomationTableB) return AutomationTableA->MethodSetsCount;
DPRINT("AutomationTableA MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableA->MethodItemSize, AutomationTableA->MethodSetsCount); DPRINT("AutomationTableB MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableB->MethodItemSize, AutomationTableB->MethodSetsCount);
if (AutomationTableA->MethodItemSize && AutomationTableB->MethodItemSize) { /* sanity check */ ASSERT(AutomationTableA->MethodItemSize == AutomationTableB->MethodItemSize); }
/* now iterate all property sets and compare their guids */ Count = AutomationTableA->MethodSetsCount;
for(Index = 0; Index < AutomationTableB->MethodSetsCount; Index++) { /* set found to false */ bFound = FALSE;
for(SubIndex = 0; SubIndex < AutomationTableA->MethodSetsCount; SubIndex++) { if (IsEqualGUIDAligned(AutomationTableB->MethodSets[Index].Set, AutomationTableA->MethodSets[SubIndex].Set)) { /* same property set found */ bFound = TRUE; break; } }
if (!bFound) Count++; }
return Count;}
ULONGKspCountEventSets( IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL){ ULONG Index, SubIndex, Count; BOOL bFound;
if (!AutomationTableA) return AutomationTableB->EventSetsCount;
if (!AutomationTableB) return AutomationTableA->EventSetsCount;
DPRINT("AutomationTableA EventItemSize %lu EventSetsCount %lu\n", AutomationTableA->EventItemSize, AutomationTableA->EventSetsCount); DPRINT("AutomationTableB EventItemSize %lu EventSetsCount %lu\n", AutomationTableB->EventItemSize, AutomationTableB->EventSetsCount);
if (AutomationTableA->EventItemSize && AutomationTableB->EventItemSize) { /* sanity check */ ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize); }
/* now iterate all Event sets and compare their guids */ Count = AutomationTableA->EventSetsCount;
for(Index = 0; Index < AutomationTableB->EventSetsCount; Index++) { /* set found to false */ bFound = FALSE;
for(SubIndex = 0; SubIndex < AutomationTableA->EventSetsCount; SubIndex++) { if (IsEqualGUIDAligned(AutomationTableB->EventSets[Index].Set, AutomationTableA->EventSets[SubIndex].Set)) { /* same Event set found */ bFound = TRUE; break; } }
if (!bFound) Count++; }
return Count;}
ULONGKspCountPropertySets( IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL){ ULONG Index, SubIndex, Count; BOOL bFound;
if (!AutomationTableA) return AutomationTableB->PropertySetsCount;
if (!AutomationTableB) return AutomationTableA->PropertySetsCount;
/* sanity check */ DPRINT("AutomationTableA PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount); DPRINT("AutomationTableB PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount); ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize);
/* now iterate all property sets and compare their guids */ Count = AutomationTableA->PropertySetsCount;
for(Index = 0; Index < AutomationTableB->PropertySetsCount; Index++) { /* set found to false */ bFound = FALSE;
for(SubIndex = 0; SubIndex < AutomationTableA->PropertySetsCount; SubIndex++) { if (IsEqualGUIDAligned(AutomationTableB->PropertySets[Index].Set, AutomationTableA->PropertySets[SubIndex].Set)) { /* same property set found */ bFound = TRUE; break; } }
if (!bFound) Count++; }
return Count;}
NTSTATUSKspCopyMethodSets( OUT PKSAUTOMATION_TABLE Table, IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL){ ULONG Index, SubIndex, Count; BOOL bFound;
if (!AutomationTableA) { /* copy of property set */ RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableB->MethodSetsCount); return STATUS_SUCCESS; } else if (!AutomationTableB) { /* copy of property set */ RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount); return STATUS_SUCCESS; }
/* first copy all property items from dominant table */ RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount); /* set counter */ Count = AutomationTableA->MethodSetsCount;
/* now copy entries which aren't available in the dominant table */ for(Index = 0; Index < AutomationTableB->MethodSetsCount; Index++) { /* set found to false */ bFound = FALSE;
for(SubIndex = 0; SubIndex < AutomationTableA->MethodSetsCount; SubIndex++) { if (IsEqualGUIDAligned(AutomationTableB->MethodSets[Index].Set, AutomationTableA->MethodSets[SubIndex].Set)) { /* same property set found */ bFound = TRUE; break; } }
if (!bFound) { /* copy new property item set */ RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], sizeof(KSMETHOD_SET)); Count++; } }
return STATUS_SUCCESS;}
VOIDKspAddPropertyItem( OUT PKSPROPERTY_SET OutPropertySet, IN PKSPROPERTY_ITEM PropertyItem, IN ULONG PropertyItemSize){ PKSPROPERTY_ITEM CurrentPropertyItem; ULONG Index;
// check if the property item is already present CurrentPropertyItem = (PKSPROPERTY_ITEM)OutPropertySet->PropertyItem; for(Index = 0; Index < OutPropertySet->PropertiesCount; Index++) { if (CurrentPropertyItem->PropertyId == PropertyItem->PropertyId) { // item already present return; }
// next item CurrentPropertyItem = (PKSPROPERTY_ITEM)((ULONG_PTR)CurrentPropertyItem + PropertyItemSize); } // add item RtlCopyMemory(CurrentPropertyItem, PropertyItem, PropertyItemSize); OutPropertySet->PropertiesCount++;}
NTSTATUSKspMergePropertySet( OUT PKSAUTOMATION_TABLE Table, OUT PKSPROPERTY_SET OutPropertySet, IN PKSPROPERTY_SET PropertySetA, IN PKSPROPERTY_SET PropertySetB, IN KSOBJECT_BAG Bag OPTIONAL){ ULONG PropertyCount, Index; PKSPROPERTY_ITEM PropertyItem, CurrentPropertyItem; NTSTATUS Status;
// max properties PropertyCount = PropertySetA->PropertiesCount + PropertySetB->PropertiesCount;
// allocate items PropertyItem = AllocateItem(NonPagedPool, Table->PropertyItemSize * PropertyCount); if (!PropertyItem) return STATUS_INSUFFICIENT_RESOURCES;
if (Bag) { /* add table to object bag */ Status = KsAddItemToObjectBag(Bag, PropertyItem, NULL); /* check for success */ if (!NT_SUCCESS(Status)) { /* free table */ FreeItem(Table); return Status; } }
// copy entries from dominant table RtlCopyMemory(PropertyItem, PropertySetA->PropertyItem, Table->PropertyItemSize * PropertySetA->PropertiesCount);
// init property set OutPropertySet->PropertiesCount = PropertySetA->PropertiesCount; OutPropertySet->PropertyItem = PropertyItem;
// copy other entries CurrentPropertyItem = (PKSPROPERTY_ITEM)PropertySetB->PropertyItem; for(Index = 0; Index < PropertySetB->PropertiesCount; Index++) {
// add entries KspAddPropertyItem(OutPropertySet, CurrentPropertyItem, Table->PropertyItemSize);
// next entry CurrentPropertyItem = (PKSPROPERTY_ITEM)((ULONG_PTR)CurrentPropertyItem + Table->PropertyItemSize); }
// done return STATUS_SUCCESS;}
NTSTATUSKspCopyPropertySets( OUT PKSAUTOMATION_TABLE Table, IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL, IN KSOBJECT_BAG Bag OPTIONAL){ ULONG Index, SubIndex, Count; BOOL bFound; NTSTATUS Status;
if (!AutomationTableA) { /* copy of property set */ RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableB->PropertySetsCount); return STATUS_SUCCESS; } else if (!AutomationTableB) { /* copy of property set */ RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount); return STATUS_SUCCESS; }
/* first copy all property items from dominant table */ RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount); /* set counter */ Count = AutomationTableA->PropertySetsCount;
/* now copy entries which aren't available in the dominant table */ for(Index = 0; Index < AutomationTableB->PropertySetsCount; Index++) { /* set found to false */ bFound = FALSE;
for(SubIndex = 0; SubIndex < AutomationTableA->PropertySetsCount; SubIndex++) { if (IsEqualGUIDAligned(AutomationTableB->PropertySets[Index].Set, AutomationTableA->PropertySets[SubIndex].Set)) { /* same property set found */ bFound = TRUE; break; } }
if (!bFound) { /* copy new property item set */ RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], sizeof(KSPROPERTY_SET)); Count++; } else { // merge property sets Status = KspMergePropertySet(Table, (PKSPROPERTY_SET)&Table->PropertySets[SubIndex], (PKSPROPERTY_SET)&AutomationTableA->PropertySets[SubIndex], (PKSPROPERTY_SET)&AutomationTableB->PropertySets[Index], Bag); if (!NT_SUCCESS(Status)) { // failed to merge DPRINT1("[KS] Failed to merge %x\n", Status); return Status; } } }
return STATUS_SUCCESS;}
NTSTATUSKspCopyEventSets( OUT PKSAUTOMATION_TABLE Table, IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL){ ULONG Index, SubIndex, Count; BOOL bFound;
if (!AutomationTableA) { /* copy of Event set */ RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, sizeof(KSEVENT_SET) * AutomationTableB->EventSetsCount); return STATUS_SUCCESS; } else if (!AutomationTableB) { /* copy of Event set */ RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount); return STATUS_SUCCESS; }
/* first copy all Event items from dominant table */ RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount); /* set counter */ Count = AutomationTableA->EventSetsCount;
/* now copy entries which aren't available in the dominant table */ for(Index = 0; Index < AutomationTableB->EventSetsCount; Index++) { /* set found to false */ bFound = FALSE;
for(SubIndex = 0; SubIndex < AutomationTableA->EventSetsCount; SubIndex++) { if (IsEqualGUIDAligned(AutomationTableB->EventSets[Index].Set, AutomationTableA->EventSets[SubIndex].Set)) { /* same Event set found */ bFound = TRUE; break; } }
if (!bFound) { /* copy new Event item set */ RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], sizeof(KSEVENT_SET)); Count++; } }
return STATUS_SUCCESS;}
/* @implemented*/NTSTATUSNTAPIKsMergeAutomationTables( OUT PKSAUTOMATION_TABLE *AutomationTableAB, IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL, IN KSOBJECT_BAG Bag OPTIONAL){ PKSAUTOMATION_TABLE Table; NTSTATUS Status = STATUS_SUCCESS;
if (!AutomationTableA && !AutomationTableB) { /* nothing to merge */ return STATUS_SUCCESS; }
/* allocate an automation table */ Table = AllocateItem(NonPagedPool, sizeof(KSAUTOMATION_TABLE)); if (!Table) return STATUS_INSUFFICIENT_RESOURCES;
if (Bag) { /* add table to object bag */ Status = KsAddItemToObjectBag(Bag, Table, NULL); /* check for success */ if (!NT_SUCCESS(Status)) { /* free table */ FreeItem(Table); return Status; } }
/* count property sets */ Table->PropertySetsCount = KspCountPropertySets(AutomationTableA, AutomationTableB);
if (Table->PropertySetsCount) { if (AutomationTableA) { /* use item size from dominant automation table */ Table->PropertyItemSize = AutomationTableA->PropertyItemSize; } else { /* use item size from 2nd automation table */ Table->PropertyItemSize = AutomationTableB->PropertyItemSize; }
if (AutomationTableA && AutomationTableB) { // FIXME handle different property item sizes ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize); }
/* now allocate the property sets */ Table->PropertySets = AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * Table->PropertySetsCount);
if (!Table->PropertySets) { /* not enough memory */ goto cleanup; }
if (Bag) { /* add set to property bag */ Status = KsAddItemToObjectBag(Bag, (PVOID)Table->PropertySets, NULL); /* check for success */ if (!NT_SUCCESS(Status)) { /* cleanup table */ goto cleanup; } } /* now copy the property sets */ Status = KspCopyPropertySets(Table, AutomationTableA, AutomationTableB, Bag); if(!NT_SUCCESS(Status)) goto cleanup;
}
/* now count the method sets */ Table->MethodSetsCount = KspCountMethodSets(AutomationTableA, AutomationTableB);
if (Table->MethodSetsCount) { if (AutomationTableA) { /* use item size from dominant automation table */ Table->MethodItemSize = AutomationTableA->MethodItemSize; } else { /* use item size from 2nd automation table */ Table->MethodItemSize = AutomationTableB->MethodItemSize; }
/* now allocate the property sets */ Table->MethodSets = AllocateItem(NonPagedPool, sizeof(KSMETHOD_SET) * Table->MethodSetsCount);
if (!Table->MethodSets) { /* not enough memory */ goto cleanup; }
if (Bag) { /* add set to property bag */ Status = KsAddItemToObjectBag(Bag, (PVOID)Table->MethodSets, NULL); /* check for success */ if (!NT_SUCCESS(Status)) { /* cleanup table */ goto cleanup; } } /* now copy the property sets */ Status = KspCopyMethodSets(Table, AutomationTableA, AutomationTableB); if(!NT_SUCCESS(Status)) goto cleanup; }
/* now count the event sets */ Table->EventSetsCount = KspCountEventSets(AutomationTableA, AutomationTableB);
if (Table->EventSetsCount) { if (AutomationTableA) { /* use item size from dominant automation table */ Table->EventItemSize = AutomationTableA->EventItemSize; } else { /* use item size from 2nd automation table */ Table->EventItemSize = AutomationTableB->EventItemSize; }
/* now allocate the property sets */ Table->EventSets = AllocateItem(NonPagedPool, sizeof(KSEVENT_SET) * Table->EventSetsCount);
if (!Table->EventSets) { /* not enough memory */ goto cleanup; }
if (Bag) { /* add set to property bag */ Status = KsAddItemToObjectBag(Bag, (PVOID)Table->EventSets, NULL); /* check for success */ if (!NT_SUCCESS(Status)) { /* cleanup table */ goto cleanup; } } /* now copy the property sets */ Status = KspCopyEventSets(Table, AutomationTableA, AutomationTableB); if(!NT_SUCCESS(Status)) goto cleanup; }
/* store result */ *AutomationTableAB = Table;
return Status;
cleanup:
if (Table) { if (Table->PropertySets) { /* clean property sets */ if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->PropertySets, TRUE))) FreeItem((PVOID)Table->PropertySets); }
if (Table->MethodSets) { /* clean property sets */ if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->MethodSets, TRUE))) FreeItem((PVOID)Table->MethodSets); }
if (Table->EventSets) { /* clean property sets */ if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->EventSets, TRUE))) FreeItem((PVOID)Table->EventSets); }
if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, Table, TRUE))) FreeItem(Table); }
return STATUS_INSUFFICIENT_RESOURCES;}
/* @unimplemented*/KSDDKAPIPUNKNOWNNTAPIKsRegisterAggregatedClientUnknown( IN PVOID Object, IN PUNKNOWN ClientUnknown){ PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
/* sanity check */ ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
if (BasicHeader->ClientAggregate) { /* release existing aggregate */ BasicHeader->ClientAggregate->lpVtbl->Release(BasicHeader->ClientAggregate); }
/* increment reference count */ ClientUnknown->lpVtbl->AddRef(ClientUnknown);
/* store client aggregate */ BasicHeader->ClientAggregate = ClientUnknown;
/* return objects outer unknown */ return BasicHeader->OuterUnknown;}
/* @unimplemented*/NTSTATUSNTAPIKsRegisterFilterWithNoKSPins( IN PDEVICE_OBJECT DeviceObject, IN const GUID* InterfaceClassGUID, IN ULONG PinCount, IN BOOL* PinDirection, IN KSPIN_MEDIUM* MediumList, IN GUID* CategoryList OPTIONAL){ ULONG Size, Index; NTSTATUS Status; PWSTR SymbolicLinkList; //PUCHAR Buffer; HANDLE hKey; UNICODE_STRING InterfaceString; //UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData");
if (!InterfaceClassGUID || !PinCount || !PinDirection || !MediumList) { /* all these parameters are required */ return STATUS_INVALID_PARAMETER; }
/* calculate filter data value size */ Size = PinCount * sizeof(KSPIN_MEDIUM); if (CategoryList) { /* add category list */ Size += PinCount * sizeof(GUID); }
/* FIXME generate filter data blob */ UNIMPLEMENTED;
/* get symbolic link list */ Status = IoGetDeviceInterfaces(InterfaceClassGUID, DeviceObject, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &SymbolicLinkList); if (NT_SUCCESS(Status)) { /* initialize first symbolic link */ RtlInitUnicodeString(&InterfaceString, SymbolicLinkList);
/* open first device interface registry key */ Status = IoOpenDeviceInterfaceRegistryKey(&InterfaceString, GENERIC_WRITE, &hKey);
if (NT_SUCCESS(Status)) { /* write filter data */ //Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Buffer, Size);
/* close the key */ ZwClose(hKey); }
if (PinCount) { /* update medium cache */ for(Index = 0; Index < PinCount; Index++) { KsCacheMedium(&InterfaceString, &MediumList[Index], PinDirection[Index]); } }
/* free the symbolic link list */ FreeItem(SymbolicLinkList); }
return Status;}