Something went wrong. Try again.
Reactos
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: dll/win32/kernel32/client/console/console.c * PURPOSE: Win32 server console functions * PROGRAMMERS: James Tabor <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net> * Hermes Belusca-Maito (hermes.belusca@sfr.fr) */
/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG#include <debug.h>
/* GLOBALS ********************************************************************/
extern RTL_CRITICAL_SECTION ConsoleLock;extern BOOLEAN ConsoleInitialized;
/* Console reserved "file" names */static LPCWSTR BaseConFileName = CONSOLE_FILE_NAME;static LPCWSTR BaseConInputFileName = CONSOLE_INPUT_FILE_NAME;static LPCWSTR BaseConOutputFileName = CONSOLE_OUTPUT_FILE_NAME;
/* Console Control handling */static PHANDLER_ROUTINE InitialHandler[1];static PHANDLER_ROUTINE* CtrlHandlers;static ULONG NrCtrlHandlers;static ULONG NrAllocatedHandlers;static BOOLEAN LastCloseNotify = FALSE;
extern BOOL WINAPI IsDebuggerPresent(VOID);
/* Console Input facilities */HANDLE InputWaitHandle = INVALID_HANDLE_VALUE;
#define EXENAME_LENGTH (255 + 1)static RTL_CRITICAL_SECTION ExeNameLock;static BOOLEAN ExeNameInitialized;static WCHAR ExeNameBuffer[EXENAME_LENGTH]; // NULL-terminatedstatic USHORT ExeNameLength; // Count in number of characters without NULLstatic WCHAR StartDirBuffer[MAX_PATH + 1]; // NULL-terminatedstatic USHORT StartDirLength; // Count in number of characters without NULL
/* Default Console Control Handler ********************************************/
static BOOLWINAPIDefaultConsoleCtrlHandler(DWORD Event){ DPRINT("Default handler called: %lx\n", Event); switch(Event) { case CTRL_C_EVENT: DPRINT("Ctrl-C Event\n"); break;
case CTRL_BREAK_EVENT: DPRINT("Ctrl-Break Event\n"); break;
case CTRL_CLOSE_EVENT: DPRINT("Ctrl Close Event\n"); break;
case CTRL_LAST_CLOSE_EVENT: DPRINT("Ctrl Last Close Event\n"); break;
case CTRL_LOGOFF_EVENT: DPRINT("Ctrl Logoff Event\n"); break;
case CTRL_SHUTDOWN_EVENT: DPRINT("Ctrl Shutdown Event\n"); break; }
ExitProcess(CONTROL_C_EXIT); return TRUE;}
DWORDWINAPIConsoleControlDispatcher(IN LPVOID lpThreadParameter){ DWORD nExitCode = 0; DWORD CodeAndFlag = PtrToUlong(lpThreadParameter); DWORD nCode = CodeAndFlag & MAXLONG; UINT i; EXCEPTION_RECORD erException;
DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
switch(nCode) { case CTRL_C_EVENT: case CTRL_BREAK_EVENT: { if (IsDebuggerPresent()) { erException.ExceptionCode = (nCode == CTRL_C_EVENT ? DBG_CONTROL_C : DBG_CONTROL_BREAK); erException.ExceptionFlags = 0; erException.ExceptionRecord = NULL; erException.ExceptionAddress = DefaultConsoleCtrlHandler; erException.NumberParameters = 0;
_SEH2_TRY { RtlRaiseException(&erException); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { RtlEnterCriticalSection(&ConsoleLock);
if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1)) { for (i = NrCtrlHandlers; i > 0; i--) { if (CtrlHandlers[i - 1](nCode)) break; } }
RtlLeaveCriticalSection(&ConsoleLock); } _SEH2_END;
ExitThread(0); } break; }
case CTRL_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: break;
case CTRL_LAST_CLOSE_EVENT: /* * In case the console app hasn't register for last close notification, * just kill this console handler thread. We don't want that such apps * get killed for unexpected reasons. On the contrary apps that registered * can be killed because they expect to be. */ if (!LastCloseNotify) ExitThread(0); break;
case 4: ExitProcess(CONTROL_C_EXIT); break;
default: ASSERT(FALSE); break; }
ASSERT(ConsoleInitialized);
RtlEnterCriticalSection(&ConsoleLock);
nExitCode = 0; if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1)) { for (i = NrCtrlHandlers; i > 0; i--) { if ((i == 1) && (CodeAndFlag & MINLONG) && ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT))) { DPRINT("Skipping system/service apps\n"); break; }
if (CtrlHandlers[i - 1](nCode)) { switch(nCode) { case CTRL_CLOSE_EVENT: case CTRL_LAST_CLOSE_EVENT: case CTRL_LOGOFF_EVENT: case CTRL_SHUTDOWN_EVENT: nExitCode = CodeAndFlag; break; } break; } } }
RtlLeaveCriticalSection(&ConsoleLock);
ExitThread(nExitCode); return STATUS_SUCCESS;}
VOIDInitializeCtrlHandling(VOID){ /* Initialize Console Ctrl Handler */ NrAllocatedHandlers = NrCtrlHandlers = 1; CtrlHandlers = InitialHandler; CtrlHandlers[0] = DefaultConsoleCtrlHandler;}
/* Input EXE Name Support *****************************************************/
VOIDInitExeName(VOID){ NTSTATUS Status; PPEB Peb = NtCurrentPeb(); PCURDIR CurrentDirectory = &Peb->ProcessParameters->CurrentDirectory; PLDR_DATA_TABLE_ENTRY ImageEntry;
if (ExeNameInitialized) return;
/* Initialize the EXE name lock */ Status = RtlInitializeCriticalSection(&ExeNameLock); if (!NT_SUCCESS(Status)) return; ExeNameInitialized = TRUE;
ImageEntry = CONTAINING_RECORD(Peb->Ldr->InLoadOrderModuleList.Flink, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
/* Retrieve the EXE name, NULL-terminate it... */ ExeNameLength = min(sizeof(ExeNameBuffer)/sizeof(ExeNameBuffer[0]), ImageEntry->BaseDllName.Length / sizeof(WCHAR)); RtlCopyMemory(ExeNameBuffer, ImageEntry->BaseDllName.Buffer, ImageEntry->BaseDllName.Length); ExeNameBuffer[ExeNameLength] = UNICODE_NULL;
/* ... and retrieve the current directory path and NULL-terminate it. */ StartDirLength = min(sizeof(StartDirBuffer)/sizeof(StartDirBuffer[0]), CurrentDirectory->DosPath.Length / sizeof(WCHAR)); RtlCopyMemory(StartDirBuffer, CurrentDirectory->DosPath.Buffer, CurrentDirectory->DosPath.Length); StartDirBuffer[StartDirLength] = UNICODE_NULL;}
/* * NOTE: * The "LPDWORD Length" parameters point on input to the maximum size of * the buffers that can hold data (if != 0), and on output they hold the * real size of the data. If "Length" are == 0 on input, then on output * they receive the full size of the data. * The "LPWSTR* String" parameters have a double meaning: * - when "CaptureStrings" is TRUE, data is copied to the buffers pointed * by the pointers (*String). * - when "CaptureStrings" is FALSE, "*String" are set to the addresses of * the source data. */VOIDSetUpAppName(IN BOOLEAN CaptureStrings, IN OUT LPDWORD CurDirLength, IN OUT LPWSTR* CurDir, IN OUT LPDWORD AppNameLength, IN OUT LPWSTR* AppName){ DWORD Length;
/* Retrieve the needed buffer size */ Length = (StartDirLength + 1) * sizeof(WCHAR); if (*CurDirLength > 0) Length = min(Length, *CurDirLength); *CurDirLength = Length;
/* Capture the data if needed, or, return a pointer to it */ if (CaptureStrings) { /* * Length is always >= sizeof(WCHAR). Copy everything but the * possible trailing NULL character, and then NULL-terminate. */ Length -= sizeof(WCHAR); RtlCopyMemory(*CurDir, StartDirBuffer, Length); (*CurDir)[Length / sizeof(WCHAR)] = UNICODE_NULL; } else { *CurDir = StartDirBuffer; }
/* Retrieve the needed buffer size */ Length = (ExeNameLength + 1) * sizeof(WCHAR); if (*AppNameLength > 0) Length = min(Length, *AppNameLength); *AppNameLength = Length;
/* Capture the data if needed, or, return a pointer to it */ if (CaptureStrings) { /* * Length is always >= sizeof(WCHAR). Copy everything but the * possible trailing NULL character, and then NULL-terminate. */ Length -= sizeof(WCHAR); RtlCopyMemory(*AppName, ExeNameBuffer, Length); (*AppName)[Length / sizeof(WCHAR)] = UNICODE_NULL; } else { *AppName = ExeNameBuffer; }}
USHORTGetCurrentExeName(OUT PWCHAR ExeName, IN USHORT BufferSize){ USHORT ExeLength;
if (ExeNameInitialized) { RtlEnterCriticalSection(&ExeNameLock);
if (BufferSize > ExeNameLength * sizeof(WCHAR)) BufferSize = ExeNameLength * sizeof(WCHAR);
RtlCopyMemory(ExeName, ExeNameBuffer, BufferSize);
RtlLeaveCriticalSection(&ExeNameLock); ExeLength = BufferSize; } else { *ExeName = UNICODE_NULL; ExeLength = 0; }
return ExeLength;}
/* FUNCTIONS ******************************************************************/
LPCWSTRIntCheckForConsoleFileName(IN LPCWSTR pszName, IN DWORD dwDesiredAccess){ LPCWSTR ConsoleName = pszName; ULONG DeviceNameInfo;
/* * Check whether we deal with a DOS device, and if so, * strip the path till the file name. * Therefore, things like \\.\CON or C:\some_path\CONIN$ * are transformed into CON or CONIN$, for example. */ DeviceNameInfo = RtlIsDosDeviceName_U(pszName); if (DeviceNameInfo != 0) { ConsoleName = (LPCWSTR)((ULONG_PTR)ConsoleName + ((DeviceNameInfo >> 16) & 0xFFFF)); }
/* Return a standard console "file" name according to what we passed in parameters */ if (_wcsicmp(ConsoleName, BaseConInputFileName) == 0) { return BaseConInputFileName; } else if (_wcsicmp(ConsoleName, BaseConOutputFileName) == 0) { return BaseConOutputFileName; } else if (_wcsicmp(ConsoleName, BaseConFileName) == 0) { if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_READ) { return BaseConInputFileName; } else if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_WRITE) { return BaseConOutputFileName; } }
/* If we are there, that means that either the file name or the desired access are wrong */ return NULL;}
/* * @implemented (Undocumented) * @note See http://undoc.airesoft.co.uk/kernel32.dll/ConsoleMenuControl.php */HMENUWINAPIDECLSPEC_HOTPATCHConsoleMenuControl(HANDLE hConsoleOutput, DWORD dwCmdIdLow, DWORD dwCmdIdHigh){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_MENUCONTROL MenuControlRequest = &ApiMessage.Data.MenuControlRequest;
MenuControlRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; MenuControlRequest->OutputHandle = hConsoleOutput; MenuControlRequest->CmdIdLow = dwCmdIdLow; MenuControlRequest->CmdIdHigh = dwCmdIdHigh; MenuControlRequest->MenuHandle = NULL;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepMenuControl), sizeof(*MenuControlRequest));
return MenuControlRequest->MenuHandle;}
/* * @implemented */HANDLEWINAPIDECLSPEC_HOTPATCHDuplicateConsoleHandle(HANDLE hSourceHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest = &ApiMessage.Data.DuplicateHandleRequest;
if ( (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) || (!(dwOptions & DUPLICATE_SAME_ACCESS) && (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE))) ) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; }
DuplicateHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; DuplicateHandleRequest->SourceHandle = hSourceHandle; DuplicateHandleRequest->DesiredAccess = dwDesiredAccess; DuplicateHandleRequest->InheritHandle = bInheritHandle; DuplicateHandleRequest->Options = dwOptions;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepDuplicateHandle), sizeof(*DuplicateHandleRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return INVALID_HANDLE_VALUE; }
return DuplicateHandleRequest->TargetHandle;}
/* * @implemented */BOOLWINAPIGetConsoleHandleInformation(IN HANDLE hHandle, OUT LPDWORD lpdwFlags){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETHANDLEINFO GetHandleInfoRequest = &ApiMessage.Data.GetHandleInfoRequest;
GetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetHandleInfoRequest->Handle = hHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHandleInformation), sizeof(*GetHandleInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
*lpdwFlags = GetHandleInfoRequest->Flags;
return TRUE;}
/* * @implemented */BOOLWINAPISetConsoleHandleInformation(IN HANDLE hHandle, IN DWORD dwMask, IN DWORD dwFlags){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETHANDLEINFO SetHandleInfoRequest = &ApiMessage.Data.SetHandleInfoRequest;
SetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetHandleInfoRequest->Handle = hHandle; SetHandleInfoRequest->Mask = dwMask; SetHandleInfoRequest->Flags = dwFlags;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHandleInformation), sizeof(*SetHandleInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIGetConsoleDisplayMode(LPDWORD lpModeFlags){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &ApiMessage.Data.GetDisplayModeRequest;
if (lpModeFlags == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
GetDisplayModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetDisplayMode), sizeof(*GetDisplayModeRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
*lpModeFlags = GetDisplayModeRequest->DisplayMode; // ModeFlags
return TRUE;}
/* * @implemented (Undocumented) * @note See https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html */DWORDWINAPIGetConsoleFontInfo(IN HANDLE hConsoleOutput, IN BOOL bMaximumWindow, IN DWORD nFontCount, OUT PCONSOLE_FONT_INFO lpConsoleFontInfo){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETFONTINFO GetFontInfoRequest = &ApiMessage.Data.GetFontInfoRequest; PCSR_CAPTURE_BUFFER CaptureBuffer;
GetFontInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetFontInfoRequest->OutputHandle = hConsoleOutput; GetFontInfoRequest->MaximumWindow = bMaximumWindow; GetFontInfoRequest->NumFonts = nFontCount;
CaptureBuffer = CsrAllocateCaptureBuffer(1, nFontCount * sizeof(CONSOLE_FONT_INFO)); if (CaptureBuffer == NULL) { DPRINT1("CsrAllocateCaptureBuffer failed!\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; }
CsrAllocateMessagePointer(CaptureBuffer, nFontCount * sizeof(CONSOLE_FONT_INFO), (PVOID*)&GetFontInfoRequest->FontInfo);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetFontInfo), sizeof(*GetFontInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); } else { RtlCopyMemory(lpConsoleFontInfo, GetFontInfoRequest->FontInfo, GetFontInfoRequest->NumFonts * sizeof(CONSOLE_FONT_INFO)); }
CsrFreeCaptureBuffer(CaptureBuffer); return GetFontInfoRequest->NumFonts;}
/* * @implemented */COORDWINAPIDECLSPEC_HOTPATCHGetConsoleFontSize(IN HANDLE hConsoleOutput, IN DWORD nFont){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETFONTSIZE GetFontSizeRequest = &ApiMessage.Data.GetFontSizeRequest; COORD Empty = {0, 0};
GetFontSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetFontSizeRequest->OutputHandle = hConsoleOutput; GetFontSizeRequest->FontIndex = nFont;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetFontSize), sizeof(*GetFontSizeRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return Empty; }
return GetFontSizeRequest->FontSize;}
/* * @implemented (Undocumented) */BOOLWINAPIGetConsoleHardwareState(HANDLE hConsoleOutput, PDWORD Flags, PDWORD State){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest;
DPRINT1("GetConsoleHardwareState(%lu, 0x%p) UNIMPLEMENTED!\n", Flags, State);
if (Flags == NULL || State == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
HardwareStateRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; HardwareStateRequest->OutputHandle = hConsoleOutput;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHardwareState), sizeof(*HardwareStateRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
*Flags = HardwareStateRequest->Flags; *State = HardwareStateRequest->State;
return TRUE;}
/* * @implemented (Undocumented) */HANDLEWINAPIGetConsoleInputWaitHandle(VOID){ return InputWaitHandle;}
/* * @implemented */BOOLWINAPIGetCurrentConsoleFont(IN HANDLE hConsoleOutput, IN BOOL bMaximumWindow, OUT PCONSOLE_FONT_INFO lpConsoleCurrentFont){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETCURRENTFONT GetCurrentFontRequest = &ApiMessage.Data.GetCurrentFontRequest;
GetCurrentFontRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetCurrentFontRequest->OutputHandle = hConsoleOutput; GetCurrentFontRequest->MaximumWindow = bMaximumWindow;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCurrentFont), sizeof(*GetCurrentFontRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
lpConsoleCurrentFont->dwFontSize = GetCurrentFontRequest->FontSize; lpConsoleCurrentFont->nFont = GetCurrentFontRequest->FontIndex;
return TRUE;}
/* * @implemented (Undocumented) * @note See https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html */DWORDWINAPIDECLSPEC_HOTPATCHGetNumberOfConsoleFonts(VOID){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETNUMFONTS GetNumFontsRequest = &ApiMessage.Data.GetNumFontsRequest;
GetNumFontsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfFonts), sizeof(*GetNumFontsRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return 0; }
return GetNumFontsRequest->NumFonts;}
/* * @implemented (Undocumented) * @note See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/ */BOOLWINAPIInvalidateConsoleDIBits(IN HANDLE hConsoleOutput, IN PSMALL_RECT lpRect){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &ApiMessage.Data.InvalidateDIBitsRequest;
if (lpRect == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
InvalidateDIBitsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; InvalidateDIBitsRequest->OutputHandle = hConsoleOutput; InvalidateDIBitsRequest->Region = *lpRect;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepInvalidateBitMapRect), sizeof(*InvalidateDIBitsRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented (Undocumented) */HANDLEWINAPIOpenConsoleW(LPCWSTR wsName, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwShareMode){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_OPENCONSOLE OpenConsoleRequest = &ApiMessage.Data.OpenConsoleRequest; CONSOLE_HANDLE_TYPE HandleType;
if (wsName && (_wcsicmp(wsName, BaseConInputFileName) == 0)) { HandleType = HANDLE_INPUT; } else if (wsName && (_wcsicmp(wsName, BaseConOutputFileName) == 0)) { HandleType = HANDLE_OUTPUT; } else { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; }
if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) || (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; }
OpenConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; OpenConsoleRequest->HandleType = HandleType; OpenConsoleRequest->DesiredAccess = dwDesiredAccess; OpenConsoleRequest->InheritHandle = bInheritHandle; OpenConsoleRequest->ShareMode = dwShareMode;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepOpenConsole), sizeof(*OpenConsoleRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return INVALID_HANDLE_VALUE; }
return OpenConsoleRequest->Handle;}
/* * @implemented (Undocumented) * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleCursor.php */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleCursor(HANDLE hConsoleOutput, HCURSOR hCursor){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETCURSOR SetCursorRequest = &ApiMessage.Data.SetCursorRequest;
SetCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetCursorRequest->OutputHandle = hConsoleOutput; SetCursorRequest->CursorHandle = hCursor;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursor), sizeof(*SetCursorRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPISetConsoleDisplayMode(HANDLE hConsoleOutput, DWORD dwFlags, // dwModeFlags PCOORD lpNewScreenBufferDimensions){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &ApiMessage.Data.SetDisplayModeRequest;
SetDisplayModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetDisplayModeRequest->OutputHandle = hConsoleOutput; SetDisplayModeRequest->DisplayMode = dwFlags; // ModeFlags ; dwModeFlags SetDisplayModeRequest->NewSBDim.X = 0; SetDisplayModeRequest->NewSBDim.Y = 0; /* SetDisplayModeRequest->EventHandle; */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetDisplayMode), sizeof(*SetDisplayModeRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
if (lpNewScreenBufferDimensions) *lpNewScreenBufferDimensions = SetDisplayModeRequest->NewSBDim;
return TRUE;}
/* * @implemented (Undocumented) * @note See https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleFont(IN HANDLE hConsoleOutput, IN DWORD nFont){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETFONT SetFontRequest = &ApiMessage.Data.SetFontRequest;
SetFontRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetFontRequest->OutputHandle = hConsoleOutput; SetFontRequest->FontIndex = nFont;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetFont), sizeof(*SetFontRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented (Undocumented) */BOOLWINAPISetConsoleHardwareState(HANDLE hConsoleOutput, DWORD Flags, DWORD State){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest;
DPRINT1("SetConsoleHardwareState(%lu, %lu) UNIMPLEMENTED!\n", Flags, State);
HardwareStateRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; HardwareStateRequest->OutputHandle = hConsoleOutput; HardwareStateRequest->Flags = Flags; HardwareStateRequest->State = State;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHardwareState), sizeof(*HardwareStateRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @unimplemented (Undocumented) */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleKeyShortcuts( _In_ BOOL bSet, _In_ BYTE bReserveKeys, _In_reads_(dwNumAppKeys) LPAPPKEY lpAppKeys, _In_ DWORD dwNumAppKeys){ DPRINT1("SetConsoleKeyShortcuts(%lu, 0x%x, 0x%p, 0x%x) UNIMPLEMENTED!\n", bSet, bReserveKeys, lpAppKeys, dwNumAppKeys); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE;}
/* * @implemented (Undocumented) * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleMaximumWindowSize.php * Does nothing, returns TRUE only. Checked on Windows Server 2003. */BOOLWINAPISetConsoleMaximumWindowSize(HANDLE hConsoleOutput, COORD dwMaximumSize){ DPRINT1("SetConsoleMaximumWindowSize(0x%p, {%d, %d}) does nothing\n", hConsoleOutput, dwMaximumSize.X, dwMaximumSize.Y); return TRUE;}
/* * @implemented (Undocumented) */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleMenuClose(BOOL bEnable){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &ApiMessage.Data.SetMenuCloseRequest;
SetMenuCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetMenuCloseRequest->Enable = bEnable;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMenuClose), sizeof(*SetMenuCloseRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented (Undocumented) * @note See http://comments.gmane.org/gmane.comp.lang.harbour.devel/27844 (DEAD_LINK) * Usage example: https://github.com/harbour/core/commit/d79a1b7b812cbde6ddf718ebfd6939a24f633e52 */BOOLWINAPIDECLSPEC_HOTPATCHSetConsolePalette(HANDLE hConsoleOutput, HPALETTE hPalette, UINT dwUsage){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETPALETTE SetPaletteRequest = &ApiMessage.Data.SetPaletteRequest;
SetPaletteRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetPaletteRequest->OutputHandle = hConsoleOutput; SetPaletteRequest->PaletteHandle = hPalette; SetPaletteRequest->Usage = dwUsage;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetPalette), sizeof(*SetPaletteRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented (Undocumented) * @note See http://undoc.airesoft.co.uk/kernel32.dll/ShowConsoleCursor.php */INTWINAPIDECLSPEC_HOTPATCHShowConsoleCursor(HANDLE hConsoleOutput, BOOL bShow){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SHOWCURSOR ShowCursorRequest = &ApiMessage.Data.ShowCursorRequest;
ShowCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; ShowCursorRequest->OutputHandle = hConsoleOutput; ShowCursorRequest->Show = bShow; ShowCursorRequest->RefCount = 0;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepShowCursor), sizeof(*ShowCursorRequest));
return ShowCursorRequest->RefCount;}
/* * FUNCTION: Checks whether the given handle is a valid console handle. * * ARGUMENTS: * hIoHandle - Handle to be checked. * * RETURNS: * TRUE : Handle is a valid console handle. * FALSE: Handle is not a valid console handle. * * STATUS: Officially undocumented * * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHVerifyConsoleIoHandle(HANDLE hIoHandle){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_VERIFYHANDLE VerifyHandleRequest = &ApiMessage.Data.VerifyHandleRequest;
VerifyHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; VerifyHandleRequest->Handle = hIoHandle; VerifyHandleRequest->IsValid = FALSE;
/* If the process is not attached to a console, return invalid handle */ if (VerifyHandleRequest->ConsoleHandle == NULL) return FALSE;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepVerifyIoHandle), sizeof(*VerifyHandleRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return VerifyHandleRequest->IsValid;}
/* * @implemented (Undocumented) */BOOLWINAPIDECLSPEC_HOTPATCHCloseConsoleHandle(HANDLE hHandle){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_CLOSEHANDLE CloseHandleRequest = &ApiMessage.Data.CloseHandleRequest;
CloseHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; CloseHandleRequest->Handle = hHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCloseHandle), sizeof(*CloseHandleRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */HANDLEWINAPIDECLSPEC_HOTPATCHGetStdHandle(DWORD nStdHandle)/* * FUNCTION: Get a handle for the standard input, standard output * and a standard error device. * * ARGUMENTS: * nStdHandle - Specifies the device for which to return the handle. * * RETURNS: If the function succeeds, the return value is the handle * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE. */{ PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters; HANDLE Handle = INVALID_HANDLE_VALUE;
switch (nStdHandle) { case STD_INPUT_HANDLE: Handle = Ppb->StandardInput; break;
case STD_OUTPUT_HANDLE: Handle = Ppb->StandardOutput; break;
case STD_ERROR_HANDLE: Handle = Ppb->StandardError; break; }
/* If the returned handle is invalid, set last error */ if (Handle == INVALID_HANDLE_VALUE) SetLastError(ERROR_INVALID_HANDLE);
return Handle;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetStdHandle(DWORD nStdHandle, HANDLE hHandle)/* * FUNCTION: Set the handle for the standard input, standard output or * the standard error device. * * ARGUMENTS: * nStdHandle - Specifies the handle to be set. * hHandle - The handle to set. * * RETURNS: TRUE if the function succeeds, FALSE otherwise. */{ PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
/* No need to check if hHandle == INVALID_HANDLE_VALUE */
switch (nStdHandle) { case STD_INPUT_HANDLE: Ppb->StandardInput = hHandle; return TRUE;
case STD_OUTPUT_HANDLE: Ppb->StandardOutput = hHandle; return TRUE;
case STD_ERROR_HANDLE: Ppb->StandardError = hHandle; return TRUE; }
/* nStdHandle was invalid, bail out */ SetLastError(ERROR_INVALID_HANDLE); return FALSE;}
/* * @implemented */static BOOLIntAllocConsole(LPWSTR Title, DWORD TitleLength, LPWSTR Desktop, DWORD DesktopLength, LPWSTR CurDir, DWORD CurDirLength, LPWSTR AppName, DWORD AppNameLength, LPTHREAD_START_ROUTINE CtrlRoutine, LPTHREAD_START_ROUTINE PropRoutine, PCONSOLE_START_INFO ConsoleStartInfo){ BOOL Success = TRUE; NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest; PCSR_CAPTURE_BUFFER CaptureBuffer;
AllocConsoleRequest->CtrlRoutine = CtrlRoutine; AllocConsoleRequest->PropRoutine = PropRoutine;
CaptureBuffer = CsrAllocateCaptureBuffer(5, TitleLength + DesktopLength + CurDirLength + AppNameLength + sizeof(CONSOLE_START_INFO)); if (CaptureBuffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); Success = FALSE; goto Quit; }
CsrCaptureMessageBuffer(CaptureBuffer, ConsoleStartInfo, sizeof(CONSOLE_START_INFO), (PVOID*)&AllocConsoleRequest->ConsoleStartInfo);
AllocConsoleRequest->TitleLength = TitleLength; CsrCaptureMessageBuffer(CaptureBuffer, Title, TitleLength, (PVOID*)&AllocConsoleRequest->ConsoleTitle);
AllocConsoleRequest->DesktopLength = DesktopLength; CsrCaptureMessageBuffer(CaptureBuffer, Desktop, DesktopLength, (PVOID*)&AllocConsoleRequest->Desktop);
AllocConsoleRequest->CurDirLength = CurDirLength; CsrCaptureMessageBuffer(CaptureBuffer, CurDir, CurDirLength, (PVOID*)&AllocConsoleRequest->CurDir);
AllocConsoleRequest->AppNameLength = AppNameLength; CsrCaptureMessageBuffer(CaptureBuffer, AppName, AppNameLength, (PVOID*)&AllocConsoleRequest->AppName);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc), sizeof(*AllocConsoleRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); Success = FALSE; goto Quit; }
// Is AllocConsoleRequest->ConsoleStartInfo->InitEvents aligned on handle boundary ???? Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS, AllocConsoleRequest->ConsoleStartInfo->InitEvents, WaitAny, FALSE, NULL); if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); Success = FALSE; goto Quit; }
NtClose(AllocConsoleRequest->ConsoleStartInfo->InitEvents[INIT_SUCCESS]); NtClose(AllocConsoleRequest->ConsoleStartInfo->InitEvents[INIT_FAILURE]); if (Status != INIT_SUCCESS) { NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; Success = FALSE; } else { RtlCopyMemory(ConsoleStartInfo, AllocConsoleRequest->ConsoleStartInfo, sizeof(CONSOLE_START_INFO)); Success = TRUE; }
Quit: if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); return Success;}
BOOLWINAPIDECLSPEC_HOTPATCHAllocConsole(VOID){ BOOL Success; CONSOLE_START_INFO ConsoleStartInfo;
PWCHAR ConsoleTitle; PWCHAR Desktop; PWCHAR AppName; PWCHAR CurDir;
ULONG TitleLength = (MAX_PATH + 1) * sizeof(WCHAR); ULONG DesktopLength = (MAX_PATH + 1) * sizeof(WCHAR); ULONG AppNameLength = 128 * sizeof(WCHAR); ULONG CurDirLength = (MAX_PATH + 1) * sizeof(WCHAR);
RtlEnterCriticalSection(&ConsoleLock);
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle) { DPRINT1("AllocConsole: Allocating a console to a process already having one\n"); SetLastError(ERROR_ACCESS_DENIED); Success = FALSE; goto Quit; }
/* Set up the console properties */ SetUpConsoleInfo(FALSE, &TitleLength, &ConsoleTitle, &DesktopLength, &Desktop, &ConsoleStartInfo); DPRINT("ConsoleTitle = '%S' - Desktop = '%S'\n", ConsoleTitle, Desktop);
/* Initialize the Input EXE name */ InitExeName(); SetUpAppName(FALSE, &CurDirLength, &CurDir, &AppNameLength, &AppName); DPRINT("CurDir = '%S' - AppName = '%S'\n", CurDir, AppName);
Success = IntAllocConsole(ConsoleTitle, TitleLength, Desktop, DesktopLength, CurDir, CurDirLength, AppName, AppNameLength, ConsoleControlDispatcher, PropDialogHandler, &ConsoleStartInfo); if (Success) { /* Set up the handles */ SetUpHandles(&ConsoleStartInfo); InputWaitHandle = ConsoleStartInfo.InputWaitHandle;
/* Initialize Console Ctrl Handling */ InitializeCtrlHandling();
/* Sync the current thread's LangId with the console's one */ SetTEBLangID(); }
Quit: RtlLeaveCriticalSection(&ConsoleLock); return Success;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHFreeConsole(VOID){ BOOL Success = TRUE; CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_FREECONSOLE FreeConsoleRequest = &ApiMessage.Data.FreeConsoleRequest; HANDLE ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
RtlEnterCriticalSection(&ConsoleLock);
/* We must have a non-trivial handle to close */ if (ConsoleHandle == NULL) // IsConsoleHandle(ConsoleHandle) { SetLastError(ERROR_INVALID_PARAMETER); Success = FALSE; goto Quit; }
/* Set up the data to send to the Console Server */ FreeConsoleRequest->ConsoleHandle = ConsoleHandle;
/* Call the server */ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree), sizeof(*FreeConsoleRequest));
/* Check for success */ if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); Success = FALSE; goto Quit; }
/* Reset the console handle */ NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
/* Close the associated input handle */ CloseHandle(InputWaitHandle); InputWaitHandle = INVALID_HANDLE_VALUE;
Quit: RtlLeaveCriticalSection(&ConsoleLock); return Success;}
/* * @implemented */BOOLWINAPIGetConsoleScreenBufferInfo(HANDLE hConsoleOutput, PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &ApiMessage.Data.ScreenBufferInfoRequest;
if (lpConsoleScreenBufferInfo == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
ScreenBufferInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; ScreenBufferInfoRequest->OutputHandle = hConsoleOutput;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo), sizeof(*ScreenBufferInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
lpConsoleScreenBufferInfo->dwSize = ScreenBufferInfoRequest->ScreenBufferSize; lpConsoleScreenBufferInfo->dwCursorPosition = ScreenBufferInfoRequest->CursorPosition; lpConsoleScreenBufferInfo->wAttributes = ScreenBufferInfoRequest->Attributes; lpConsoleScreenBufferInfo->srWindow.Left = ScreenBufferInfoRequest->ViewOrigin.X; lpConsoleScreenBufferInfo->srWindow.Top = ScreenBufferInfoRequest->ViewOrigin.Y; lpConsoleScreenBufferInfo->srWindow.Right = ScreenBufferInfoRequest->ViewOrigin.X + ScreenBufferInfoRequest->ViewSize.X - 1; lpConsoleScreenBufferInfo->srWindow.Bottom = ScreenBufferInfoRequest->ViewOrigin.Y + ScreenBufferInfoRequest->ViewSize.Y - 1; lpConsoleScreenBufferInfo->dwMaximumWindowSize = ScreenBufferInfoRequest->MaximumViewSize;
return TRUE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleCursorPosition(HANDLE hConsoleOutput, COORD dwCursorPosition){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &ApiMessage.Data.SetCursorPositionRequest;
SetCursorPositionRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetCursorPositionRequest->OutputHandle = hConsoleOutput; SetCursorPositionRequest->Position = dwCursorPosition;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition), sizeof(*SetCursorPositionRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIGetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
if (lpMode == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; ConsoleModeRequest->Handle = hConsoleHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode), sizeof(*ConsoleModeRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
*lpMode = ConsoleModeRequest->Mode;
return TRUE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; ConsoleModeRequest->Handle = hConsoleHandle; ConsoleModeRequest->Mode = dwMode;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode), sizeof(*ConsoleModeRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIGetNumberOfConsoleInputEvents(HANDLE hConsoleInput, LPDWORD lpNumberOfEvents){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest;
GetNumInputEventsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetNumInputEventsRequest->InputHandle = hConsoleInput; GetNumInputEventsRequest->NumberOfEvents = 0;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents), sizeof(*GetNumInputEventsRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
if (lpNumberOfEvents == NULL) { SetLastError(ERROR_INVALID_ACCESS); return FALSE; }
*lpNumberOfEvents = GetNumInputEventsRequest->NumberOfEvents;
return TRUE;}
/* * @implemented */COORDWINAPIDECLSPEC_HOTPATCHGetLargestConsoleWindowSize(HANDLE hConsoleOutput){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest;
GetLargestWindowSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput; GetLargestWindowSizeRequest->Size.X = 0; GetLargestWindowSizeRequest->Size.Y = 0;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLargestWindowSize), sizeof(*GetLargestWindowSizeRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); }
DPRINT("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y); return GetLargestWindowSizeRequest->Size;}
/* * @implemented */BOOLWINAPIGetConsoleCursorInfo(HANDLE hConsoleOutput, PCONSOLE_CURSOR_INFO lpConsoleCursorInfo){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest;
if (!lpConsoleCursorInfo) { if (!hConsoleOutput) SetLastError(ERROR_INVALID_HANDLE); else SetLastError(ERROR_INVALID_ACCESS);
return FALSE; }
CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; CursorInfoRequest->OutputHandle = hConsoleOutput;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo), sizeof(*CursorInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
*lpConsoleCursorInfo = CursorInfoRequest->Info;
return TRUE;}
/* * @implemented */BOOLWINAPISetConsoleCursorInfo(HANDLE hConsoleOutput, CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest;
CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; CursorInfoRequest->OutputHandle = hConsoleOutput; CursorInfoRequest->Info = *lpConsoleCursorInfo;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo), sizeof(*CursorInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIGetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETMOUSEINFO GetMouseInfoRequest = &ApiMessage.Data.GetMouseInfoRequest;
GetMouseInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMouseInfo), sizeof(*GetMouseInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
*lpNumberOfMouseButtons = GetMouseInfoRequest->NumButtons; return TRUE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleActiveScreenBuffer(HANDLE hConsoleOutput){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &ApiMessage.Data.SetScreenBufferRequest;
SetScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetScreenBufferRequest->OutputHandle = hConsoleOutput;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer), sizeof(*SetScreenBufferRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHFlushConsoleInputBuffer(HANDLE hConsoleInput){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &ApiMessage.Data.FlushInputBufferRequest;
FlushInputBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; FlushInputBufferRequest->InputHandle = hConsoleInput;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer), sizeof(*FlushInputBufferRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleScreenBufferSize(HANDLE hConsoleOutput, COORD dwSize){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &ApiMessage.Data.SetScreenBufferSizeRequest;
SetScreenBufferSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetScreenBufferSizeRequest->OutputHandle = hConsoleOutput; SetScreenBufferSizeRequest->Size = dwSize;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize), sizeof(*SetScreenBufferSizeRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
staticBOOLIntScrollConsoleScreenBuffer(HANDLE hConsoleOutput, CONST SMALL_RECT* lpScrollRectangle, CONST SMALL_RECT* lpClipRectangle, COORD dwDestinationOrigin, CONST CHAR_INFO* lpFill, BOOL bUnicode){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
ScrollScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; ScrollScreenBufferRequest->OutputHandle = hConsoleOutput; ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
if (lpClipRectangle != NULL) { ScrollScreenBufferRequest->UseClipRectangle = TRUE; ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle; } else { ScrollScreenBufferRequest->UseClipRectangle = FALSE; }
ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin; ScrollScreenBufferRequest->Fill = *lpFill; ScrollScreenBufferRequest->Unicode = bUnicode;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer), sizeof(*ScrollScreenBufferRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHScrollConsoleScreenBufferA(HANDLE hConsoleOutput, CONST SMALL_RECT* lpScrollRectangle, CONST SMALL_RECT* lpClipRectangle, COORD dwDestinationOrigin, CONST CHAR_INFO* lpFill){ return IntScrollConsoleScreenBuffer(hConsoleOutput, lpScrollRectangle, lpClipRectangle, dwDestinationOrigin, lpFill, FALSE);}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHScrollConsoleScreenBufferW(HANDLE hConsoleOutput, CONST SMALL_RECT *lpScrollRectangle, CONST SMALL_RECT *lpClipRectangle, COORD dwDestinationOrigin, CONST CHAR_INFO *lpFill){ return IntScrollConsoleScreenBuffer(hConsoleOutput, lpScrollRectangle, lpClipRectangle, dwDestinationOrigin, lpFill, TRUE);}
/* * @implemented */BOOLWINAPISetConsoleWindowInfo(HANDLE hConsoleOutput, BOOL bAbsolute, CONST SMALL_RECT *lpConsoleWindow){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest;
if (lpConsoleWindow == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
SetWindowInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetWindowInfoRequest->OutputHandle = hConsoleOutput; SetWindowInfoRequest->Absolute = bAbsolute; SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo), sizeof(*SetWindowInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleTextAttribute(HANDLE hConsoleOutput, WORD wAttributes){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &ApiMessage.Data.SetTextAttribRequest;
SetTextAttribRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetTextAttribRequest->OutputHandle = hConsoleOutput; SetTextAttribRequest->Attributes = wAttributes;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute), sizeof(*SetTextAttribRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
staticBOOLAddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine){ PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
if (HandlerRoutine == NULL) { NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE; return TRUE; }
if (NrCtrlHandlers == NrAllocatedHandlers) { NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(), 0, (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE)); if (NewCtrlHandlers == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; }
memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
CtrlHandlers = NewCtrlHandlers; NrAllocatedHandlers += 4; }
ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine; return TRUE;}
staticBOOLRemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine){ ULONG i;
if (HandlerRoutine == NULL) { NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE; return TRUE; }
for (i = 0; i < NrCtrlHandlers; i++) { if (CtrlHandlers[i] == HandlerRoutine) { if (i < (NrCtrlHandlers - 1)) { memmove(&CtrlHandlers[i], &CtrlHandlers[i+1], (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE)); }
NrCtrlHandlers--; return TRUE; } }
SetLastError(ERROR_INVALID_PARAMETER); return FALSE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add){ BOOL Ret;
RtlEnterCriticalSection(&ConsoleLock);
if (Add) Ret = AddConsoleCtrlHandler(HandlerRoutine); else Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
RtlLeaveCriticalSection(&ConsoleLock); return Ret;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHGenerateConsoleCtrlEvent(DWORD dwCtrlEvent, DWORD dwProcessGroupId){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &ApiMessage.Data.GenerateCtrlEventRequest;
if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
GenerateCtrlEventRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GenerateCtrlEventRequest->CtrlEvent = dwCtrlEvent; GenerateCtrlEventRequest->ProcessGroupId = dwProcessGroupId;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent), sizeof(*GenerateCtrlEventRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
static DWORDIntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest; PCSR_CAPTURE_BUFFER CaptureBuffer;
if (dwNumChars == 0) return 0;
TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; TitleRequest->Length = dwNumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); TitleRequest->Unicode = bUnicode;
CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length); if (CaptureBuffer == NULL) { DPRINT1("CsrAllocateCaptureBuffer failed!\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; }
CsrAllocateMessagePointer(CaptureBuffer, TitleRequest->Length, (PVOID*)&TitleRequest->Title);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle), sizeof(*TitleRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { CsrFreeCaptureBuffer(CaptureBuffer); BaseSetLastNTError(ApiMessage.Status); return 0; }
dwNumChars = TitleRequest->Length / (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
if (dwNumChars > 0) { RtlCopyMemory(lpConsoleTitle, TitleRequest->Title, TitleRequest->Length);
if (bUnicode) ((LPWSTR)lpConsoleTitle)[dwNumChars] = UNICODE_NULL; else ((LPSTR)lpConsoleTitle)[dwNumChars] = ANSI_NULL; }
CsrFreeCaptureBuffer(CaptureBuffer);
return dwNumChars;}
/* * @implemented */DWORDWINAPIDECLSPEC_HOTPATCHGetConsoleTitleW(LPWSTR lpConsoleTitle, DWORD nSize){ return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);}
/* * @implemented */DWORDWINAPIDECLSPEC_HOTPATCHGetConsoleTitleA(LPSTR lpConsoleTitle, DWORD nSize){ return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);}
static BOOLIntSetConsoleTitle(CONST VOID *lpConsoleTitle, BOOLEAN bUnicode){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest; PCSR_CAPTURE_BUFFER CaptureBuffer;
ULONG NumChars = (ULONG)(lpConsoleTitle ? (bUnicode ? wcslen(lpConsoleTitle) : strlen(lpConsoleTitle)) : 0);
TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; TitleRequest->Length = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); TitleRequest->Unicode = bUnicode;
CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length); if (CaptureBuffer == NULL) { DPRINT1("CsrAllocateCaptureBuffer failed!\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; }
CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)lpConsoleTitle, TitleRequest->Length, (PVOID*)&TitleRequest->Title);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle), sizeof(*TitleRequest));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleTitleW(LPCWSTR lpConsoleTitle){ return IntSetConsoleTitle(lpConsoleTitle, TRUE);}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleTitleA(LPCSTR lpConsoleTitle){ return IntSetConsoleTitle(lpConsoleTitle, FALSE);}
/* * @implemented */HANDLEWINAPICreateConsoleScreenBuffer(DWORD dwDesiredAccess, DWORD dwShareMode, CONST SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwFlags, LPVOID lpScreenBufferData){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest; PCSR_CAPTURE_BUFFER CaptureBuffer = NULL; PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = lpScreenBufferData;
if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) || (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) || (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) ) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; }
CreateScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; CreateScreenBufferRequest->DesiredAccess = dwDesiredAccess; CreateScreenBufferRequest->InheritHandle = (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE); CreateScreenBufferRequest->ShareMode = dwShareMode; CreateScreenBufferRequest->ScreenBufferType = dwFlags;
if (dwFlags == CONSOLE_GRAPHICS_BUFFER) { if (CreateScreenBufferRequest->InheritHandle || GraphicsBufferInfo == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; }
CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength); if (CaptureBuffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return INVALID_HANDLE_VALUE; }
CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)GraphicsBufferInfo->lpBitMapInfo, GraphicsBufferInfo->dwBitMapInfoLength, (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo); }
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer), sizeof(*CreateScreenBufferRequest));
if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return INVALID_HANDLE_VALUE; }
if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo) { GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->hMutex ; // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ; GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->lpBitMap; // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap; }
return CreateScreenBufferRequest->OutputHandle;}
/* * @implemented */UINTWINAPIDECLSPEC_HOTPATCHGetConsoleCP(VOID){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest;
/* Get the Input Code Page */ GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetConsoleCPRequest->OutputCP = FALSE;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP), sizeof(*GetConsoleCPRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return 0; }
return GetConsoleCPRequest->CodePage;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleCP(UINT wCodePageID){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest;
/* Set the Input Code Page */ SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetConsoleCPRequest->CodePage = wCodePageID; SetConsoleCPRequest->OutputCP = FALSE; /* SetConsoleCPRequest->EventHandle; */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP), sizeof(*SetConsoleCPRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* * @implemented */UINTWINAPIDECLSPEC_HOTPATCHGetConsoleOutputCP(VOID){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest;
/* Get the Output Code Page */ GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetConsoleCPRequest->OutputCP = TRUE;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP), sizeof(*GetConsoleCPRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return 0; }
return GetConsoleCPRequest->CodePage;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleOutputCP(UINT wCodePageID){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest;
/* Set the Output Code Page */ SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetConsoleCPRequest->CodePage = wCodePageID; SetConsoleCPRequest->OutputCP = TRUE; /* SetConsoleCPRequest->EventHandle; */
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP), sizeof(*SetConsoleCPRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
/* Sync the current thread's LangId with the console's one */ SetTEBLangID();
return TRUE;}
/* * @implemented */DWORDWINAPIGetConsoleProcessList(LPDWORD lpdwProcessList, DWORD dwProcessCount){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest; PCSR_CAPTURE_BUFFER CaptureBuffer; ULONG nProcesses = 0;
if (lpdwProcessList == NULL || dwProcessCount == 0) { SetLastError(ERROR_INVALID_PARAMETER); return 0; }
CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD)); if (CaptureBuffer == NULL) { DPRINT1("CsrAllocateCaptureBuffer failed!\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; }
GetProcessListRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetProcessListRequest->ProcessCount = dwProcessCount;
CsrAllocateMessagePointer(CaptureBuffer, dwProcessCount * sizeof(DWORD), (PVOID*)&GetProcessListRequest->ProcessIdsList);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList), sizeof(*GetProcessListRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); } else { nProcesses = GetProcessListRequest->ProcessCount; if (dwProcessCount >= nProcesses) { RtlCopyMemory(lpdwProcessList, GetProcessListRequest->ProcessIdsList, nProcesses * sizeof(DWORD)); } }
CsrFreeCaptureBuffer(CaptureBuffer); return nProcesses;}
/* * @implemented */BOOLWINAPIGetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &ApiMessage.Data.GetSelectionInfoRequest;
if (lpConsoleSelectionInfo == NULL) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
GetSelectionInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo), sizeof(*GetSelectionInfoRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
*lpConsoleSelectionInfo = GetSelectionInfoRequest->Info;
return TRUE;}
/* * @implemented * @note Strongly inspired by AllocConsole. */static BOOLIntAttachConsole(DWORD ProcessId, LPTHREAD_START_ROUTINE CtrlRoutine, LPTHREAD_START_ROUTINE PropRoutine, PCONSOLE_START_INFO ConsoleStartInfo){ BOOL Success = TRUE; NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest; PCSR_CAPTURE_BUFFER CaptureBuffer;
AttachConsoleRequest->ProcessId = ProcessId; AttachConsoleRequest->CtrlRoutine = CtrlRoutine; AttachConsoleRequest->PropRoutine = PropRoutine;
CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO)); if (CaptureBuffer == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); Success = FALSE; goto Quit; }
CsrCaptureMessageBuffer(CaptureBuffer, ConsoleStartInfo, sizeof(CONSOLE_START_INFO), (PVOID*)&AttachConsoleRequest->ConsoleStartInfo);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach), sizeof(*AttachConsoleRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); Success = FALSE; goto Quit; }
// Is AttachConsoleRequest->ConsoleStartInfo->InitEvents aligned on handle boundary ???? Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS, AttachConsoleRequest->ConsoleStartInfo->InitEvents, WaitAny, FALSE, NULL); if (!NT_SUCCESS(Status)) { BaseSetLastNTError(Status); Success = FALSE; goto Quit; }
NtClose(AttachConsoleRequest->ConsoleStartInfo->InitEvents[INIT_SUCCESS]); NtClose(AttachConsoleRequest->ConsoleStartInfo->InitEvents[INIT_FAILURE]); if (Status != INIT_SUCCESS) { NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; Success = FALSE; } else { RtlCopyMemory(ConsoleStartInfo, AttachConsoleRequest->ConsoleStartInfo, sizeof(CONSOLE_START_INFO)); Success = TRUE; }
Quit: if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); return Success;}
BOOLWINAPIAttachConsole(DWORD dwProcessId){ BOOL Success; CONSOLE_START_INFO ConsoleStartInfo; DWORD dummy;
RtlEnterCriticalSection(&ConsoleLock);
if (NtCurrentPeb()->ProcessParameters->ConsoleHandle) { DPRINT1("AttachConsole: Attaching a console to a process already having one\n"); SetLastError(ERROR_ACCESS_DENIED); Success = FALSE; goto Quit; }
/* Set up the console properties */ SetUpConsoleInfo(FALSE, &dummy, NULL, &dummy, NULL, &ConsoleStartInfo);
Success = IntAttachConsole(dwProcessId, ConsoleControlDispatcher, PropDialogHandler, &ConsoleStartInfo); if (Success) { /* Set up the handles */ SetUpHandles(&ConsoleStartInfo); InputWaitHandle = ConsoleStartInfo.InputWaitHandle;
/* Initialize Console Ctrl Handling */ InitializeCtrlHandling();
/* Sync the current thread's LangId with the console's one */ SetTEBLangID(); }
Quit: RtlLeaveCriticalSection(&ConsoleLock); return Success;}
/* * @implemented */HWNDWINAPIDECLSPEC_HOTPATCHGetConsoleWindow(VOID){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETWINDOW GetWindowRequest = &ApiMessage.Data.GetWindowRequest;
GetWindowRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow), sizeof(*GetWindowRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return (HWND)NULL; }
return GetWindowRequest->WindowHandle;}
/* * @implemented */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleIcon(HICON hIcon){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_SETICON SetIconRequest = &ApiMessage.Data.SetIconRequest;
SetIconRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; SetIconRequest->IconHandle = hIcon;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon), sizeof(*SetIconRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/****************************************************************************** * \name SetConsoleInputExeNameW * \brief Sets the console input file name from a unicode string. * \param lpExeName Pointer to a unicode string with the name. * \return TRUE if successful, FALSE if unsuccessful. * \remarks If lpExeName is 0 or the string length is 0 or greater than 255, * the function fails and sets last error to ERROR_INVALID_PARAMETER. */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleInputExeNameW(IN LPCWSTR lpExeName){ DWORD ExeLength;
ExeLength = lstrlenW(lpExeName); if ((ExeLength == 0) || (ExeLength >= EXENAME_LENGTH)) { /* Fail if string is empty or too long */ SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
RtlEnterCriticalSection(&ExeNameLock); _SEH2_TRY { /* Set the input EXE name, not NULL terminated */ RtlCopyMemory(ExeNameBuffer, lpExeName, ExeLength * sizeof(WCHAR)); ExeNameLength = (USHORT)ExeLength; } _SEH2_FINALLY { RtlLeaveCriticalSection(&ExeNameLock); } _SEH2_END;
return TRUE;}
/****************************************************************************** * \name SetConsoleInputExeNameA * \brief Sets the console input file name from an ansi string. * \param lpExeName Pointer to an ansi string with the name. * \return TRUE if successful, FALSE if unsuccessful. * \remarks If lpExeName is 0 or the string length is 0 or greater than 255, * the function fails and sets last error to ERROR_INVALID_PARAMETER. */BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleInputExeNameA(IN LPCSTR lpExeName){ NTSTATUS Status;#ifdef USE_TEB_STATIC_USTR PUNICODE_STRING ExeNameU;#else UNICODE_STRING ExeNameU;#endif ANSI_STRING ExeNameA;#ifndef USE_TEB_STATIC_USTR WCHAR Buffer[EXENAME_LENGTH];#endif
#ifdef USE_TEB_STATIC_USTR /* * Use the TEB static UNICODE string for storage. It is already * initialized at process creation time by the Memory Manager. */ ExeNameU = &NtCurrentTeb()->StaticUnicodeString;#endif
/* Initialize string for conversion */ RtlInitAnsiString(&ExeNameA, lpExeName);
#if 1 if ((ExeNameA.Length == 0) || (ExeNameA.Length >= EXENAME_LENGTH)) { /* Fail if string is empty or too long */ SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }#endif#ifndef USE_TEB_STATIC_USTR ExeNameU.Length = 0; ExeNameU.MaximumLength = (USHORT)sizeof(Buffer); ExeNameU.Buffer = Buffer;#endif
#ifdef USE_TEB_STATIC_USTR Status = RtlAnsiStringToUnicodeString(ExeNameU, &ExeNameA, FALSE);#else Status = RtlAnsiStringToUnicodeString(&ExeNameU, &ExeNameA, FALSE);#endif if (!NT_SUCCESS(Status)) { /* Fail if string is empty or too long */ if (Status == STATUS_BUFFER_OVERFLOW) SetLastError(ERROR_FILENAME_EXCED_RANGE); else SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; }
#ifdef USE_TEB_STATIC_USTR return SetConsoleInputExeNameW(ExeNameU->Buffer);#else return SetConsoleInputExeNameW(ExeNameU.Buffer);#endif}
/****************************************************************************** * \name GetConsoleInputExeNameW * \brief Retrieves the console input file name as unicode string. * \param nBufferLength Length of the buffer in WCHARs. * Specify 0 to receive the needed buffer length. * \param lpBuffer Pointer to a buffer that receives the string. * \return Needed buffer size if \p nBufferLength is 0. * Otherwise 1 if successful, 2 if buffer is too small. * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer * is not big enough. */DWORDWINAPIDECLSPEC_HOTPATCHGetConsoleInputExeNameW(IN DWORD nBufferLength, OUT LPWSTR lpExeName){ if (nBufferLength <= ExeNameLength) { /* Buffer is not large enough! Return the correct size. */ SetLastError(ERROR_BUFFER_OVERFLOW); return ExeNameLength + 1; }
RtlEnterCriticalSection(&ExeNameLock); _SEH2_TRY { /* Copy the input EXE name and NULL-terminate it */ RtlCopyMemory(lpExeName, ExeNameBuffer, ExeNameLength * sizeof(WCHAR)); lpExeName[ExeNameLength] = UNICODE_NULL; } _SEH2_FINALLY { RtlLeaveCriticalSection(&ExeNameLock); } _SEH2_END;
return TRUE;}
/****************************************************************************** * \name GetConsoleInputExeNameA * \brief Retrieves the console input file name as ansi string. * \param nBufferLength Length of the buffer in CHARs. * \param lpBuffer Pointer to a buffer that receives the string. * \return 1 if successful, 2 if buffer is too small. * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer * is not big enough. The buffer receives as much characters as fit. */DWORDWINAPIDECLSPEC_HOTPATCHGetConsoleInputExeNameA(IN DWORD nBufferLength, OUT LPSTR lpExeName){ NTSTATUS Status; DWORD ExeLength; UNICODE_STRING BufferU; ANSI_STRING BufferA; WCHAR Buffer[EXENAME_LENGTH];
/* Get the UNICODE name */ ExeLength = GetConsoleInputExeNameW(EXENAME_LENGTH, Buffer);
if ((ExeLength == 0) || (ExeLength >= EXENAME_LENGTH)) return ExeLength;
/* Initialize the strings for conversion */ RtlInitUnicodeString(&BufferU, Buffer); BufferA.Length = 0; BufferA.MaximumLength = (USHORT)nBufferLength; BufferA.Buffer = lpExeName;
/* Convert UNICODE name to ANSI, copying as much chars as it can fit */ Status = RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE); if (!NT_SUCCESS(Status)) { if (Status == STATUS_BUFFER_OVERFLOW) { SetLastError(ERROR_BUFFER_OVERFLOW); return ExeLength + 1; } SetLastError(ERROR_INVALID_PARAMETER); }
return ExeLength;}
BOOLWINAPIGetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type){ STUB; return FALSE;}
BOOLWINAPIDECLSPEC_HOTPATCHGetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2){ STUB; return FALSE;}
BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2){ STUB; return FALSE;}
BOOLWINAPIDECLSPEC_HOTPATCHGetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode){ STUB; return FALSE;}
BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleNlsMode(HANDLE hConsole, DWORD dwMode){ STUB; return FALSE;}
BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleLocalEUDC( _In_ HANDLE hConsoleHandle, _In_ WORD wCodePoint, _In_ COORD cFontSize, _In_ PCHAR lpSB){ STUB; return FALSE;}
static BOOLIntRegisterConsoleIME( _In_ HWND hWnd, _In_ DWORD dwThreadId, _In_opt_ SIZE_T cbDesktop, _In_opt_ PWSTR pDesktop, _Out_opt_ PDWORD pdwAttachToThreadId){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_REGISTERCONSOLEIME RegisterConsoleIME = &ApiMessage.Data.RegisterConsoleIME; PCSR_CAPTURE_BUFFER CaptureBuffer;
if (!cbDesktop || !pDesktop) { pDesktop = NtCurrentPeb()->ProcessParameters->DesktopInfo.Buffer; cbDesktop = NtCurrentPeb()->ProcessParameters->DesktopInfo.Length; }
cbDesktop = min(cbDesktop, (MAX_PATH + 1) * sizeof(WCHAR));
RegisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; RegisterConsoleIME->hWnd = hWnd; RegisterConsoleIME->dwThreadId = dwThreadId; RegisterConsoleIME->cbDesktop = cbDesktop;
CaptureBuffer = CsrAllocateCaptureBuffer(1, cbDesktop); if (!CaptureBuffer) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; }
CsrCaptureMessageBuffer(CaptureBuffer, pDesktop, cbDesktop, (PVOID*)&RegisterConsoleIME->pDesktop);
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, CaptureBuffer, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepRegisterConsoleIME), sizeof(*RegisterConsoleIME));
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
if (pdwAttachToThreadId) { _SEH2_TRY { *pdwAttachToThreadId = RegisterConsoleIME->dwAttachToThreadId; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { BaseSetLastNTError(STATUS_ACCESS_VIOLATION); _SEH2_YIELD(return FALSE); } _SEH2_END; }
return TRUE;}
static BOOLIntUnregisterConsoleIME( _In_ DWORD dwThreadId){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_UNREGISTERCONSOLEIME UnregisterConsoleIME = &ApiMessage.Data.UnregisterConsoleIME;
UnregisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; UnregisterConsoleIME->dwThreadId = dwThreadId;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepUnregisterConsoleIME), sizeof(*UnregisterConsoleIME)); if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
return TRUE;}
/* This function is called by CONIME.EXE */BOOLWINAPIDECLSPEC_HOTPATCHRegisterConsoleIME( _In_ HWND hWnd, _Out_opt_ LPDWORD pdwAttachToThreadId){ return IntRegisterConsoleIME(hWnd, GetCurrentThreadId(), 0, NULL, pdwAttachToThreadId);}
BOOLWINAPIDECLSPEC_HOTPATCHRegisterConsoleOS2(BOOL bUnknown){ STUB; return FALSE;}
BOOLWINAPIDECLSPEC_HOTPATCHSetConsoleOS2OemFormat(BOOL bUnknown){ STUB; return FALSE;}
/* This function is called by CONIME.EXE */BOOLWINAPIDECLSPEC_HOTPATCHUnregisterConsoleIME(VOID){ return IntUnregisterConsoleIME(GetCurrentThreadId());}
/** * @brief * Internal helper function used to synchronize the current * thread's language ID with the one from the console. **/VOIDSetTEBLangID(VOID){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETLANGID LangIdRequest = &ApiMessage.Data.LangIdRequest;
/* Retrieve the "best-suited" language ID corresponding * to the active console output code page. */ LangIdRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLangId), sizeof(*LangIdRequest)); if (!NT_SUCCESS(ApiMessage.Status)) { /* * No best console language ID: keep the current thread's one. * Since this internal function only modifies an optional setting, * don't set any last error, as it could otherwise mess with the * main last error set by the caller. */ return; }
/* * We succeeded, set the current thread's language ID by * modifying its locale -- Windows <= 2003 does not have * the concept of a separate thread UI language. * Ignore the returned value. */ if (!SetThreadLocale(MAKELCID(LangIdRequest->LangId, SORT_DEFAULT))) { DPRINT1("SetTEBLangID: Could not set thread locale to console lang ID %lu\n", LangIdRequest->LangId); }}
staticBOOLIntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName, IN BOOL bAnsi){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &ApiMessage.Data.GetKbdLayoutNameRequest;
/* Set up the data to send to the Console Server */ GetKbdLayoutNameRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; GetKbdLayoutNameRequest->Ansi = bAnsi;
/* Call the server */ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetKeyboardLayoutName), sizeof(*GetKbdLayoutNameRequest));
/* Check for success */ if (!NT_SUCCESS(ApiMessage.Status)) { BaseSetLastNTError(ApiMessage.Status); return FALSE; }
/* Retrieve the results */ _SEH2_TRY { /* Copy only KL_NAMELENGTH == 9 characters, ANSI or UNICODE */ if (bAnsi) strncpy(pszLayoutName, (PCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH); else wcsncpy(pszLayoutName, (PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastError(ERROR_INVALID_ACCESS); _SEH2_YIELD(return FALSE); } _SEH2_END;
return TRUE;}
/* * @implemented (undocumented) */BOOLWINAPIDECLSPEC_HOTPATCHGetConsoleKeyboardLayoutNameA(OUT LPSTR pszLayoutName){ return IntGetConsoleKeyboardLayoutName(pszLayoutName, TRUE);}
/* * @implemented (undocumented) */BOOLWINAPIDECLSPEC_HOTPATCHGetConsoleKeyboardLayoutNameW(OUT LPWSTR pszLayoutName){ return IntGetConsoleKeyboardLayoutName(pszLayoutName, FALSE);}
/* * @implemented */DWORDWINAPISetLastConsoleEventActive(VOID){ CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest = &ApiMessage.Data.NotifyLastCloseRequest;
/* Set the flag used by the console control dispatcher */ LastCloseNotify = TRUE;
/* Set up the input arguments */ NotifyLastCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
/* Call CSRSS; just return the NTSTATUS cast to DWORD */ return CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepNotifyLastClose), sizeof(*NotifyLastCloseRequest));}
/* EOF */