--- /dev/null
+
+#include <windows.h>
+#include <ddk/ntddk.h>
+#include <kernel32/error.h>
+
+int
+STDCALL
+LoadStringA( HINSTANCE hInstance,
+ UINT uID,
+ LPSTR lpBuffer,
+ int nBufferMax)
+{
+ HRSRC rsc;
+ PBYTE ptr;
+ int len;
+ int count, dest = uID % 16;
+ PWSTR pwstr;
+ UNICODE_STRING UString;
+ ANSI_STRING AString;
+ NTSTATUS Status;
+
+ rsc = FindResource( (HMODULE)hInstance,
+ MAKEINTRESOURCE( (uID / 16) + 1 ),
+ RT_STRING );
+ if( rsc == NULL )
+ return 0;
+ // get pointer to string table
+ ptr = (PBYTE)LoadResource( (HMODULE)hInstance, rsc );
+ if( ptr == NULL )
+ return 0;
+ for( count = 0; count <= dest; count++ )
+ {
+ // walk each of the 16 string slots in the string table
+ len = (*(USHORT *)ptr) * 2; // length is in unicode chars, convert to bytes
+ ptr += 2; // first 2 bytes are length, string follows
+ pwstr = (PWSTR)ptr;
+ ptr += len;
+ }
+ if( !len )
+ return 0; // zero means no string is there
+ // convert unitocde to ansi, and copy string to caller buffer
+ UString.Length = UString.MaximumLength = len;
+ UString.Buffer = pwstr;
+ memset( &AString, 0, sizeof AString );
+ Status = RtlUnicodeStringToAnsiString( &AString, &UString, TRUE );
+ if( !NT_SUCCESS( Status ) )
+ {
+ SetLastErrorByStatus( Status );
+ return 0;
+ }
+ nBufferMax--; // save room for the null
+ if( nBufferMax > AString.Length )
+ nBufferMax = AString.Length;
+ memcpy( lpBuffer, AString.Buffer, nBufferMax );
+ lpBuffer[nBufferMax] = 0;
+ RtlFreeAnsiString( &AString );
+ return nBufferMax;
+}
+