1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
LogFile.c
Abstract:
Port UAS log file routines:
PortUasOpenLogFile
PortUasWriteToLogFile
PortUasCloseLogFile
Author:
JR (John Rogers, JohnRo@Microsoft) 02-Sep-1993
Environment:
Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
02-Sep-1993 JohnRo
Created to add PortUAS /log:filename switch for Cheetah.
--*/
// These must be included first:
#include <nt.h> // Needed by <portuasp.h>
#include <ntrtl.h> // (Needed with nt.h and windows.h)
#include <nturtl.h> // (Needed with ntrtl.h and windows.h)
#include <windows.h> // IN, LPWSTR, BOOL, etc.
#include <lmcons.h> // NET_API_STATUS.
// These may be included in any order:
#include <lmapibuf.h> // NetApiBufferFree().
#include <netdebug.h> // NetpKdPrint(), FORMAT_ equates.
#include <portuasp.h> // My prototypes.
#include <prefix.h> // PREFIX_ equates.
#include <tstring.h> // NetpAlloc{type}From{type}, TCHAR_EOS.
#include <winerror.h> // ERROR_ equates, NO_ERROR.
NET_API_STATUS
PortUasOpenLogFile(
IN LPCTSTR FileName,
OUT LPHANDLE ResultHandle
)
/*++
Routine Description:
PortUasOpenLogFile opens a PortUAS log file for a given file
name and passes back a handle for use in writing to the file.
This handle is expected to only be passed to PortUasWriteToLogFile
and PortUasCloseLogFile.
Arguments:
FileName - The name of the file to be created as a log file. This
might be of the form "d:\mystuff\first.log", ".\junk.txt", or even
a UNC name like "\\myserver\share\x\y\z". This file must not already
exist, or an error will be returned.
CODEWORK: If the file already exists, we might want to consider
having this routine do one or more of the following:
- prompt for a new file name
- prompt for permission to delete the existing file
- prompt for permission to append to the existing file
ResultHandle - Points to a HANDLE variable which will be filled-in with
a handle to be used to process the log file. This handle is only
intended to be passed to PortUasWriteToLogFile and PortUasCloseLogFile.
Return Value:
NET_API_STATUS.
--*/
{
NET_API_STATUS ApiStatus;
HANDLE TheHandle = INVALID_HANDLE_VALUE;
if ( (FileName==NULL) || ((*FileName)==TCHAR_EOS) ) {
ApiStatus = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
if (ResultHandle == NULL) {
ApiStatus = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
TheHandle = CreateFile(
FileName,
GENERIC_WRITE, // desired access
0, // share mode (none)
NULL, // no security attr
CREATE_NEW, // disposition create new (fail exist)
0, // flags and attributes: normal
(HANDLE) NULL ); // no template
if (TheHandle == INVALID_HANDLE_VALUE) {
ApiStatus = (NET_API_STATUS) GetLastError();
NetpAssert( ApiStatus != NO_ERROR );
goto Cleanup; // Don't forget to release lock(s)...
}
ApiStatus = NO_ERROR;
Cleanup:
if (ApiStatus == NO_ERROR) {
NetpAssert( ResultHandle != NULL );
NetpAssert( TheHandle != INVALID_HANDLE_VALUE );
*ResultHandle = TheHandle;
} else {
if (ResultHandle != NULL) {
*ResultHandle = INVALID_HANDLE_VALUE;
}
NetpKdPrint(( PREFIX_PORTUAS
"PortUasOpenLogFile FAILED: status=" FORMAT_API_STATUS ".\n",
ApiStatus ));
}
return (ApiStatus);
} // PortUasOpenLogFile
NET_API_STATUS
PortUasWriteToLogFile(
IN HANDLE LogFileHandle,
IN LPCTSTR TextToLog
)
/*++
Routine Description:
PortUasWriteToLogFile appends the given text to the given log file.
Arguments:
LogFileHandle - Must refer to an open log file, from PortUasOpenLogFile.
TextToLog - Contains text to be appended to the log file. This text
may contain newline characters to break the output into multiple
lines. PortUasWriteToLogFile does not automatically do any line
breaks.
Return Value:
NET_API_STATUS.
--*/
{
NET_API_STATUS ApiStatus;
DWORD BytesWritten = 0;
BOOL OK;
DWORD SizeToWrite; // str buffer size (in bytes, w/o '\0' char).
LPSTR StrBuffer = NULL;
NetpAssert( LogFileHandle != INVALID_HANDLE_VALUE );
NetpAssert( TextToLog != NULL );
//FARBUGBUG You should consider writing the file in the input codepage,
//FARBUGBUG rather than in the default. An alternative would be to
//FARBUGBUG write a Unicode log file, which can be displayed by the
//FARBUGBUG TYPE command, or in unipad.
StrBuffer = NetpAllocStrFromTStr( (LPVOID) TextToLog );
if (StrBuffer == NULL) {
ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
SizeToWrite = strlen( StrBuffer ); // buff size, not including '\0' char.
OK = WriteFile(
LogFileHandle,
StrBuffer,
SizeToWrite, // number of bytes to write
&BytesWritten, // bytes actually written
NULL ); // no overlapped structure
if ( !OK ) {
ApiStatus = (NET_API_STATUS) GetLastError();
NetpAssert( ApiStatus != NO_ERROR );
goto Cleanup;
}
NetpAssert( SizeToWrite == BytesWritten );
ApiStatus = NO_ERROR;
Cleanup:
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( PREFIX_PORTUAS
"PortUasWriteToLogFile FAILED: status=" FORMAT_API_STATUS ".\n",
ApiStatus ));
}
if (StrBuffer != NULL) {
(VOID) NetApiBufferFree( StrBuffer );
}
return (ApiStatus);
} // PortUasWriteToLogFile
NET_API_STATUS
PortUasCloseLogFile(
IN HANDLE LogFileHandle
)
/*++
Routine Description:
PortUasCloseLogFile closes an open log file.
Arguments:
LogFileHandle - Must refer to an open log file, from PortUasOpenLogFile.
Return Value:
NET_API_STATUS.
--*/
{
NET_API_STATUS ApiStatus;
NetpAssert( LogFileHandle != INVALID_HANDLE_VALUE );
if ( !CloseHandle( LogFileHandle ) ) {
ApiStatus = (NET_API_STATUS) GetLastError();
NetpAssert( ApiStatus != NO_ERROR );
goto Cleanup;
}
ApiStatus = NO_ERROR;
Cleanup:
if (ApiStatus != NO_ERROR) {
NetpKdPrint(( PREFIX_PORTUAS
"PortUasCloseLogFile FAILED: status=" FORMAT_API_STATUS ".\n",
ApiStatus ));
}
return (ApiStatus);
} // PortUasCloseLogFile
|