summaryrefslogtreecommitdiffstats
path: root/private/net/svcdlls/repl/common/impbuild.c
blob: 8043fd8fc0f4e27cefa29270427cce72b862ae09 (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
/*++

Copyright (c) 1992-1993  Microsoft Corporation

Module Name:

    ImpBuild.c

Abstract:

    This file contains ImportDirBuildApiRecord.  This is used by
    NetrReplImportDirGetInfo and NetrReplImportDirEnum.

Author:

    John Rogers (JohnRo) 08-Jan-1992

Environment:

    Portable to any flat, 32-bit environment.  (Uses Win32 typedefs.)
    Requires ANSI C extensions: slash-slash comments, long external names.

Notes:

    This code assumes that the import dir info levels are subsets of each other.

Revision History:

    08-Jan-1992 JohnRo
        Created.
    24-Jan-1992 JohnRo
        Changed to use LPTSTR etc.
    27-Jan-1992 JohnRo
        Changed interface to allow use when service is not running.
    21-Feb-1992 JohnRo
        Fixed bug checking state parameter.
        UncMaster parm is optional.
        Added check of UncMaster validity.
        Undid redundant checks of Buffer (3 of them!)
    21-Feb-1992 JohnRo
        Changed ImportDirBuildApiRecord() so master name is not a UNC name.
    22-Feb-1992 JohnRo
        Made changes suggested by PC-LINT.
    26-Feb-1992 JohnRo
        Check lock fields for validity.
        API records now contain timestamps instead of elapsed times.
        Added assertion of valid record at end.
    25-Mar-1992 JohnRo
        Avoid obsolete state values.
    27-Mar-1992 JohnRo
        Allow MasterName to point to a null char.
    28-Jul-1992 JohnRo
        RAID 2274: repl svc should impersonate caller.
        Added debug output of structure after we build it.
    30-Apr-1993 JohnRo
        Use NetpKdPrint() where possible.

--*/


// These must be included first:

#include <windef.h>     // IN, VOID, LPTSTR, etc.
#include <lmcons.h>     // NET_API_STATUS.
#include <repldefs.h>   // ReplIsIntegrityValid(), IF_DEBUG(), SLASH_SLASH, etc.

// These can be in any order:

#include <align.h>      // POINTER_IS_ALIGNED(), ALIGN_TCHAR.
#include <dirname.h>    // ReplIsDirNameValid().
#include <impdir.h>     // My prototype, ImportDirIsLevelValid().
#include <lmrepl.h>     // LPREPL_IDIR_INFO_1, REPL_EXTENT_ stuff, etc.
#include <names.h>      // NetpIsComputerNameValid().
#include <netdebug.h>   // NetpAssert(), NetpKdPrint(), etc.
#include <prefix.h>     // PREFIX_ equates.
#include <tstr.h>       // STRLEN(), TCHAR_EOS, etc.
#include <winerror.h>   // ERROR_ equates, NO_ERROR.


NET_API_STATUS
ImportDirBuildApiRecord (
    IN DWORD Level,
    IN LPTSTR DirName,
    IN DWORD State,
    IN LPTSTR MasterName OPTIONAL,      // computer name (not UNC).
    IN DWORD TimeOfLastUpdate,          // Seconds since 1970.
    IN DWORD LockCount,
    IN DWORD TimeOfFirstLock,           // Seconds since 1970.
    OUT LPVOID Buffer,
    IN OUT LPBYTE *StringLocation       // Points just past top of data.
    )

{
    LPREPL_IDIR_INFO_1 ApiRecord = Buffer;  // superset info level
    LPTSTR StringDest;
    DWORD StringLength;

    NetpAssert( StringLocation != NULL);
    NetpAssert( *StringLocation != NULL);

    IF_DEBUG( IMPAPI ) {
        NetpKdPrint(( PREFIX_REPL
                "ImportDirBuildApiRecord: building record at " FORMAT_LPVOID
                ", *str loc is " FORMAT_LPVOID ".\n",
                (LPVOID) Buffer, (LPVOID) *StringLocation ));
    }

    if ( (MasterName != NULL) && ((*MasterName) == TCHAR_EOS) ) {
        MasterName = NULL;
    }

    //
    // Check for caller errors.
    //
    if ( ! ReplIsDirNameValid( DirName ) ) {
        return (ERROR_INVALID_DATA);
    } else if (Buffer == NULL) {
        return (ERROR_INVALID_PARAMETER);
    } else if ( !ReplIsStateValid( State ) ) {
        return (ERROR_INVALID_DATA);
    } else if ( !ImportDirIsLevelValid( Level ) ) {
        return (ERROR_INVALID_LEVEL);
    } else if ((MasterName!=NULL) && !NetpIsComputerNameValid(MasterName)) {
        return (ERROR_INVALID_PARAMETER);
    } else if ( !ReplAreLockFieldsValid( LockCount, TimeOfFirstLock ) ) {
        return (ERROR_INVALID_PARAMETER);
    }

    //
    // First do subset common to both info levels.
    //
    StringLength = (DWORD) STRLEN( DirName );

    NetpAssert( POINTER_IS_ALIGNED( *StringLocation, ALIGN_TCHAR ) );
    StringDest = (LPTSTR) (LPVOID) (*StringLocation);
    StringDest -= (StringLength + 1);

    *StringLocation = (LPBYTE) (LPVOID) StringDest;

    ApiRecord->rpid1_dirname = StringDest;

    (void) STRCPY(
            StringDest,                 // dest
            DirName);                   // src

    //
    // Next do stuff only found in level 1.
    //
    if (Level > 0) {

        //
        // Do master name (only other string)...
        //
        if (MasterName != NULL) {
            StringLength = (DWORD) STRLEN( MasterName ) + 2; // Ch to UNC.

            NetpAssert( POINTER_IS_ALIGNED( *StringLocation, ALIGN_TCHAR ) );
            StringDest = (LPTSTR) (LPVOID) (*StringLocation);
            StringDest -= (StringLength + 1);

            *StringLocation = (LPBYTE) (LPVOID) StringDest;

            ApiRecord->rpid1_mastername = StringDest;

            (void) STRCPY(
                    StringDest,         // dest
                    SLASH_SLASH );      // src
            (void) STRCAT(
                    StringDest,         // dest
                    MasterName);        // src
        } else {
            ApiRecord->rpid1_mastername = NULL;
        }

        //
        // Now do simple stuff...
        //
        {
            ApiRecord->rpid1_state = State;
        }

        ApiRecord->rpid1_last_update_time = TimeOfLastUpdate;

        ApiRecord->rpid1_lockcount = LockCount;

        if (TimeOfFirstLock == 0) {
            ApiRecord->rpid1_locktime = 0;
        } else {
            ApiRecord->rpid1_locktime = TimeOfFirstLock;
        }
    }

    IF_DEBUG( IMPAPI ) {
        NetpKdPrint(( PREFIX_REPL
                "ImportDirBuildApiRecord: built structure:\n" ));
        NetpDbgDisplayReplImportDir( Level, Buffer );
    }

    NetpAssert( ImportDirIsApiRecordValid( Level, ApiRecord, NULL ) );

    return (NO_ERROR);

}