Add Dirk Luetjen's ssphys libraries and command-line tool
[vss2svn.git] / ssphys / SSPhysLib / SSTypes.h
blobae903c40c7bc4beaa04c1d2b572ed5b240e9e4f2
1 // SSTypes.h:structure definitions for SourceSafe files
2 //
3 //////////////////////////////////////////////////////////////////////
5 #if !defined(AFX_SSTYPES_H__6602C07F_65ED_4FD7_A730_6D416805378A__INCLUDED_)
6 #define AFX_SSTYPES_H__6602C07F_65ED_4FD7_A730_6D416805378A__INCLUDED_
8 #if _MSC_VER > 1000
9 #pragma once
10 #endif // _MSC_VER > 1000
13 #include "time.h"
14 #include <boost/preprocessor/seq.hpp>
15 #include <boost/preprocessor/control.hpp>
16 #include <boost/preprocessor/comparison/greater.hpp>
18 typedef unsigned char byte;
19 typedef unsigned long ulong;
20 typedef unsigned short ushort;
22 inline std::string toString (const char* ch, int len)
24 return std::string (ch, len);
27 inline std::string timeToString (const time_t& t, int len)
29 char date[12];
30 char time[12];
31 const char* format2 = "Date: %-8s Time: %s";
32 const tm* ttm = gmtime (&t);//localtime (&versionDate);
33 strftime (date, countof (date), "%x", ttm);
34 strftime (time, countof (time), "%X", ttm);
35 char line2[60]; _snprintf (line2, 60, format2, date, time);
36 return line2;
39 //---------------------------------------------------------------------------
40 // OLE API documentation
41 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvss/html/vssauto.asp
43 //---------------------------------------------------------------------------
44 //struct RECORD_HEADER {
45 // ulong size;
46 // char type[2];
47 // short checksum;
48 //};
50 #define SS_TYPE_I(T) BOOST_PP_SEQ_ELEM(0, T)
51 #define SS_VARIABLE_I(T) BOOST_PP_SEQ_ELEM(1, T)
52 #define SS_ARRAYSIZE_I(T) BOOST_PP_SEQ_ELEM(2, T)
53 #define SS_RETURNTYPE_I(T) BOOST_PP_SEQ_ELEM(3, T)
54 #define SS_CONVFUNC_I(T) BOOST_PP_SEQ_ELEM(4, T)
56 #define SS_IS_ARRAY_I(T) BOOST_PP_IF (BOOST_PP_GREATER(BOOST_PP_SEQ_SIZE(T),2), BOOST_PP_GREATER(SS_ARRAYSIZE_I(T),1), 0)
57 #define SS_ARRAY_DECL(T) BOOST_PP_CAT([, BOOST_PP_CAT(SS_ARRAYSIZE_I(T), ]))
59 #define SS_IS_RETURNTYPE_I(T) BOOST_PP_GREATER(BOOST_PP_SEQ_SIZE(T),3)
60 #define SS_IS_CONVFUNC_I(T) BOOST_PP_GREATER(BOOST_PP_SEQ_SIZE(T),4)
62 #define SS_TYPE(T) SS_TYPE_I(T)
63 #define SS_NAME(T) SS_VARIABLE_I(T)
64 #define SS_VARIABLE_DECL(T) BOOST_PP_IF(SS_IS_ARRAY_I(T), BOOST_PP_CAT(SS_VARIABLE_I(T), SS_ARRAY_DECL(T)), SS_VARIABLE_I(T))
65 #define SS_RETURNTYPE(T) BOOST_PP_IF(SS_IS_RETURNTYPE_I(T), SS_RETURNTYPE_I(T), SS_TYPE_I(T))
67 #define SS_ACCESSOR(DATA, T) return (DATA->SS_NAME(T));
68 #define SS_CONVERTER(DATA, T, FUNC) return FUNC (DATA->SS_NAME(T), SS_ARRAYSIZE_I(T));
71 #define DEFINE_ELEMENTS(r, data, T) \
72 SS_TYPE(T) SS_VARIABLE_DECL(T);
74 #define SS_STRUCT(name, fields) \
75 struct name \
76 { \
77 BOOST_PP_SEQ_FOR_EACH(DEFINE_ELEMENTS, ~, fields) \
80 #define DEFINE_ACCESSORS(R, DATA, T) \
81 SS_RETURNTYPE(T) BOOST_PP_CAT (Get, SS_NAME(T)) () const\
82 { \
83 BOOST_PP_IF(SS_IS_CONVFUNC_I(T), SS_CONVERTER(DATA, T, SS_CONVFUNC_I(T)), SS_ACCESSOR(DATA, T)); \
87 #define RECORD_HEADER_SEQ \
88 ((ulong) (size)) \
89 ((char) (type) (2) (std::string) (toString)) \
90 ((short) (checksum))
92 SS_STRUCT(RECORD_HEADER, RECORD_HEADER_SEQ);
95 //struct SSNAME {
96 // short flags; // 00 = item, 01 == project
97 // char name[34]; // short name
98 // ulong nsmap; // offset into the names.dat
100 //};
102 #define SSNAME_SEQ \
103 ((short) (flags)) /* 00 = item, 01 == project */ \
104 ((char) (name) (34) (std::string) (toString)) /* short name */ \
105 ((ulong) (nsmap)) /* offset into the names.dat */
107 SS_STRUCT(SSNAME, SSNAME_SEQ);
109 // TODO: in the OLE API: VSSITEM_PROJECT = 0; VSSITEM_FILE = 1
110 #define SSITEM_PROJECT 1
111 #define SSITEM_FILE 2
113 enum eFileType
115 eFileTypeBinary,
116 eFileTypeText
120 //struct DH {
121 // short type; // 1 Project, 2 File
123 // short numberOfRecords;
125 // // This is the last name that was given to the item
126 // SSNAME name;
127 // char dummy2[2];
128 // char fileExt[2]; // .A or .B
130 // // offsets for records
131 // ulong i1; // first EL Header
132 // ulong i2; // last EL oder FD HEader
133 // ulong i3; // size of the file
134 //};
136 #define DH_SEQ \
137 ((short) (Type)) /* 1 Project, 2 File */ \
138 ((short) (NumberOfActions)) \
140 /* This is the last name that was given to the item */ \
141 ((SSNAME) (SSName)) \
142 ((char) (Dummy) (2) (std::string) (toString)) \
143 ((char) (LatestExt) (2) (std::string) (toString)) /* .A or .B */ \
145 /* offsets for records */ \
146 ((ulong) (HistoryOffsetBegin)) /* first EL Header */ \
147 ((ulong) (HistoryOffsetLast)) /* last EL oder FD HEader */ \
148 ((ulong) (HistoryOffsetEnd)) /* size of the file */
150 SS_STRUCT (DH, DH_SEQ);
154 struct DH_FILE : public DH {
155 char dummy4[20];
157 // 0x00 == initial
158 // 0x02 == binary
159 // 0x04 == store only latest revision
160 // 0x41 == checked out
161 // 0x20 == shared
162 short Flag;
163 char ShareSrcSpec[10];
165 ulong OffsetBFRecord; // offset to the last BR record in the file
166 ulong OffsetPFRecord; // offset to the last PF record in the file
167 short NumberOfBranches; // number of the BF records
168 short NumberOfReferences; // Reference count for the item
170 ulong OffsetCFRecord1; // file checked out, ptr to CF record
171 ulong OffsetCFRecord2; // file not checked out, ptr to CF record
172 int unknown; // changes after checkin
174 char dummy5[8];
176 // diese scheinen immer Paare zu bilden, nach einem Checkin ändert sich
177 // der d11, d21
178 // d12 == d22 == d32
179 short d11;
180 short d12;
181 short d21;
182 short d22;
183 short d31;
184 short d32;
186 char dummy6[4];
188 // dito wie dxx, jedoch zum ersten mal nach einem Checkin
189 short e11;
190 short e12;
191 short e21;
192 short e22;
193 short e31;
194 short e32;
196 char dummy7[200];
198 short NumberOfItems; // including projects
199 short NumberOfProjects; // number of subprojects
202 struct DH_PROJECT : public DH {
203 char dummy4[20];
205 char ParentSpec[258]; // of last checkout
206 short dummy7;
208 char ParentPhys[10];
209 char dummy8[2];
211 short NumberOfItems; // including projects
212 short NumberOfProjects;
215 enum eAction {
216 Labeled = 0,
217 Created_Project = 1,
218 Added_Project = 2,
219 Added_File = 3,
220 Destroyed_Project = 4,
221 Destroyed_File = 5,
222 Deleted_Project = 6,
223 Deleted_File = 7,
224 Recovered_Project = 8,
225 Recovered_File = 9,
226 Renamed_Project = 10,
227 Renamed_File = 11,
228 // missing action 12,
229 // missing action 13
230 Shared_File = 14, // Share, Pin, Unpin
231 Branch_File = 15, // reported as Rollback im Parent Project
232 Created_File = 16,
233 Checked_in = 17,
234 // missing action 18
235 RollBack = 19
236 // missing known actions: archives, restores
239 inline eAction ushortToAction (const ushort& v, int)
241 return static_cast <eAction> (v);
244 #define VERSION_RECORD_SEQ \
245 ((ulong) (Previous)) /* previous VERSION_RECORD */ \
246 ((ushort) (ActionID) (1) (eAction) (ushortToAction)) /* eAction action */ \
247 ((short) (VersionNumber)) \
248 ((time_t) (Date) (1) (std::string) (timeToString)) \
249 ((char) (Username) (32) (std::string) (toString)) \
251 ((char) (Label) (32) (std::string) (toString)) \
253 /* This seems to be always be a pointer to the next record \
254 If (lengthComment != 0) this next record is the comment record */ \
255 ((ulong) (OffsetToNextRecordOrComment)) \
257 /* This offset seems to be NULL in most cases \
258 In case of a LabelAction this is the offset to the so called LabelComment Record \
259 In addition the lengthLabelComment is > 0 */ \
260 ((ulong) (OffsetToLabelComment)) \
262 /* Length of the comment strings */ \
263 ((short) (LengthComment)) \
264 ((short) (LengthLabelComment))
266 SS_STRUCT (VERSION_RECORD, VERSION_RECORD_SEQ);
268 //struct VERSION_RECORD {
269 // ulong previous; // previous VERSION_RECORD
270 // ushort action; // eAction action;
271 // short version;
272 // time_t date;
273 // char user[32];
275 // char label[32];
277 // // This seems to be always be a pointer to the next record
278 // // If (lengthComment != 0) this next record is the comment record
279 // ulong offsetToNextRecordOrComment;
281 // // This offset seems to be NULL in most cases
282 // // In case of a LabelAction this is the offset to the so called LabelComment Record
283 // // In addition the lengthLabelComment is > 0
284 // ulong offsetToLabelComment;
286 // // Length of the comment strings
287 // short lengthComment;
288 // short lengthLabelComment;
289 //};
291 struct ITEM_ACTION {
292 SSNAME name;
293 char physical[10];
296 //struct CREATED_PROJECT_ACTION {
297 // SSNAME name;
298 // char physical[10];
299 //} ;
301 //struct ADDED_PROJECT_ACTION {
302 // SSNAME name;
303 // char physical[10];
304 //} ;
306 //struct ADDED_FILE_ACTION {
307 // SSNAME name;
308 // char physical[10];
309 //} ;
311 struct DESTROYED_ACTION {
312 SSNAME name;
313 short padding;
314 char physical[10];
317 //struct DESTROYED_PROJECT_ACTION {
318 // SSNAME name;
319 // short padding;
320 // char physical[10];
321 //} ;
323 //struct DESTROYED_FILE_ACTION {
324 // SSNAME name;
325 // short padding;
326 // char physical[10];
327 //} ;
329 //struct DELETED_PROJECT_ACTION {
330 // SSNAME name;
331 // char physical[10];
332 //} ;
334 //struct DELETED_FILE_ACTION {
335 // SSNAME name;
336 // char physical[10];
337 //} ;
339 //struct RECOVERED_PROJECT_ACTION {
340 // SSNAME name;
341 // char physical[10];
342 //} ;
344 //struct RECOVERED_FILE_ACTION {
345 // SSNAME name;
346 // char physical[10];
347 //} ;
349 struct RENAMED_ACTION {
350 SSNAME newName;
351 SSNAME name; // old name
352 char physical[10];
355 struct SHARED_FILE_ACTION {
356 char srcPathSpec[260];
357 SSNAME name;
358 short pinnedToVersion; // -1: shared, 0: pinned; >0 unpinned und letzte Version?
359 short version; // >0: version, ==0 unpinned
360 short padding2; // reference ins project file? Nr des shares?
361 char physical[10];
364 //struct CREATED_FILE_ACTION {
365 // SSNAME name;
366 // char physical[10];
367 //} ;
369 struct CHECKED_IN_ACTION {
370 ulong offsetFileDelta;
371 long padding;
372 char checkInSpec[260];
375 struct ROLLBACK_ACTION {
376 SSNAME name;
377 char physical[10];
378 char parent[10];
382 struct CF {
383 char User[32];
384 char Padding[4];
385 // zusammen 260?
386 char CheckOutFolder[256];
387 char Padding2[4];
388 char Computer[32];
389 // zusammen 260
390 // char parentSpec[80];
391 // char fileSpec2[60];
392 // char padding3[120];
393 char ParentSpec[260];
395 char Comment[13];
396 char Padding4[51];
398 // initial alles 0
399 // Check Out: flag1=01, flag2=40, flag3=00
400 // Check In : flag1=00, flag2=00, flag3=10
401 char Flag1;
402 char Padding5;
403 char Flag2;
404 char Padding6[8];
405 char Flag3;
406 int NumberOfVersions;
409 struct FD {
410 short command; // 01 copy, 00 replace, 02
411 short dummy;
412 ulong start;
413 ulong end;
416 struct PF {
417 ulong PreviousOffset;
418 char ParentPhys[10];
419 short padding;
422 struct BF {
423 ulong PreviousOffset;
424 char BranchToPhys[10];
425 short padding;
428 //---------------------------------------------------------------------------
429 struct PROJECT_ENTRY{
430 short type;
431 // 0x01 deleted
432 // 0x02 store binary diffs
433 // 0x04 store only latest revision
434 // 0x08 shared
435 short flags;
436 SSNAME name;
437 short pinnedToVersion;
438 char phys[10];
441 //---------------------------------------------------------------------------
442 struct HN {
443 ulong size;
444 char type[2];
445 short checksum;
446 char unknown1[16];
447 ulong fileLen;
448 char unknown2[60];
451 struct NSENTRY{
452 // 1: 8.3 Name
453 // 2: voller name
454 // 3: 28.3 Name //?
455 // 10: Projekte
456 short id;
457 short offset;
460 struct NSMAP{
461 short num;
462 short unknown;
467 //---------------------------------------------------------------------------
468 class CAction
470 public:
471 static const char* ActionToString (eAction e);
476 #endif // !defined(AFX_SSTYPES_H__6602C07F_65ED_4FD7_A730_6D416805378A__INCLUDED_)