smbcomread.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "headers.h"
  10. SmbProcessResult
  11. smbcomreadandx(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *b)
  12. {
  13. uint8_t andxcommand;
  14. uint16_t andxoffset;
  15. uint32_t andxoffsetfixup;
  16. uint32_t datafixup;
  17. uint32_t bytecountfixup;
  18. uint16_t fid;
  19. SmbTree *t;
  20. SmbFile *f;
  21. int64_t offset;
  22. uint16_t maxcount;
  23. int32_t toread;
  24. int32_t nb;
  25. if (h->wordcount != 10 && h->wordcount != 12)
  26. return SmbProcessResultFormat;
  27. andxcommand = *pdata++;
  28. pdata++;
  29. andxoffset = smbnhgets(pdata); pdata += 2;
  30. fid = smbnhgets(pdata); pdata += 2;
  31. offset = smbnhgetl(pdata); pdata += 4;
  32. maxcount = smbnhgets(pdata); pdata += 2;
  33. pdata += 2; // mincount
  34. pdata += 4; // timeout ?
  35. pdata += 2; // remaining
  36. if (h->wordcount == 12)
  37. offset |= (int64_t)smbnhgetl(pdata) << 32;
  38. t = smbidmapfind(s->tidmap, h->tid);
  39. if (t == nil) {
  40. smbseterror(s, ERRSRV, ERRinvtid);
  41. return SmbProcessResultError;
  42. }
  43. f = smbidmapfind(s->fidmap, fid);
  44. if (f == nil) {
  45. smbseterror(s, ERRDOS, ERRbadfid);
  46. return SmbProcessResultError;
  47. }
  48. if (!f->ioallowed) {
  49. smbseterror(s, ERRDOS, ERRbadaccess);
  50. return SmbProcessResultError;
  51. }
  52. h->wordcount = 12;
  53. if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup))
  54. return SmbProcessResultMisc;
  55. if (!smbbufferputs(s->response, -1) // remaining
  56. || !smbbufferputs(s->response, 0) // datacompactionmode
  57. || !smbbufferputs(s->response, 0)) // reserved
  58. return SmbProcessResultMisc;
  59. datafixup = smbbufferwriteoffset(s->response);
  60. if (!smbbufferputbytes(s->response, nil, 6)
  61. || !smbbufferfill(s->response, 0, 8)) // reserved
  62. return SmbProcessResultMisc;
  63. bytecountfixup = smbbufferwriteoffset(s->response);
  64. if (!smbbufferputs(s->response, 0)
  65. || !smbbufferputb(s->response, 0))
  66. return SmbProcessResultMisc;
  67. smbbufferwritelimit(s->response, smbbufferwriteoffset(s->response) + 65535);
  68. smbbufferoffsetputs(s->response, datafixup + 2, smbbufferwriteoffset(s->response));
  69. seek(f->fd, offset, 0);
  70. toread = smbbufferwritespace(s->response);
  71. if (toread > maxcount)
  72. toread = maxcount;
  73. nb = readn(f->fd, smbbufferwritepointer(s->response), toread);
  74. if (nb < 0) {
  75. smbseterror(s, ERRDOS, ERRbadaccess);
  76. return SmbProcessResultError;
  77. }
  78. if (!smbbufferputbytes(s->response, nil, nb)
  79. || !smbbufferfixuprelatives(s->response, bytecountfixup)
  80. || !smbbufferoffsetputs(s->response, datafixup, nb)
  81. || !smbbufferoffsetputs(s->response, datafixup + 4, nb >> 16))
  82. return SmbProcessResultMisc;
  83. if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
  84. return smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b);
  85. return SmbProcessResultReply;
  86. }