- int reverse=0;
- char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|";
- int len;
-
- while (*fmt && buf<maxbuf) {
- switch (*fmt) {
- case 'a':
- write_bits(CVAL(buf,0),attrib_fmt);
- buf++; fmt++;
- break;
-
- case 'A':
- write_bits(SVAL(buf,0),attrib_fmt);
- buf+=2; fmt++;
- break;
-
- case '{':
- {
- char bitfmt[128];
- char *p = strchr(++fmt,'}');
- int l = PTR_DIFF(p,fmt);
- strncpy(bitfmt,fmt,l);
- bitfmt[l]=0;
- fmt = p+1;
- write_bits(CVAL(buf,0),bitfmt);
- buf++;
- break;
- }
-
- case 'P':
- {
- int l = atoi(fmt+1);
- buf += l;
- fmt++;
- while (isdigit(*fmt)) fmt++;
- break;
- }
- case 'r':
- reverse = !reverse;
- fmt++;
- break;
- case 'D':
- {
- unsigned int x = reverse?RIVAL(buf,0):IVAL(buf,0);
- printf("%d (0x%x)",x, x);
- buf += 4;
- fmt++;
- break;
- }
- case 'L':
- {
- unsigned int x1 = reverse?RIVAL(buf,0):IVAL(buf,0);
- unsigned int x2 = reverse?RIVAL(buf,4):IVAL(buf,4);
- if (x2) {
- printf("0x%08x:%08x",x2, x1);
- } else {
- printf("%d (0x%08x%08x)",x1, x2, x1);
- }
- buf += 8;
- fmt++;
- break;
- }
- case 'd':
- {
- unsigned int x = reverse?RSVAL(buf,0):SVAL(buf,0);
- printf("%d (0x%x)",x, x);
- buf += 2;
- fmt++;
- break;
- }
- case 'W':
- {
- unsigned int x = reverse?RIVAL(buf,0):IVAL(buf,0);
- printf("0x%X",x);
- buf += 4;
- fmt++;
- break;
- }
- case 'w':
- {
- unsigned int x = reverse?RSVAL(buf,0):SVAL(buf,0);
- printf("0x%X",x);
- buf += 2;
- fmt++;
- break;
- }
- case 'B':
- {
- unsigned int x = CVAL(buf,0);
- printf("0x%X",x);
- buf += 1;
- fmt++;
- break;
- }
- case 'b':
- {
- unsigned int x = CVAL(buf,0);
- printf("%d (0x%x)",x, x);
- buf += 1;
- fmt++;
- break;
- }
- case 'S':
- {
- printf("%.*s",(int)PTR_DIFF(maxbuf,buf),unistr(buf, &len));
- buf += len;
- fmt++;
- break;
- }
- case 'Z':
- {
- if (*buf != 4 && *buf != 2)
- printf("Error! ASCIIZ buffer of type %d (safety=%d)\n",
- *buf,(int)PTR_DIFF(maxbuf,buf));
- printf("%.*s",(int)PTR_DIFF(maxbuf,buf+1),unistr(buf+1, &len));
- buf += len+1;
- fmt++;
- break;
- }
- case 's':
- {
- int l = atoi(fmt+1);
- printf("%-*.*s",l,l,buf);
- buf += l;
- fmt++; while (isdigit(*fmt)) fmt++;
- break;
- }
- case 'h':
- {
- int l = atoi(fmt+1);
- while (l--) printf("%02x",*buf++);
- fmt++; while (isdigit(*fmt)) fmt++;
- break;
- }
- case 'n':
- {
- int t = atoi(fmt+1);
- char nbuf[255];
- int name_type;
- int len;
- switch (t) {
- case 1:
- name_type = name_extract(startbuf,PTR_DIFF(buf,startbuf),maxbuf,
- nbuf);
- if (name_type < 0)
- goto trunc;
- len = name_len(buf,maxbuf);
- if (len < 0)
- goto trunc;
- buf += len;
- printf("%-15.15s NameType=0x%02X (%s)",
- nbuf,name_type,name_type_str(name_type));
- break;
- case 2:
- name_type = buf[15];
- printf("%-15.15s NameType=0x%02X (%s)",
- buf,name_type,name_type_str(name_type));
- buf += 16;
- break;
- }
- fmt++; while (isdigit(*fmt)) fmt++;
- break;
- }
- case 'T':
- {
- time_t t;
- int x = IVAL(buf,0);
- switch (atoi(fmt+1)) {
- case 1:
- if (x==0 || x==-1 || x==0xFFFFFFFF)
- t = 0;
- else
- t = make_unix_date(buf);
- buf+=4;
- break;
- case 2:
- if (x==0 || x==-1 || x==0xFFFFFFFF)
- t = 0;
- else
- t = make_unix_date2(buf);
- buf+=4;
- break;
- case 3:
- t = interpret_long_date(buf);
- buf+=8;
- break;
+ int reverse = 0;
+ const char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|";
+ int len;
+
+ while (*fmt && buf<maxbuf) {
+ switch (*fmt) {
+ case 'a':
+ TCHECK(buf[0]);
+ write_bits(buf[0], attrib_fmt);
+ buf++;
+ fmt++;
+ break;
+
+ case 'A':
+ TCHECK2(buf[0], 2);
+ write_bits(EXTRACT_LE_16BITS(buf), attrib_fmt);
+ buf += 2;
+ fmt++;
+ break;
+
+ case '{':
+ {
+ char bitfmt[128];
+ char *p;
+ int l;
+
+ p = strchr(++fmt, '}');
+ l = PTR_DIFF(p, fmt);
+
+ if ((unsigned int)l > sizeof(bitfmt) - 1)
+ l = sizeof(bitfmt)-1;
+
+ strncpy(bitfmt, fmt, l);
+ bitfmt[l] = '\0';
+ fmt = p + 1;
+ TCHECK(buf[0]);
+ write_bits(buf[0], bitfmt);
+ buf++;
+ break;
+ }
+
+ case 'P':
+ {
+ int l = atoi(fmt + 1);
+ TCHECK2(buf[0], l);
+ buf += l;
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'r':
+ reverse = !reverse;
+ fmt++;
+ break;
+ case 'b':
+ {
+ unsigned int x;
+ TCHECK(buf[0]);
+ x = buf[0];
+ printf("%u (0x%x)", x, x);
+ buf += 1;
+ fmt++;
+ break;
+ }
+ case 'd':
+ {
+ unsigned int x;
+ TCHECK2(buf[0], 2);
+ x = reverse ? EXTRACT_16BITS(buf) :
+ EXTRACT_LE_16BITS(buf);
+ printf("%d (0x%x)", x, x);
+ buf += 2;
+ fmt++;
+ break;
+ }
+ case 'D':
+ {
+ unsigned int x;
+ TCHECK2(buf[0], 4);
+ x = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ printf("%d (0x%x)", x, x);
+ buf += 4;
+ fmt++;
+ break;
+ }
+ case 'L':
+ {
+ u_int64_t x;
+ TCHECK2(buf[0], 8);
+ x = reverse ? EXTRACT_64BITS(buf) :
+ EXTRACT_LE_64BITS(buf);
+ printf("%" PRIu64 " (0x%" PRIx64 ")", x, x);
+ buf += 8;
+ fmt++;
+ break;
+ }
+ case 'M':
+ {
+ /* Weird mixed-endian length values in 64-bit locks */
+ u_int32_t x1, x2;
+ u_int64_t x;
+ TCHECK2(buf[0], 8);
+ x1 = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ x2 = reverse ? EXTRACT_32BITS(buf + 4) :
+ EXTRACT_LE_32BITS(buf + 4);
+ x = (((u_int64_t)x1) << 32) | x2;
+ printf("%" PRIu64 " (0x%" PRIx64 ")", x, x);
+ buf += 8;
+ fmt++;
+ break;
+ }
+ case 'B':
+ {
+ unsigned int x;
+ TCHECK(buf[0]);
+ x = buf[0];
+ printf("0x%X", x);
+ buf += 1;
+ fmt++;
+ break;
+ }
+ case 'w':
+ {
+ unsigned int x;
+ TCHECK2(buf[0], 2);
+ x = reverse ? EXTRACT_16BITS(buf) :
+ EXTRACT_LE_16BITS(buf);
+ printf("0x%X", x);
+ buf += 2;
+ fmt++;
+ break;
+ }
+ case 'W':
+ {
+ unsigned int x;
+ TCHECK2(buf[0], 4);
+ x = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ printf("0x%X", x);
+ buf += 4;
+ fmt++;
+ break;
+ }
+ case 'l':
+ {
+ fmt++;
+ switch (*fmt) {
+
+ case 'b':
+ TCHECK(buf[0]);
+ stringlen = buf[0];
+ printf("%u", stringlen);
+ buf += 1;
+ break;
+
+ case 'd':
+ TCHECK2(buf[0], 2);
+ stringlen = reverse ? EXTRACT_16BITS(buf) :
+ EXTRACT_LE_16BITS(buf);
+ printf("%u", stringlen);
+ buf += 2;
+ break;
+
+ case 'D':
+ TCHECK2(buf[0], 4);
+ stringlen = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ printf("%u", stringlen);
+ buf += 4;
+ break;
+ }
+ fmt++;
+ break;
+ }
+ case 'S':
+ case 'R': /* like 'S', but always ASCII */
+ {
+ /*XXX unistr() */
+ const char *s;
+ len = 0;
+ s = unistr(buf, &len, (*fmt == 'R') ? 0 : unicodestr);
+ if (s == NULL)
+ goto trunc;
+ printf("%s", s);
+ buf += len;
+ fmt++;
+ break;
+ }
+ case 'Z':
+ case 'Y': /* like 'Z', but always ASCII */
+ {
+ const char *s;
+ TCHECK(*buf);
+ if (*buf != 4 && *buf != 2) {
+ printf("Error! ASCIIZ buffer of type %u", *buf);
+ return maxbuf; /* give up */
+ }
+ len = 0;
+ s = unistr(buf + 1, &len, (*fmt == 'Y') ? 0 : unicodestr);
+ if (s == NULL)
+ goto trunc;
+ printf("%s", s);
+ buf += len + 1;
+ fmt++;
+ break;
+ }
+ case 's':
+ {
+ int l = atoi(fmt + 1);
+ TCHECK2(*buf, l);
+ printf("%-*.*s", l, l, buf);
+ buf += l;
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'c':
+ {
+ TCHECK2(*buf, stringlen);
+ printf("%-*.*s", stringlen, stringlen, buf);
+ buf += stringlen;
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'C':
+ {
+ const char *s;
+ s = unistr(buf, &stringlen, unicodestr);
+ if (s == NULL)
+ goto trunc;
+ printf("%s", s);
+ buf += stringlen;
+ fmt++;
+ break;
+ }
+ case 'h':
+ {
+ int l = atoi(fmt + 1);
+ TCHECK2(*buf, l);
+ while (l--)
+ printf("%02x", *buf++);
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'n':
+ {
+ int t = atoi(fmt+1);
+ char nbuf[255];
+ int name_type;
+ int len;
+
+ switch (t) {
+ case 1:
+ name_type = name_extract(startbuf, PTR_DIFF(buf, startbuf),
+ maxbuf, nbuf);
+ if (name_type < 0)
+ goto trunc;
+ len = name_len(buf, maxbuf);
+ if (len < 0)
+ goto trunc;
+ buf += len;
+ printf("%-15.15s NameType=0x%02X (%s)", nbuf, name_type,
+ name_type_str(name_type));
+ break;
+ case 2:
+ TCHECK(buf[15]);
+ name_type = buf[15];
+ printf("%-15.15s NameType=0x%02X (%s)", buf, name_type,
+ name_type_str(name_type));
+ buf += 16;
+ break;
+ }
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'T':
+ {
+ time_t t;
+ struct tm *lt;
+ const char *tstring;
+ u_int32_t x;
+
+ switch (atoi(fmt + 1)) {
+ case 1:
+ TCHECK2(buf[0], 4);
+ x = EXTRACT_LE_32BITS(buf);
+ if (x == 0 || x == 0xFFFFFFFF)
+ t = 0;
+ else
+ t = make_unix_date(buf);
+ buf += 4;
+ break;
+ case 2:
+ TCHECK2(buf[0], 4);
+ x = EXTRACT_LE_32BITS(buf);
+ if (x == 0 || x == 0xFFFFFFFF)
+ t = 0;
+ else
+ t = make_unix_date2(buf);
+ buf += 4;
+ break;
+ case 3:
+ TCHECK2(buf[0], 8);
+ t = interpret_long_date(buf);
+ buf += 8;
+ break;
+ }
+ if (t != 0) {
+ lt = localtime(&t);
+ if (lt != NULL)
+ tstring = asctime(lt);
+ else
+ tstring = "(Can't convert time)\n";
+ } else
+ tstring = "NULL\n";
+ printf("%s", tstring);
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ default:
+ putchar(*fmt);
+ fmt++;
+ break;