summaryrefslogtreecommitdiffstats
path: root/private/net/portuas/logfile.c
blob: b259e7db778f5ea66ebfd2078ceb6411a7405a91 (plain) (blame)
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