smbcomread.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "headers.h"
  2. SmbProcessResult
  3. smbcomreadandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
  4. {
  5. uchar andxcommand;
  6. ushort andxoffset;
  7. ulong andxoffsetfixup;
  8. ulong datafixup;
  9. ulong bytecountfixup;
  10. ushort fid;
  11. SmbTree *t;
  12. SmbFile *f;
  13. vlong offset;
  14. ushort maxcount;
  15. long toread;
  16. long nb;
  17. if (h->wordcount != 10 && h->wordcount != 12)
  18. return SmbProcessResultFormat;
  19. andxcommand = *pdata++;
  20. pdata++;
  21. andxoffset = smbnhgets(pdata); pdata += 2;
  22. fid = smbnhgets(pdata); pdata += 2;
  23. offset = smbnhgetl(pdata); pdata += 4;
  24. maxcount = smbnhgets(pdata); pdata += 2;
  25. pdata += 2; // mincount
  26. pdata += 4; // timeout ?
  27. pdata += 2; // remaining
  28. if (h->wordcount == 12)
  29. offset |= (vlong)smbnhgetl(pdata) << 32;
  30. t = smbidmapfind(s->tidmap, h->tid);
  31. if (t == nil) {
  32. smbseterror(s, ERRSRV, ERRinvtid);
  33. return SmbProcessResultError;
  34. }
  35. f = smbidmapfind(s->fidmap, fid);
  36. if (f == nil) {
  37. smbseterror(s, ERRDOS, ERRbadfid);
  38. return SmbProcessResultError;
  39. }
  40. if (!f->ioallowed) {
  41. smbseterror(s, ERRDOS, ERRbadaccess);
  42. return SmbProcessResultError;
  43. }
  44. h->wordcount = 12;
  45. if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup))
  46. return SmbProcessResultMisc;
  47. if (!smbbufferputs(s->response, -1) // remaining
  48. || !smbbufferputs(s->response, 0) // datacompactionmode
  49. || !smbbufferputs(s->response, 0)) // reserved
  50. return SmbProcessResultMisc;
  51. datafixup = smbbufferwriteoffset(s->response);
  52. if (!smbbufferputbytes(s->response, nil, 6)
  53. || !smbbufferfill(s->response, 0, 8)) // reserved
  54. return SmbProcessResultMisc;
  55. bytecountfixup = smbbufferwriteoffset(s->response);
  56. if (!smbbufferputs(s->response, 0)
  57. || !smbbufferputb(s->response, 0))
  58. return SmbProcessResultMisc;
  59. smbbufferwritelimit(s->response, smbbufferwriteoffset(s->response) + 65535);
  60. smbbufferoffsetputs(s->response, datafixup + 2, smbbufferwriteoffset(s->response));
  61. seek(f->fd, offset, 0);
  62. toread = smbbufferwritespace(s->response);
  63. if (toread > maxcount)
  64. toread = maxcount;
  65. nb = readn(f->fd, smbbufferwritepointer(s->response), toread);
  66. if (nb < 0) {
  67. smbseterror(s, ERRDOS, ERRbadaccess);
  68. return SmbProcessResultError;
  69. }
  70. if (!smbbufferputbytes(s->response, nil, nb)
  71. || !smbbufferfixuprelatives(s->response, bytecountfixup)
  72. || !smbbufferoffsetputs(s->response, datafixup, nb)
  73. || !smbbufferoffsetputs(s->response, datafixup + 4, nb >> 16))
  74. return SmbProcessResultMisc;
  75. if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
  76. return smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b);
  77. return SmbProcessResultReply;
  78. }