1 ////////////////////////////////////////////////////////////////////
2 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
5 ////////////////////////////////////////////////////////////////////
6 
7 extern "C"
8 ULONG
9 MyRtlCompareMemory(
10     PVOID s1,
11     PVOID s2,
12     ULONG len
13     )
14 {
15     ULONG i;
16 
17     for(i=0; i<len; i++) {
18         if( ((char*)s1)[i] != ((char*)s2)[i] )
19             break;
20     }
21     return i;
22 }
23 
24 #define STRING_BUFFER_ALIGNMENT  (32)
25 #define STRING_BUFFER_ALIGN(sz)  (((sz)+STRING_BUFFER_ALIGNMENT)&(~((ULONG)(STRING_BUFFER_ALIGNMENT-1))))
26 
27 #ifndef NT_NATIVE_MODE
28 
29 extern "C"
30 ULONG
31 RtlCompareUnicodeString(
32     PUNICODE_STRING s1,
33     PUNICODE_STRING s2,
34     BOOLEAN UpCase
35     )
36 {
37     ULONG i;
38 
39     if(s1->Length != s2->Length) return (-1);
40     i = memcmp(s1->Buffer, s2->Buffer, (s1->Length) ? (s1->Length) : (s2->Length));
41     return i;
42 }
43 
44 extern "C"
45 NTSTATUS
46 RtlUpcaseUnicodeString(
47     PUNICODE_STRING dst,
48     PUNICODE_STRING src,
49     BOOLEAN Alloc
50     )
51 {
52 //    if(s1->Length != s2->Length) return (-1);
53     memcpy(dst->Buffer, src->Buffer, src->Length);
54     dst->Buffer[src->Length/sizeof(WCHAR)] = 0;
55     dst->Length = src->Length;
56     _wcsupr(dst->Buffer);
57     return STATUS_SUCCESS;
58 }
59 
60 extern "C"
61 NTSTATUS
62 RtlAppendUnicodeToString(
63     IN PUNICODE_STRING Str1,
64     IN PWSTR Str2
65     )
66 {
67     PWCHAR tmp;
68     USHORT i;
69 
70 #ifdef _X86_
71 
72     __asm push  ebx
73     __asm push  esi
74     __asm xor   ebx,ebx
75     __asm mov   esi,Str2
76 Scan_1:
77     __asm cmp   [word ptr esi+ebx],0
78     __asm je    EO_Scan
79     __asm add   ebx,2
80     __asm jmp   Scan_1
81 EO_Scan:
82     __asm mov   i,bx
83     __asm pop   esi
84     __asm pop   ebx
85 
86 #else   // NO X86 optimization, use generic C/C++
87 
88     i=0;
89     while(Str2[i]) {
90        i++;
91     }
92     i *= sizeof(WCHAR);
93 
94 #endif // _X86_
95 
96     tmp = Str1->Buffer;
97     ASSERT(Str1->MaximumLength);
98     if((Str1->Length+i+sizeof(WCHAR)) > Str1->MaximumLength) {
99         PWCHAR tmp2 = (PWCHAR)ExAllocatePoolWithTag(NonPagedPool, STRING_BUFFER_ALIGN(i + Str1->Length + sizeof(WCHAR))*2, 'ilTS');
100         if(!tmp2)
101             return STATUS_INSUFFICIENT_RESOURCES;
102         memcpy(tmp2, tmp, Str1->MaximumLength);
103         ExFreePool(tmp);
104         tmp = tmp2;
105         Str1->MaximumLength = STRING_BUFFER_ALIGN(i + sizeof(WCHAR))*2;
106         Str1->Buffer = tmp;
107     }
108     RtlCopyMemory(((PCHAR)tmp)+Str1->Length, Str2, i);
109     i+=Str1->Length;
110     tmp[(i / sizeof(WCHAR))] = 0;
111     Str1->Length = i;
112 
113     return STATUS_SUCCESS;
114 
115 #undef UDF_UNC_STR_TAG
116 
117 } // end RtlAppendUnicodeToString()
118 
119 #endif //NT_NATIVE_MODE
120 
121 #ifdef CDRW_W32
122 NTSTATUS
123 MyInitUnicodeString(
124     IN PUNICODE_STRING Str1,
125     IN PCWSTR Str2
126     )
127 {
128 
129     USHORT i;
130 
131 #ifdef _X86_
132 
133     __asm push  ebx
134     __asm push  esi
135     __asm xor   ebx,ebx
136     __asm mov   esi,Str2
137 Scan_1:
138     __asm cmp   [word ptr esi+ebx],0
139     __asm je    EO_Scan
140     __asm add   ebx,2
141     __asm jmp   Scan_1
142 EO_Scan:
143     __asm mov   i,bx
144     __asm pop   esi
145     __asm pop   ebx
146 
147 #else   // NO X86 optimization, use generic C/C++
148 
149     i=0;
150     while(Str2[i]) {
151        i++;
152     }
153     i *= sizeof(WCHAR);
154 
155 #endif // _X86_
156 
157     Str1->MaximumLength = STRING_BUFFER_ALIGN((Str1->Length = i) + sizeof(WCHAR));
158     Str1->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool, Str1->MaximumLength);
159     if(!Str1->Buffer)
160         return STATUS_INSUFFICIENT_RESOURCES;
161     RtlCopyMemory(Str1->Buffer, Str2, i);
162     Str1->Buffer[i/sizeof(WCHAR)] = 0;
163     return STATUS_SUCCESS;
164 
165 } // end MyInitUnicodeString()
166 #endif //CDRW_W32