From 6026330fce733717967218bf1d8cfdde1f8244c8 Mon Sep 17 00:00:00 2001 From: janwas Date: Fri, 1 Apr 2011 15:06:52 +0000 Subject: [PATCH] updated version of Aken that includes support for MSR and static validation (-> .c instead of .cpp) closes #754 (please re-open if not) This was SVN commit r9137. --- binaries/system/aken.sys | Bin 3712 -> 9592 bytes binaries/system/aken64.sys | Bin 5120 -> 10104 bytes binaries/system/aken64d.sys | Bin 7168 -> 14200 bytes binaries/system/akend.sys | Bin 5248 -> 12664 bytes .../sysdep/os/win/aken/{aken.cpp => aken.c} | 931 ++++++++++-------- source/lib/sysdep/os/win/aken/build_all.bat | 32 + .../lib/sysdep/os/win/aken/build_single.bat | 67 ++ source/lib/sysdep/os/win/aken/sources | 2 +- 8 files changed, 626 insertions(+), 406 deletions(-) rename source/lib/sysdep/os/win/aken/{aken.cpp => aken.c} (61%) create mode 100644 source/lib/sysdep/os/win/aken/build_all.bat create mode 100644 source/lib/sysdep/os/win/aken/build_single.bat diff --git a/binaries/system/aken.sys b/binaries/system/aken.sys index f52b2bd117c5e4cd5eaacd2c2d6a9b417674f65c..1c2e3f92a9250f9caa0dfadfc26ad9c812db5f9f 100644 GIT binary patch literal 9592 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 MudWikBk@E0-@pWDZU6uP delta 1579 zcmb_c|4&<06u+-~k3Pz4i%be(z!)&)n{&ca=qn-vieMOD3Zsc(b5I_k+O?IwG9hd{ z!bpS%ad@>FgNX)y@P~yEr=hyd6{0p6VsOSpf6(yLrU8{KixfikJhz3}Kfs%O`Z?!w z?>YC}bKhM#(JTJ9BRu5yN4R>Q z2O?~B*n3F~+8@mpgc>LY{jG?#2iiK)Q3;epgf7%K)|2$eK-Q6BBa9nWX}Sqe$o7%kTHLRi7{13L zbQcf=TnBsr*aeVL4%`MP09*k)3D|>UYy#E*Ujm$7%)UbnB$E_65@T^-&5Z@1vV zpVPLuJ2i?@c@w%eh?BSziK~$zD`(}+(apSe8_r}6PxOQ=TSW+dADloT%R>~0P3)0p zKcgvR4(TUv!G5+WOSsu)Ygc@GHFA`U4#;m zm-&i@#u}9X4`E_DSU7e^7Kxcy+CHlpsW+nMeNV$<7wI{*W zF9tWXQTG~+2jh!XJu;q;&&+&>EKJoeF1J9GM4W_u=PEdOU6X<-O#$@_F49z}7HI6$ zWZ-R0{_u5}EeW1mW>HKN+GQUn*Itn8xRD){wYw&_b2j-6R<5MSEu462WQPV(JU+6+ z5;lzNaD>%?1s3*A3k(uE9LOWY1%hfICeQ{nb%txPS(P<849zLND}O(ZZzre|NDXr6 zmGe*qeu2xWh^eHdh4dIMA)H07VmBMEV$Ty#AtiZ+L|I5tV?j|3r=A00WtoOsJ&BX_ zX}E&RO^Qi1x|s;)VsVx(Wtb#PjU-GX36X{*3_|=^aL7t_oU&{+hic2dgCm4$E2HH3 zE8?AcAGU`CTak($kcu9rM-qHQD%u+R=dxDuvC(?uZ#PsW!SgEz{f&HMANO8m$W~ue z-b6^G%}c%xWmsd{%$wfmySDTsnqc-<#>MT8nbtr3V+BlJ7$0z%FB zbYeLS4qWVVJ0120hwC+jo`0+#the77O=PG>@|R^dO2!%E&&I0K@zQro z=Sst+Oj%NyzwEcNLQ}EHWU4g1XzDh7Y6_TEO#S>2{}%7(Kji25MgBIw%HQL6_(#0f MY%ph-;ZvIb7Xeb{rT_o{ diff --git a/binaries/system/aken64.sys b/binaries/system/aken64.sys index 735c3fee38901a758d600f26603eb81ecf7d7c53..23d1fc3a063e6e5d558a9d08ea33c1a023f0fcd0 100644 GIT binary patch literal 10104 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 literal 5120 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 O4bi=8F}oEV;{Oe@0GE&e literal 7168 zcmeHMeQZJi=$g}*q;4D z5(%cH2`H%(iK$xE{@3wGwf{o3DM{H!!^W1-!5UTFv`I*yY1*8bt^6?!gu1@{&VA2` z^Fgbs+NOArLB`MT$vd+)jL*@upvrD7r~K{pJdDL`&s`TX$59M~JTUf4)KTz7Tb zl+Ay2TT3LGR+6d2u~e{22?gWvgs!w}N~$}qMB|FDp;_rlgte-&vh}KE`WMHqzdx|y z_3_1ietZ<;+b_K}{=9_O#s?+5KHe|kWeJ<2p$O|N_ptFGQTWUn`i-GKndjZ2O4?9l zCn^VJjY$mz0iBH7OakLYM5TD-yJRHsL~?#Rl$Yd8p-J5WWMN#u0z1}DNzWFA{hfr+YAIH)5RK28G&QqIZ|MzVQ{ zM3pHRWjHciyA{bWVQ-dO=f&{!lRd6#WDl5F>uo?wD**?KgjZWtFzb@A&I#0*m}r*;j^J zROh0MW5TC8|5j+HV`QnoBm_F%Ta;MJ&VZX|8aup>PZ0S1sv0r_FSp>M7Tjw=VZmoD z7_p#k!51v}ngu5;_-hNUmezc2<`VJ@`ly1An$y(mYkuX;&nJhDKGZNY7^qqM#J&q$ zZo>Q8aHkyCLVCK*6AZVdPsH2OiSATLYl}tO+tPjMu$FA=iN@Q4of;lp;l0%oMKNlJ zzHL(xZL)15+eRC0+>bHCbAWam*((9dZB+jJGRXYRMYP$reUZP;M(gr&`@!dNJ0|#F zZ=B@&v|atC@=nLQhOztH^)I}#^ZrYM6L;@d(QhiaUI9zKj=L7P6R;coec=6o$tLi& z0SAmU8u+V#chPHsI|FzH z2on7fbA8(WyBQD*7pxe(=@z(PYi7J2_DSMm##_UKJ@1H&U#&4**WNaaJ=0?Fl6&!v zE_`iRVy~5LL`240Ax3CMe(n_gT0Tc&&xofqOBnFUz+EYql&Ax>Dk*p8 z^oN0zn!*EPYLtn{x7O0ZD2CvOwJisuWy1RR&*jk4ugZ zJ}8+vF;@0E!pok35PKpWlq>8(?v)X{+$5qfbh%CL8UNbu^)mj!8p;R%177vKZMiqy z8Cnc|(p$obkh{q3nDDMa0z62B2e2BUSDT5bF4DL0s6^kLI{<6y4t(~KV-j9ECg!r= z_=#cUcAIoCO#0+pHpFz931tJSbi}j|86r(_**}c$2%~83WtylOj`yR=QG5Oy>LqeQ%^GiQ!5AeTt2vG+MEOV z!W<7SnPW5Nn88PAb`*2WZ-o8%b=D+vuwkI_BsYL_1A4{8WD?yni9_lg(0EN+Ib*j> zxhw$Kta1&28_?eY@Hel>jLId*@+&cp?CEL!GguX7m+?n7>@aST5DACp1%AlIxZrZ@&e_aGq-7Svfgel22~ItV21#cI{Tl+V?{p{*=_F(r;VnZxKmcXN96shfm%PSxuDj;zA7j`KDDwE%U8M=9CIh5EGUNS z+cTDJG1zM--67`@8DTeE8<;hCsm4lq9ljXr6Cpj;qy@u`iIl!iN#d#O=vAJ;V?9}Q zF%K5xkEEiywp3x?DjMAmj?~TKkm0J+^q^FlM8OK zKZk#M+(EkK zJfthM)c-)JJJK4pNK`f!ak0 zN`XpR7W@uADsObd_0pS#6`il|Q3z*uowu&<*I=G6r?U*l%AR`3WCnq8KTCmgR2G0rLZ!Kk|WLSoVFX=m{-#Fs}2duTLCE zX+d3U?(1q##G)a8G~T)Fz<%8QzN&qnb|M;DQ3|9-%g=Y=IeNJr8M4}+LO_)KXcfqO zw14;SlF!-d6Fx1b>6#f7(P2)rlN8Dt>Ryh$!q-sl#T<5t|Xgk(!SNL zr6ISY^k~n4SR$>_?~9xCSY0};rF41<)aB)w=;`8n7F}wFMnOTP?_j*L{1F8gqAA=0 UL~%Wl?o7pFRa&oR<~9HP7c)PLWB>pF diff --git a/binaries/system/akend.sys b/binaries/system/akend.sys index 7cbb0ef6611aeca094f507cd3fac3dbc233ac7bc..113d1f63ff9b1b3175eaf986707629f9ba89c8cb 100644 GIT binary patch literal 12664 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 literal 5248 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 F{|Oqyn-c&4 diff --git a/source/lib/sysdep/os/win/aken/aken.cpp b/source/lib/sysdep/os/win/aken/aken.c similarity index 61% rename from source/lib/sysdep/os/win/aken/aken.cpp rename to source/lib/sysdep/os/win/aken/aken.c index c821f51eef..5f7f016d3a 100644 --- a/source/lib/sysdep/os/win/aken/aken.cpp +++ b/source/lib/sysdep/os/win/aken/aken.c @@ -1,405 +1,526 @@ -/* Copyright (c) 2010 Wildfire Games - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -extern "C" { // must come before ntddk.h - -#include -#include "aken.h" - -#define WIN32_NAME L"\\DosDevices\\Aken" -#define DEVICE_NAME L"\\Device\\Aken" - -// this driver isn't large, but it's still slightly nicer to make its -// functions pageable and thus not waste precious non-paged pool. -// #pragma code_seg is more convenient than specifying alloc_text for -// every other function. -NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING registryPath); -#pragma alloc_text(INIT, DriverEntry) // => discardable -#pragma code_seg(push, "PAGE") - - -//----------------------------------------------------------------------------- -// memory mapping -//----------------------------------------------------------------------------- - -/* -there are three approaches to mapping physical memory: -(http://www.microsoft.com/whdc/driver/kernel/mem-mgmt.mspx) - -- MmMapIoSpace (http://support.microsoft.com/kb/189327/en-us). despite the - name, it maps physical pages of any kind by allocating PTEs. very easy to - implement, but occupies precious kernel address space. possible bugs: - http://www.osronline.com/showThread.cfm?link=96737 - http://support.microsoft.com/kb/925793/en-us - -- ZwMapViewOfSection of PhysicalMemory (http://tinyurl.com/yozmgy). - the code is a bit bulky, but the WinXP API prevents mapping pages with - conflicting attributes (see below). - -- MmMapLockedPagesSpecifyCache or MmGetSystemAddressForMdlSafe - (http://www.osronline.com/article.cfm?id=423). note: the latter is a macro - that calls the former. this is the 'normal' and fully documented way, - but it doesn't appear able to map a fixed physical address. - (MmAllocatePagesForMdl understandably doesn't work since some pages we - want to map are marked as unavailable for allocation, and I don't see - another documented way to fill an MDL with PFNs.) - -our choice here is forced by a very insidious issue. if someone else has -already mapped a page with different attributes (e.g. cacheable), TLBs -may end up corrupted, leading to disaster. the search for a documented -means of accessing the page frame database (to check if mapped anywhere -and determine the previously set attributes) has not borne fruit, so we -must use ZwMapViewOfSection. (if taking this up again, see -http://www.woodmann.com/forum/archive/index.php/t-6516.html ) - -note that we guess if the page will have been mapped as cacheable and -even try the opposite if that turns out to have been incorrect. -*/ - -static bool IsMemoryUncacheable(DWORD64 physicalAddress64) -{ - // original PC memory - contains BIOS - if(physicalAddress64 < 0x100000) - return true; - - return false; -} - -static NTSTATUS AkenMapPhysicalMemory(const DWORD64 physicalAddress64, const DWORD64 numBytes64, DWORD64& virtualAddress64) -{ - NTSTATUS ntStatus; - - // (convenience) - LARGE_INTEGER physicalAddress; - physicalAddress.QuadPart = physicalAddress64; - - // get handle to PhysicalMemory object - HANDLE hMemory; - { - OBJECT_ATTRIBUTES objectAttributes; - UNICODE_STRING objectName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); - const ULONG attributes = OBJ_CASE_INSENSITIVE; - const HANDLE rootDirectory = 0; - InitializeObjectAttributes(&objectAttributes, &objectName, attributes, rootDirectory, (PSECURITY_DESCRIPTOR)0); - ntStatus = ZwOpenSection(&hMemory, SECTION_ALL_ACCESS, &objectAttributes); - if(!NT_SUCCESS(ntStatus)) - { - KdPrint(("AkenMapPhysicalMemory: ZwOpenSection failed\n")); - return ntStatus; - } - } - - // add a reference (required to prevent the handle from being deleted) - { - PVOID physicalMemorySection = NULL; - const POBJECT_TYPE objectType = 0; // allowed since specifying KernelMode - ntStatus = ObReferenceObjectByHandle(hMemory, SECTION_ALL_ACCESS, objectType, KernelMode, &physicalMemorySection, 0); - if(!NT_SUCCESS(ntStatus)) - { - KdPrint(("AkenMapPhysicalMemory: ObReferenceObjectByHandle failed\n")); - goto close_handle; - } - } - - // note: mapmem.c does HalTranslateBusAddress, but we only care about - // system memory. translating doesn't appear to be necessary, even if - // much existing code uses it (probably due to cargo cult). - - // map desired memory into user PTEs - { - const HANDLE hProcess = (HANDLE)-1; - PVOID virtualBaseAddress = 0; // let ZwMapViewOfSection pick - const ULONG zeroBits = 0; // # high-order bits in address that must be 0 - SIZE_T mappedSize = (SIZE_T)numBytes64; // will receive the actual page-aligned size - LARGE_INTEGER physicalBaseAddress = physicalAddress; // will be rounded down to 64KB boundary - const SECTION_INHERIT inheritDisposition = ViewShare; - const ULONG allocationType = 0; - ULONG protect = PAGE_READWRITE; - if(IsMemoryUncacheable(physicalAddress64)) - protect |= PAGE_NOCACHE; - ntStatus = ZwMapViewOfSection(hMemory, hProcess, &virtualBaseAddress, zeroBits, mappedSize, &physicalBaseAddress, &mappedSize, inheritDisposition, allocationType, protect); - if(!NT_SUCCESS(ntStatus)) - { - // try again with the opposite cacheability attribute - protect ^= PAGE_NOCACHE; - ntStatus = ZwMapViewOfSection(hMemory, hProcess, &virtualBaseAddress, zeroBits, mappedSize, &physicalBaseAddress, &mappedSize, inheritDisposition, allocationType, protect); - if(!NT_SUCCESS(ntStatus)) - { - KdPrint(("AkenMapPhysicalMemory: ZwMapViewOfSection failed\n")); - goto close_handle; - } - } - - // the mapping rounded our physical base address down to the nearest - // 64KiB boundary, so adjust the virtual address accordingly. - const DWORD32 numBytesRoundedDown = physicalAddress.LowPart - physicalBaseAddress.LowPart; - ASSERT(numBytesRoundedDown < 0x10000); - virtualAddress64 = (DWORD64)virtualBaseAddress + numBytesRoundedDown; - } - - ntStatus = STATUS_SUCCESS; - -close_handle: - // closing the handle even on success means that callers won't have to - // pass it back when unmapping. why does this work? ZwMapViewOfSection - // apparently adds a reference to hMemory. - ZwClose(hMemory); - - return ntStatus; -} - - -static NTSTATUS AkenUnmapPhysicalMemory(const DWORD64 virtualAddress) -{ - const HANDLE hProcess = (HANDLE)-1; - PVOID baseAddress = (PVOID)virtualAddress; - NTSTATUS ntStatus = ZwUnmapViewOfSection(hProcess, baseAddress); - if(!NT_SUCCESS(ntStatus)) - { - KdPrint(("AkenUnmapPhysicalMemory: ZwUnmapViewOfSection failed\n")); - return ntStatus; - } - - return STATUS_SUCCESS; -} - - -//----------------------------------------------------------------------------- -// helper functions called from DeviceControl -//----------------------------------------------------------------------------- - -static NTSTATUS AkenIoctlReadPort(PVOID buf, const ULONG inSize, ULONG& outSize) -{ - if(inSize != sizeof(AkenReadPortIn) || outSize != sizeof(AkenReadPortOut)) - return STATUS_BUFFER_TOO_SMALL; - - const AkenReadPortIn* in = (const AkenReadPortIn*)buf; - const USHORT port = in->port; - const UCHAR numBytes = in->numBytes; - DWORD32 value; - switch(numBytes) - { - case 1: - value = (DWORD32)READ_PORT_UCHAR((PUCHAR)port); - break; - case 2: - value = (DWORD32)READ_PORT_USHORT((PUSHORT)port); - break; - case 4: - value = (DWORD32)READ_PORT_ULONG((PULONG)port); - break; - default: - return STATUS_INVALID_PARAMETER; - } - KdPrint(("AkenIoctlReadPort: port %x = %x\n", port, value)); - - AkenReadPortOut* out = (AkenReadPortOut*)buf; - out->value = value; - return STATUS_SUCCESS; -} - -static NTSTATUS AkenIoctlWritePort(PVOID buf, const ULONG inSize, ULONG& outSize) -{ - if(inSize != sizeof(AkenWritePortIn) || outSize != 0) - return STATUS_BUFFER_TOO_SMALL; - - const AkenWritePortIn* in = (const AkenWritePortIn*)buf; - const DWORD32 value = in->value; - const USHORT port = in->port; - const UCHAR numBytes = in->numBytes; - switch(numBytes) - { - case 1: - WRITE_PORT_UCHAR((PUCHAR)port, (UCHAR)(value & 0xFF)); - break; - case 2: - WRITE_PORT_USHORT((PUSHORT)port, (USHORT)(value & 0xFFFF)); - break; - case 4: - WRITE_PORT_ULONG((PULONG)port, value); - break; - default: - return STATUS_INVALID_PARAMETER; - } - KdPrint(("AkenIoctlWritePort: port %x := %x\n", port, value)); - - return STATUS_SUCCESS; -} - -static NTSTATUS AkenIoctlMap(PVOID buf, const ULONG inSize, ULONG& outSize) -{ - if(inSize != sizeof(AkenMapIn) || outSize != sizeof(AkenMapOut)) - return STATUS_BUFFER_TOO_SMALL; - - const AkenMapIn* in = (const AkenMapIn*)buf; - const DWORD64 physicalAddress = in->physicalAddress; - const DWORD64 numBytes = in->numBytes; - - DWORD64 virtualAddress; - NTSTATUS ntStatus = AkenMapPhysicalMemory(physicalAddress, numBytes, virtualAddress); - - AkenMapOut* out = (AkenMapOut*)buf; - out->virtualAddress = virtualAddress; - return ntStatus; -} - -static NTSTATUS AkenIoctlUnmap(PVOID buf, const ULONG inSize, ULONG& outSize) -{ - if(inSize != sizeof(AkenUnmapIn) || outSize != 0) - return STATUS_BUFFER_TOO_SMALL; - - const AkenUnmapIn* in = (const AkenUnmapIn*)buf; - const DWORD64 virtualAddress = in->virtualAddress; - NTSTATUS ntStatus = AkenUnmapPhysicalMemory(virtualAddress); - - return ntStatus; -} - -static NTSTATUS AkenIoctlUnknown(PVOID buf, const ULONG inSize, ULONG& outSize) -{ - KdPrint(("AkenIoctlUnknown\n")); - outSize = 0; - return STATUS_INVALID_DEVICE_REQUEST; -} - - -typedef NTSTATUS (*AkenIoctl)(PVOID buf, ULONG inSize, ULONG& outSize); - -static inline AkenIoctl AkenIoctlFromCode(ULONG ioctlCode) -{ - switch(ioctlCode) - { - case IOCTL_AKEN_READ_PORT: - return AkenIoctlReadPort; - - case IOCTL_AKEN_WRITE_PORT: - return AkenIoctlWritePort; - - case IOCTL_AKEN_MAP: - return AkenIoctlMap; - - case IOCTL_AKEN_UNMAP: - return AkenIoctlUnmap; - - default: - return AkenIoctlUnknown; - } -} - - -//----------------------------------------------------------------------------- -// entry points -//----------------------------------------------------------------------------- - -static NTSTATUS AkenCreate(IN PDEVICE_OBJECT deviceObject, IN PIRP irp) -{ - irp->IoStatus.Status = STATUS_SUCCESS; - irp->IoStatus.Information = 0; - IoCompleteRequest(irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} - - -static NTSTATUS AkenClose(IN PDEVICE_OBJECT deviceObject, IN PIRP irp) -{ - // same as AkenCreate ATM - irp->IoStatus.Status = STATUS_SUCCESS; - irp->IoStatus.Information = 0; - IoCompleteRequest(irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} - - -static NTSTATUS AkenDeviceControl(IN PDEVICE_OBJECT deviceObject, IN PIRP irp) -{ - // get buffer from IRP. all our IOCTLs are METHOD_BUFFERED, so buf is - // allocated by the I/O manager and used for both input and output. - PVOID buf = irp->AssociatedIrp.SystemBuffer; - PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(irp); - ULONG ioctlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; - const ULONG inSize = irpStack->Parameters.DeviceIoControl.InputBufferLength; - ULONG outSize = irpStack->Parameters.DeviceIoControl.OutputBufferLength; // modified by AkenIoctl* - - const AkenIoctl akenIoctl = AkenIoctlFromCode(ioctlCode); - const NTSTATUS ntStatus = akenIoctl(buf, inSize, outSize); - - irp->IoStatus.Information = outSize; // number of bytes to copy from buf to user's buffer - irp->IoStatus.Status = ntStatus; - IoCompleteRequest(irp, IO_NO_INCREMENT); - return ntStatus; -} - - -static VOID AkenUnload(IN PDRIVER_OBJECT driverObject) -{ - KdPrint(("AkenUnload\n")); - - UNICODE_STRING win32Name = RTL_CONSTANT_STRING(WIN32_NAME); - IoDeleteSymbolicLink(&win32Name); - - if(driverObject->DeviceObject) - IoDeleteDevice(driverObject->DeviceObject); -} - - -#pragma code_seg(pop) // make sure we don't countermand the alloc_text - -NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath) -{ - UNICODE_STRING deviceName = RTL_CONSTANT_STRING(DEVICE_NAME); - - // create device object - PDEVICE_OBJECT deviceObject; - { - const ULONG deviceExtensionSize = 0; - const ULONG deviceCharacteristics = FILE_DEVICE_SECURE_OPEN; - const BOOLEAN exlusive = TRUE; - NTSTATUS ntStatus = IoCreateDevice(driverObject, deviceExtensionSize, &deviceName, FILE_DEVICE_AKEN, deviceCharacteristics, exlusive, &deviceObject); - if(!NT_SUCCESS(ntStatus)) - { - KdPrint(("DriverEntry: IoCreateDevice failed\n")); - return ntStatus; - } - } - - // set entry points - driverObject->MajorFunction[IRP_MJ_CREATE] = AkenCreate; - driverObject->MajorFunction[IRP_MJ_CLOSE] = AkenClose; - driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AkenDeviceControl; - driverObject->DriverUnload = AkenUnload; - - // symlink NT device name to Win32 namespace - { - UNICODE_STRING win32Name = RTL_CONSTANT_STRING(WIN32_NAME); - NTSTATUS ntStatus = IoCreateSymbolicLink(&win32Name, &deviceName); - if(!NT_SUCCESS(ntStatus)) - { - KdPrint(("DriverEntry: IoCreateSymbolicLink failed\n")); - IoDeleteDevice(deviceObject); - return ntStatus; - } - } - - return STATUS_SUCCESS; -} - -} // extern "C" { +/* Copyright (c) 2010 Wildfire Games + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// note: staticdv cannot yet check C++ code. + +#include +#include "aken.h" +#include "intrinsics.h" + +#define WIN32_NAME L"\\DosDevices\\Aken" +#define DEVICE_NAME L"\\Device\\Aken" + +// placate PREfast +DRIVER_INITIALIZE DriverEntry; +__drv_dispatchType(IRP_MJ_CREATE) DRIVER_DISPATCH AkenCreate; +__drv_dispatchType(IRP_MJ_CLOSE) DRIVER_DISPATCH AkenClose; +__drv_dispatchType(IRP_MJ_DEVICE_CONTROL) DRIVER_DISPATCH AkenDeviceControl; +DRIVER_UNLOAD AkenUnload; + +// this driver isn't large, but it's still slightly nicer to make its +// functions pageable and thus not waste precious non-paged pool. +// #pragma code_seg is more convenient than specifying alloc_text for +// every other function. +#pragma alloc_text(INIT, DriverEntry) // => discardable +#pragma code_seg(push, "PAGE") + + +//----------------------------------------------------------------------------- +// memory mapping +//----------------------------------------------------------------------------- + +/* +there are three approaches to mapping physical memory: +(http://www.microsoft.com/whdc/driver/kernel/mem-mgmt.mspx) + +- MmMapIoSpace (http://support.microsoft.com/kb/189327/en-us). despite the + name, it maps physical pages of any kind by allocating PTEs. very easy to + implement, but occupies precious kernel address space. possible bugs: + http://www.osronline.com/showThread.cfm?link=96737 + http://support.microsoft.com/kb/925793/en-us + +- ZwMapViewOfSection of PhysicalMemory (http://tinyurl.com/yozmgy). + the code is a bit bulky, but the WinXP API prevents mapping pages with + conflicting attributes (see below). + +- MmMapLockedPagesSpecifyCache or MmGetSystemAddressForMdlSafe + (http://www.osronline.com/article.cfm?id=423). note: the latter is a macro + that calls the former. this is the 'normal' and fully documented way, + but it doesn't appear able to map a fixed physical address. + (MmAllocatePagesForMdl understandably doesn't work since some pages we + want to map are marked as unavailable for allocation, and I don't see + another documented way to fill an MDL with PFNs.) + +our choice here is forced by a very insidious issue. if someone else has +already mapped a page with different attributes (e.g. cacheable), TLBs +may end up corrupted, leading to disaster. the search for a documented +means of accessing the page frame database (to check if mapped anywhere +and determine the previously set attributes) has not borne fruit, so we +must use ZwMapViewOfSection. (if taking this up again, see +http://www.woodmann.com/forum/archive/index.php/t-6516.html ) + +note that we guess if the page will have been mapped as cacheable and +even try the opposite if that turns out to have been incorrect. +*/ + +static int IsMemoryUncacheable(DWORD64 physicalAddress64) +{ + PAGED_CODE(); + + // original PC memory - contains BIOS + if(physicalAddress64 < 0x100000) + return 1; + + return 0; +} + +static NTSTATUS AkenMapPhysicalMemory(const DWORD64 physicalAddress64, const DWORD64 numBytes64, DWORD64* virtualAddress64) +{ + NTSTATUS ntStatus; + HANDLE hMemory; + LARGE_INTEGER physicalAddress; // convenience + physicalAddress.QuadPart = physicalAddress64; + + PAGED_CODE(); + + // get handle to PhysicalMemory object + { + OBJECT_ATTRIBUTES objectAttributes; + UNICODE_STRING objectName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory"); + const ULONG attributes = OBJ_CASE_INSENSITIVE; + const HANDLE rootDirectory = 0; + InitializeObjectAttributes(&objectAttributes, &objectName, attributes, rootDirectory, (PSECURITY_DESCRIPTOR)0); + ntStatus = ZwOpenSection(&hMemory, SECTION_ALL_ACCESS, &objectAttributes); + if(!NT_SUCCESS(ntStatus)) + { + KdPrint(("AkenMapPhysicalMemory: ZwOpenSection failed\n")); + return ntStatus; + } + } + + // add a reference (required to prevent the handle from being deleted) + { + PVOID physicalMemorySection = NULL; + const POBJECT_TYPE objectType = 0; // allowed since specifying KernelMode + ntStatus = ObReferenceObjectByHandle(hMemory, SECTION_ALL_ACCESS, objectType, KernelMode, &physicalMemorySection, 0); + if(!NT_SUCCESS(ntStatus)) + { + KdPrint(("AkenMapPhysicalMemory: ObReferenceObjectByHandle failed\n")); + goto close_handle; + } + } + + // note: mapmem.c does HalTranslateBusAddress, but we only care about + // system memory. translating doesn't appear to be necessary, even if + // much existing code uses it (probably due to cargo cult). + + // map desired memory into user PTEs + { + const HANDLE hProcess = (HANDLE)-1; + PVOID virtualBaseAddress = 0; // let ZwMapViewOfSection pick + const ULONG zeroBits = 0; // # high-order bits in address that must be 0 + SIZE_T mappedSize = (SIZE_T)numBytes64; // will receive the actual page-aligned size + LARGE_INTEGER physicalBaseAddress = physicalAddress; // will be rounded down to 64KB boundary + const SECTION_INHERIT inheritDisposition = ViewShare; + const ULONG allocationType = 0; + ULONG protect = PAGE_READWRITE; + if(IsMemoryUncacheable(physicalAddress64)) + protect |= PAGE_NOCACHE; + ntStatus = ZwMapViewOfSection(hMemory, hProcess, &virtualBaseAddress, zeroBits, mappedSize, &physicalBaseAddress, &mappedSize, inheritDisposition, allocationType, protect); + if(!NT_SUCCESS(ntStatus)) + { + // try again with the opposite cacheability attribute + protect ^= PAGE_NOCACHE; + ntStatus = ZwMapViewOfSection(hMemory, hProcess, &virtualBaseAddress, zeroBits, mappedSize, &physicalBaseAddress, &mappedSize, inheritDisposition, allocationType, protect); + if(!NT_SUCCESS(ntStatus)) + { + KdPrint(("AkenMapPhysicalMemory: ZwMapViewOfSection failed\n")); + goto close_handle; + } + } + + // the mapping rounded our physical base address down to the nearest + // 64KiB boundary, so adjust the virtual address accordingly. + { + const DWORD32 numBytesRoundedDown = physicalAddress.LowPart - physicalBaseAddress.LowPart; + ASSERT(numBytesRoundedDown < 0x10000); + *virtualAddress64 = (DWORD64)virtualBaseAddress + numBytesRoundedDown; + } + } + + ntStatus = STATUS_SUCCESS; + +close_handle: + // closing the handle even on success means that callers won't have to + // pass it back when unmapping. why does this work? ZwMapViewOfSection + // apparently adds a reference to hMemory. + ZwClose(hMemory); + + return ntStatus; +} + + +static NTSTATUS AkenUnmapPhysicalMemory(const DWORD64 virtualAddress) +{ + PAGED_CODE(); + + { + const HANDLE hProcess = (HANDLE)-1; + PVOID baseAddress = (PVOID)virtualAddress; + NTSTATUS ntStatus = ZwUnmapViewOfSection(hProcess, baseAddress); + if(!NT_SUCCESS(ntStatus)) + { + KdPrint(("AkenUnmapPhysicalMemory: ZwUnmapViewOfSection failed\n")); + return ntStatus; + } + } + + return STATUS_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// helper functions called from DeviceControl +//----------------------------------------------------------------------------- + +static NTSTATUS AkenIoctlReadPort(PVOID buf, const ULONG inSize, ULONG* outSize) +{ + DWORD32 value; + + PAGED_CODE(); + + if(inSize != sizeof(AkenReadPortIn) || *outSize != sizeof(AkenReadPortOut)) + return STATUS_BUFFER_TOO_SMALL; + + { + const AkenReadPortIn* in = (const AkenReadPortIn*)buf; + const USHORT port = in->port; + const UCHAR numBytes = in->numBytes; + switch(numBytes) + { + case 1: + value = (DWORD32)READ_PORT_UCHAR((PUCHAR)port); + break; + case 2: + value = (DWORD32)READ_PORT_USHORT((PUSHORT)port); + break; + case 4: + value = (DWORD32)READ_PORT_ULONG((PULONG)port); + break; + default: + return STATUS_INVALID_PARAMETER; + } + } + + { + AkenReadPortOut* out = (AkenReadPortOut*)buf; + out->value = value; + } + return STATUS_SUCCESS; +} + +static NTSTATUS AkenIoctlWritePort(PVOID buf, const ULONG inSize, ULONG* outSize) +{ + PAGED_CODE(); + + if(inSize != sizeof(AkenWritePortIn) || *outSize != 0) + return STATUS_BUFFER_TOO_SMALL; + + { + const AkenWritePortIn* in = (const AkenWritePortIn*)buf; + const DWORD32 value = in->value; + const USHORT port = in->port; + const UCHAR numBytes = in->numBytes; + switch(numBytes) + { + case 1: + WRITE_PORT_UCHAR((PUCHAR)port, (UCHAR)(value & 0xFF)); + break; + case 2: + WRITE_PORT_USHORT((PUSHORT)port, (USHORT)(value & 0xFFFF)); + break; + case 4: + WRITE_PORT_ULONG((PULONG)port, value); + break; + default: + return STATUS_INVALID_PARAMETER; + } + } + + return STATUS_SUCCESS; +} + + +static NTSTATUS AkenIoctlMap(PVOID buf, const ULONG inSize, ULONG* outSize) +{ + DWORD64 virtualAddress; + NTSTATUS ntStatus; + + PAGED_CODE(); + + if(inSize != sizeof(AkenMapIn) || *outSize != sizeof(AkenMapOut)) + return STATUS_BUFFER_TOO_SMALL; + + { + const AkenMapIn* in = (const AkenMapIn*)buf; + const DWORD64 physicalAddress = in->physicalAddress; + const DWORD64 numBytes = in->numBytes; + ntStatus = AkenMapPhysicalMemory(physicalAddress, numBytes, &virtualAddress); + } + + { + AkenMapOut* out = (AkenMapOut*)buf; + out->virtualAddress = virtualAddress; + } + return ntStatus; +} + +static NTSTATUS AkenIoctlUnmap(PVOID buf, const ULONG inSize, ULONG* outSize) +{ + NTSTATUS ntStatus; + + PAGED_CODE(); + + if(inSize != sizeof(AkenUnmapIn) || *outSize != 0) + return STATUS_BUFFER_TOO_SMALL; + + { + const AkenUnmapIn* in = (const AkenUnmapIn*)buf; + const DWORD64 virtualAddress = in->virtualAddress; + ntStatus = AkenUnmapPhysicalMemory(virtualAddress); + } + + return ntStatus; +} + + +static NTSTATUS AkenIoctlReadModelSpecificRegister(PVOID buf, const ULONG inSize, ULONG* outSize) +{ + DWORD64 value; + + PAGED_CODE(); + + if(inSize != sizeof(AkenReadRegisterIn) || *outSize != sizeof(AkenReadRegisterOut)) + return STATUS_BUFFER_TOO_SMALL; + + { + const AkenReadRegisterIn* in = (const AkenReadRegisterIn*)buf; + const DWORD64 reg = in->reg; + value = __readmsr((int)reg); + } + + { + AkenReadRegisterOut* out = (AkenReadRegisterOut*)buf; + out->value = value; + } + + return STATUS_SUCCESS; +} + +static NTSTATUS AkenIoctlWriteModelSpecificRegister(PVOID buf, const ULONG inSize, ULONG* outSize) +{ + PAGED_CODE(); + + if(inSize != sizeof(AkenWriteRegisterIn) || *outSize != 0) + return STATUS_BUFFER_TOO_SMALL; + + { + const AkenWriteRegisterIn* in = (const AkenWriteRegisterIn*)buf; + const DWORD64 reg = in->reg; + const DWORD64 value = in->value; + __writemsr((unsigned long)reg, value); + } + + return STATUS_SUCCESS; +} + +static NTSTATUS AkenIoctlReadPerformanceMonitoringCounter(PVOID buf, const ULONG inSize, ULONG* outSize) +{ + DWORD64 value; + + PAGED_CODE(); + + if(inSize != sizeof(AkenReadRegisterIn) || *outSize != sizeof(AkenReadRegisterOut)) + return STATUS_BUFFER_TOO_SMALL; + + { + const AkenReadRegisterIn* in = (const AkenReadRegisterIn*)buf; + const DWORD64 reg = in->reg; + value = __readpmc((unsigned long)reg); + } + + { + AkenReadRegisterOut* out = (AkenReadRegisterOut*)buf; + out->value = value; + } + + return STATUS_SUCCESS; +} + + +static NTSTATUS AkenIoctlUnknown(PVOID buf, const ULONG inSize, ULONG* outSize) +{ + PAGED_CODE(); + + KdPrint(("AkenIoctlUnknown\n")); + + *outSize = 0; + return STATUS_INVALID_DEVICE_REQUEST; +} + + +typedef NTSTATUS (*AkenIoctl)(PVOID buf, ULONG inSize, ULONG* outSize); + +static AkenIoctl AkenIoctlFromCode(ULONG ioctlCode) +{ + PAGED_CODE(); + + switch(ioctlCode) + { + case IOCTL_AKEN_READ_PORT: + return AkenIoctlReadPort; + case IOCTL_AKEN_WRITE_PORT: + return AkenIoctlWritePort; + + case IOCTL_AKEN_MAP: + return AkenIoctlMap; + case IOCTL_AKEN_UNMAP: + return AkenIoctlUnmap; + + case IOCTL_AKEN_READ_MSR: + return AkenIoctlReadModelSpecificRegister; + case IOCTL_AKEN_WRITE_MSR: + return AkenIoctlWriteModelSpecificRegister; + + default: + return AkenIoctlUnknown; + } +} + + +//----------------------------------------------------------------------------- +// entry points +//----------------------------------------------------------------------------- + +static NTSTATUS AkenCreate(IN PDEVICE_OBJECT deviceObject, IN PIRP irp) +{ + PAGED_CODE(); + + irp->IoStatus.Status = STATUS_SUCCESS; + irp->IoStatus.Information = 0; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + + +static NTSTATUS AkenClose(IN PDEVICE_OBJECT deviceObject, IN PIRP irp) +{ + PAGED_CODE(); + + // same as AkenCreate ATM + irp->IoStatus.Status = STATUS_SUCCESS; + irp->IoStatus.Information = 0; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + + +static NTSTATUS AkenDeviceControl(IN PDEVICE_OBJECT deviceObject, IN PIRP irp) +{ + PAGED_CODE(); + + { + // get buffer from IRP. all our IOCTLs are METHOD_BUFFERED, so buf is + // allocated by the I/O manager and used for both input and output. + PVOID buf = irp->AssociatedIrp.SystemBuffer; + PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(irp); + ULONG ioctlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; + const ULONG inSize = irpStack->Parameters.DeviceIoControl.InputBufferLength; + ULONG outSize = irpStack->Parameters.DeviceIoControl.OutputBufferLength; // modified by AkenIoctl* + + const AkenIoctl akenIoctl = AkenIoctlFromCode(ioctlCode); + const NTSTATUS ntStatus = akenIoctl(buf, inSize, &outSize); + + irp->IoStatus.Information = outSize; // number of bytes to copy from buf to user's buffer + irp->IoStatus.Status = ntStatus; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return ntStatus; + } +} + + +static VOID AkenUnload(IN PDRIVER_OBJECT driverObject) +{ + PAGED_CODE(); + + KdPrint(("AkenUnload\n")); + + { + UNICODE_STRING win32Name = RTL_CONSTANT_STRING(WIN32_NAME); + IoDeleteSymbolicLink(&win32Name); + } + + if(driverObject->DeviceObject) + IoDeleteDevice(driverObject->DeviceObject); +} + + +#pragma code_seg(pop) // make sure we don't countermand the alloc_text + +NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath) +{ + UNICODE_STRING deviceName = RTL_CONSTANT_STRING(DEVICE_NAME); + + // create device object + PDEVICE_OBJECT deviceObject; + { + const ULONG deviceExtensionSize = 0; + const ULONG deviceCharacteristics = FILE_DEVICE_SECURE_OPEN; + const BOOLEAN exlusive = TRUE; + NTSTATUS ntStatus = IoCreateDevice(driverObject, deviceExtensionSize, &deviceName, FILE_DEVICE_AKEN, deviceCharacteristics, exlusive, &deviceObject); + if(!NT_SUCCESS(ntStatus)) + { + KdPrint(("DriverEntry: IoCreateDevice failed\n")); + return ntStatus; + } + } + + // set entry points + driverObject->MajorFunction[IRP_MJ_CREATE] = AkenCreate; + driverObject->MajorFunction[IRP_MJ_CLOSE] = AkenClose; + driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AkenDeviceControl; + driverObject->DriverUnload = AkenUnload; + + // symlink NT device name to Win32 namespace + { + UNICODE_STRING win32Name = RTL_CONSTANT_STRING(WIN32_NAME); + NTSTATUS ntStatus = IoCreateSymbolicLink(&win32Name, &deviceName); + if(!NT_SUCCESS(ntStatus)) + { + KdPrint(("DriverEntry: IoCreateSymbolicLink failed\n")); + IoDeleteDevice(deviceObject); + return ntStatus; + } + } + + return STATUS_SUCCESS; +} diff --git a/source/lib/sysdep/os/win/aken/build_all.bat b/source/lib/sysdep/os/win/aken/build_all.bat new file mode 100644 index 0000000000..c7a598e353 --- /dev/null +++ b/source/lib/sysdep/os/win/aken/build_all.bat @@ -0,0 +1,32 @@ +@echo off +REM ensure header is up to date (simpler than setting include path) +copy ..\..\..\..\..\include\lib\sysdep\os\win\aken\aken.h + +cmd /c build_single.bat chk x64 +cmd /c build_single.bat fre x64 +cmd /c build_single.bat chk x86 +REM must come last because each build_single.bat deletes aken.sys, +REM and that is the final output name of this step +cmd /c build_single.bat fre x86 + +cd amd64 +copy /y aken64*.pdb ..\..\..\..\..\..\..\bin\x64 +copy /y aken64*.sys ..\..\..\..\..\..\..\bin\x64 +cd .. + +cd i386 +copy /y aken*.pdb ..\..\..\..\..\..\..\bin\Win32 +copy /y aken*.sys ..\..\..\..\..\..\..\bin\Win32 +cd .. + +echo outputs copied to bin directory; will delete ALL output files after pressing a key +pause +if exist amd64 (rmdir /S /Q amd64) +if exist i386 (rmdir /S /Q i386) +if exist objchk_wnet_amd64 (rmdir /S /Q objchk_wnet_amd64) +if exist objfre_wnet_amd64 (rmdir /S /Q objfre_wnet_amd64) +if exist objchk_wnet_x86 (rmdir /S /Q objchk_wnet_x86) +if exist objfre_wnet_x86 (rmdir /S /Q objfre_wnet_x86) +if exist *.log (del /Q *.log) +if exist *.err (del /Q *.err) +if exist *.wrn (del /Q *.wrn) \ No newline at end of file diff --git a/source/lib/sysdep/os/win/aken/build_single.bat b/source/lib/sysdep/os/win/aken/build_single.bat new file mode 100644 index 0000000000..7cd6e7fc0c --- /dev/null +++ b/source/lib/sysdep/os/win/aken/build_single.bat @@ -0,0 +1,67 @@ +@echo off +REM build a single configuration ({chk,fre} x {x64,x64}) +REM (must be in a separate file to allow invoking in a new cmd - otherwise, +REM setenv complains that the environment have already been set) +REM arguments: chk|fre x64|x86 +if %1==chk (goto configOK) +if %1==fre (goto configOK) +echo first parameter must be either chk or fre +goto :eof +:configOK +if %2==x64 (goto archOK) +if %2==x86 (goto archOK) +echo second parameter must be either x64 or x64 +goto :eof +:archOK + + +call C:\WinDDK\7600.16385.1\bin\setenv.bat C:\WinDDK\7600.16385.1\ %1 %2 WNET +e: +cd \FOM_Work\Programmierung\lowlevel\src\sysdep\os\win\aken + + +REM delete outputs to ensure they get rebuilt +if %2==x64 (goto delete64) else (goto delete32) + +:delete64 +if not exist amd64 (goto deleteEnd) +cd amd64 +if exist aken.sys (del /Q aken.sys) +if exist aken.pdb (del /Q aken.pdb) +cd .. +goto deleteEnd + +:delete32 +if not exist i386 (goto deleteEnd) +cd i386 +if exist aken.sys (del /Q aken.sys) +if exist aken.pdb (del /Q aken.pdb) +cd .. +goto deleteEnd + +:deleteEnd + + +build + + +REM rename outputs in preparation for build_all's copying them to the binaries directories +if %2==x64 (goto rename64) else (goto rename32) + +:rename64 +if not exist amd64 (goto renameEnd) +cd amd64 +if %1==chk (ren aken.pdb aken64d.pdb) else (ren aken.pdb aken64.pdb) +if %1==chk (ren aken.sys aken64d.sys) else (ren aken.sys aken64.sys) +cd .. +goto renameEnd + +:rename32 +if not exist i386 (goto renameEnd) +cd i386 +if %1==chk (ren aken.pdb akend.pdb) +if %1==chk (ren aken.sys akend.sys) +cd .. +goto renameEnd + +:renameEnd diff --git a/source/lib/sysdep/os/win/aken/sources b/source/lib/sysdep/os/win/aken/sources index 907c216dab..ce0b5aa055 100644 --- a/source/lib/sysdep/os/win/aken/sources +++ b/source/lib/sysdep/os/win/aken/sources @@ -2,4 +2,4 @@ TARGETNAME=aken TARGETPATH=. TARGETTYPE=DRIVER -SOURCES=aken.cpp +SOURCES=aken.c