SambaServer.Mod 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068
  1. MODULE SambaServer; (** AUTHOR "mancos"; PURPOSE "SMB Server"; *)
  2. IMPORT SYSTEM, Modules, Streams, KernelLog, Commands, Dates, Strings, Files, TCP, TCPServices;
  3. CONST
  4. PrimaryDomain = "BLUEBOTTLE";
  5. Server = "A2SAMBA";
  6. NativeOS = "A2";
  7. LANManager = "A2 LAN Manager";
  8. FileSystem = "AosFS";
  9. Trace = FALSE;
  10. SMBPort* = 445;
  11. TYPE
  12. Share = POINTER TO RECORD
  13. path, unc : Files.FileName;
  14. next : Share;
  15. END;
  16. Connection = POINTER TO RECORD
  17. error: BOOLEAN;
  18. errorcode: LONGINT;
  19. out: Streams.Writer;
  20. in: Streams.Reader;
  21. msgSize: LONGINT;
  22. cmd: LONGINT;
  23. flags: LONGINT;
  24. flags2: INTEGER;
  25. tid: INTEGER;
  26. pid: INTEGER;
  27. uid: INTEGER;
  28. mid: INTEGER;
  29. fid: INTEGER;
  30. sid: INTEGER;
  31. pattern: ARRAY 256 OF CHAR;
  32. netbios: INTEGER;
  33. filename: ARRAY 256 OF CHAR;
  34. sharename: ARRAY 256 OF CHAR;
  35. client: TCP.Connection;
  36. next: Connection;
  37. END;
  38. Agent = OBJECT(TCPServices.Agent)
  39. VAR
  40. out: Streams.Writer;
  41. in: Streams.Reader;
  42. c: Connection;
  43. BEGIN {ACTIVE}
  44. (* Initialisation *)
  45. Streams.OpenReader(in, client.Receive);
  46. Streams.OpenWriter(out, client.Send);
  47. WHILE (client.state IN TCP.OpenStates) DO
  48. NEW(c);
  49. SetLastConnection(c);
  50. c.out := out;
  51. c.in := in;
  52. c.client := client;
  53. c.error := CheckSMBHeader(c);
  54. IF ~c.error THEN
  55. Dispatch(c);
  56. END;
  57. END;
  58. END Agent;
  59. VAR
  60. service: TCPServices.Service;
  61. lastUID, lastTID, lastFID, lastSID: INTEGER;
  62. firstConn: Connection;
  63. shares : Share;
  64. PROCEDURE GetUID(): INTEGER;
  65. BEGIN {EXCLUSIVE}
  66. INC(lastUID);
  67. RETURN lastUID;
  68. END GetUID;
  69. PROCEDURE GetTID(): INTEGER;
  70. BEGIN {EXCLUSIVE}
  71. INC(lastTID);
  72. RETURN lastTID;
  73. END GetTID;
  74. PROCEDURE GetFID(): INTEGER;
  75. BEGIN {EXCLUSIVE}
  76. INC(lastFID);
  77. RETURN lastFID;
  78. END GetFID;
  79. PROCEDURE GetSID(): INTEGER;
  80. BEGIN {EXCLUSIVE}
  81. INC(lastSID);
  82. RETURN lastSID;
  83. END GetSID;
  84. PROCEDURE SetLastConnection(c: Connection);
  85. VAR
  86. oldConn: Connection;
  87. BEGIN {EXCLUSIVE}
  88. oldConn := GetLastConnection();
  89. oldConn.next := c;
  90. END SetLastConnection;
  91. PROCEDURE GetSharename(VAR c: Connection);
  92. VAR
  93. k: Connection;
  94. BEGIN
  95. k := firstConn;
  96. WHILE (k.next # NIL) DO
  97. IF (k.tid = c.tid) & (Strings.Length(k.sharename) > 0) THEN
  98. COPY(k.sharename, c.sharename);
  99. RETURN;
  100. END;
  101. k := k.next;
  102. END;
  103. END GetSharename;
  104. PROCEDURE GetLastConnection(): Connection;
  105. VAR
  106. c: Connection;
  107. BEGIN
  108. c := firstConn;
  109. WHILE (c.next # NIL) DO
  110. c := c.next;
  111. END;
  112. RETURN c;
  113. END GetLastConnection;
  114. PROCEDURE GetPattern(sid: INTEGER; VAR pattern: ARRAY OF CHAR);
  115. VAR
  116. c: Connection;
  117. BEGIN
  118. c := firstConn;
  119. WHILE (c.sid # sid) DO
  120. c := c.next;
  121. END;
  122. COPY(c.pattern, pattern);
  123. END GetPattern;
  124. PROCEDURE RemoveConnections(tid: INTEGER);
  125. VAR
  126. c, prev: Connection;
  127. BEGIN {EXCLUSIVE}
  128. c := firstConn;
  129. WHILE (c.next # NIL) DO
  130. IF c.tid = tid THEN
  131. prev.next := c.next
  132. END;
  133. prev := c;
  134. c := prev.next;
  135. END;
  136. END RemoveConnections;
  137. PROCEDURE GetFileName(fid: INTEGER; VAR filename: ARRAY OF CHAR);
  138. VAR
  139. c: Connection;
  140. BEGIN
  141. c := firstConn;
  142. WHILE ((c.fid # fid) & (c.next # NIL)) DO
  143. c := c.next;
  144. END;
  145. IF (c.fid = fid) THEN
  146. COPY(c.filename, filename);
  147. ELSE
  148. IF Trace THEN KernelLog.String(" -- FID not found!"); KernelLog.Ln(); END;
  149. c.error := TRUE;
  150. c.errorcode := 393217;
  151. (* SEND *)
  152. c.netbios := 32 + 3;
  153. WriteSMBHeader(c);
  154. c.out.Net8(0); (* word count *)
  155. c.out.RawInt(0); (* bytecount *)
  156. c.out.Update();
  157. END;
  158. END GetFileName;
  159. PROCEDURE Dispatch(c: Connection);
  160. BEGIN
  161. IF c.cmd = ORD(72X) THEN
  162. HandleNegotiate(c);
  163. ELSIF c.cmd = ORD(73X) THEN
  164. HandleSessionSetup(c);
  165. ELSIF c.cmd = ORD(75X) THEN
  166. HandleTreeConnect(c);
  167. ELSIF c.cmd = ORD(2DX) THEN
  168. HandleOpen(c);
  169. ELSIF c.cmd = ORD(04X) THEN
  170. HandleClose(c);
  171. ELSIF c.cmd = ORD(32X) THEN
  172. HandleTrans2(c);
  173. ELSIF c.cmd = ORD(71X) THEN
  174. HandleTreeDisconnect(c);
  175. ELSIF c.cmd = ORD(02X) THEN
  176. HandleOpenOld(c);
  177. ELSIF c.cmd = ORD(08X) THEN
  178. HandleQueryInformation(c);
  179. ELSIF c.cmd = ORD(23X) THEN
  180. HandleQueryInfo2(c);
  181. ELSIF c.cmd = ORD(2EX) THEN
  182. HandleRead(c);
  183. ELSIF c.cmd = ORD(0BX) THEN
  184. HandleWrite(c);
  185. ELSIF c.cmd = ORD(2FX) THEN
  186. HandleWriteAndX(c);
  187. ELSIF c.cmd = ORD(0A0X) THEN
  188. HandleTrans(c);
  189. ELSIF c.cmd = ORD(25X) THEN
  190. HandleLMTrans(c);
  191. ELSIF c.cmd = ORD(05X) THEN
  192. HandleFlush(c);
  193. ELSIF c.cmd = ORD(07X) THEN
  194. HandleRename(c);
  195. ELSIF c.cmd = ORD(06X) THEN
  196. HandleDelete(c);
  197. ELSIF c.cmd = ORD(09X) THEN
  198. HandleSetInfo2(c);
  199. ELSIF c.cmd = ORD(22X) THEN
  200. HandleSetInfo2(c);
  201. ELSIF c.cmd = ORD(34X) THEN
  202. HandleFindClose2(c);
  203. ELSIF c.cmd = ORD(2BX) THEN
  204. HandleEcho(c);
  205. ELSIF c.cmd = ORD(00X) THEN
  206. HandleCreateDir(c);
  207. ELSIF c.cmd = ORD(01X) THEN
  208. HandleDeleteDir(c);
  209. ELSIF c.cmd = ORD(0FX) THEN
  210. HandleCreateNew(c);
  211. ELSE
  212. IF Trace THEN KernelLog.String(" -- Unknown packet: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  213. c.in.SkipBytes(1);
  214. c.in.Reset();
  215. END;
  216. END Dispatch;
  217. PROCEDURE HandleCreateNew(c: Connection);
  218. VAR
  219. filename: ARRAY 256 OF CHAR;
  220. f: Files.File;
  221. res: WORD;
  222. BEGIN
  223. IF Trace THEN KernelLog.String("Handle Create New: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  224. c.in.SkipBytes(1); (* skip wordCount *)
  225. c.in.SkipBytes(2); (* skip file attr *)
  226. c.in.SkipBytes(4); (* skip created *)
  227. c.in.SkipBytes(2); (* skip byte count *)
  228. c.in.SkipBytes(1); (* skip format *)
  229. c.in.RawString(filename);
  230. ReplaceSlash(filename);
  231. GetSharename(c);
  232. Strings.Concat(c.sharename, filename, filename);
  233. IF Trace THEN KernelLog.String(" -- Filename: "); KernelLog.String(filename); KernelLog.Ln(); END;
  234. f := Files.Old(filename);
  235. IF (f # NIL) THEN
  236. Files.Delete(filename, res);
  237. END;
  238. f := Files.New(filename);
  239. Files.Register(f);
  240. IF res # 0 THEN (* NOT OK *)
  241. c.error := TRUE;
  242. c.errorcode := 327681;
  243. c.netbios := 32 + 3;
  244. WriteSMBHeader(c);
  245. c.out.Net8(0); (* word count *)
  246. c.out.RawInt(0); (* bytecount *)
  247. c.out.Update();
  248. RETURN;
  249. END;
  250. (* SEND *)
  251. c.netbios := 32 + 5;
  252. WriteSMBHeader(c);
  253. c.out.Net8(1); (* word count *)
  254. c.fid := GetFID();
  255. c.out.RawInt(c.fid);
  256. c.out.RawInt(0); (* bytecount *)
  257. c.out.Update();
  258. END HandleCreateNew;
  259. PROCEDURE HandleCreateDir(c: Connection);
  260. VAR
  261. dirname: ARRAY 256 OF CHAR;
  262. res: WORD;
  263. BEGIN
  264. IF Trace THEN KernelLog.String("Handle Create Directory: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  265. c.in.SkipBytes(1); (* skip wordCount *)
  266. c.in.SkipBytes(2); (* skip byte count *)
  267. c.in.SkipBytes(1); (* skip buffer format *)
  268. c.in.RawString(dirname);
  269. IF Trace THEN KernelLog.String(" -- Directory: "); KernelLog.String(dirname); KernelLog.Ln(); END;
  270. Files.CreateDirectory(dirname, res);
  271. IF res # 0 THEN
  272. c.error := TRUE;
  273. END;
  274. (* SEND *)
  275. c.netbios := 32 + 3;
  276. WriteSMBHeader(c);
  277. c.out.Net8(0); (* word count *)
  278. c.out.RawInt(0); (* bytecount *)
  279. c.out.Update();
  280. END HandleCreateDir;
  281. PROCEDURE HandleDeleteDir(c: Connection);
  282. VAR
  283. dirname: ARRAY 256 OF CHAR;
  284. res: WORD;
  285. BEGIN
  286. IF Trace THEN KernelLog.String("Handle Delete Directory: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  287. c.in.SkipBytes(1); (* skip wordCount *)
  288. c.in.SkipBytes(2); (* skip byte count *)
  289. c.in.SkipBytes(1); (* skip buffer format *)
  290. c.in.RawString(dirname);
  291. IF Trace THEN KernelLog.String(" -- Directory: "); KernelLog.String(dirname); KernelLog.Ln(); END;
  292. Files.RemoveDirectory(dirname, TRUE, res);
  293. IF res # 0 THEN (* NOT OK *)
  294. c.error := TRUE;
  295. c.errorcode := 327681;
  296. END;
  297. (* SEND *)
  298. c.netbios := 32 + 3;
  299. WriteSMBHeader(c);
  300. c.out.Net8(0); (* word count *)
  301. c.out.RawInt(0); (* bytecount *)
  302. c.out.Update();
  303. END HandleDeleteDir;
  304. PROCEDURE HandleEcho(c: Connection);
  305. VAR
  306. i, len: LONGINT;
  307. byteCount, echoCount: INTEGER;
  308. buffer: ARRAY 32 OF CHAR;
  309. BEGIN
  310. IF Trace THEN KernelLog.String("Handle Echo: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  311. c.in.SkipBytes(1); (* skip wordCount *)
  312. c.in.RawInt(echoCount);
  313. c.in.RawInt(byteCount);
  314. c.in.Bytes(buffer, 0, byteCount, len);
  315. FOR i := 1 TO echoCount DO
  316. (* SEND *)
  317. c.netbios := 32 + 5 + SHORT(len);
  318. WriteSMBHeader(c);
  319. c.out.Net8(1); (* word count *)
  320. c.out.RawInt(SHORT(i));
  321. c.out.RawInt(SHORT(len)); (* bytecount *)
  322. c.out.Bytes(buffer, 0, len);
  323. c.out.Update();
  324. END;
  325. END HandleEcho;
  326. PROCEDURE HandleLMTrans(c: Connection);
  327. BEGIN
  328. IF Trace THEN KernelLog.String("Handle LANMAN Trans: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  329. c.error := TRUE;
  330. c.errorcode := 140312577;
  331. (* SEND *)
  332. c.netbios := 32 + 3;
  333. WriteSMBHeader(c);
  334. c.out.Net8(0); (* word count *)
  335. c.out.RawInt(0); (* bytecount *)
  336. c.out.Update();
  337. END HandleLMTrans;
  338. PROCEDURE HandleTrans(c: Connection);
  339. BEGIN
  340. IF Trace THEN KernelLog.String("Handle Trans: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  341. c.error := TRUE;
  342. c.errorcode := 65537;
  343. (* SEND *)
  344. c.netbios := 32 + 3;
  345. WriteSMBHeader(c);
  346. c.out.Net8(0); (* word count *)
  347. c.out.RawInt(0); (* bytecount *)
  348. c.out.Update();
  349. END HandleTrans;
  350. PROCEDURE HandleRead(c: Connection);
  351. VAR
  352. fidToRead, maxCount: INTEGER;
  353. offset, len: LONGINT;
  354. f: Files.File;
  355. r: Files.Reader;
  356. buffer: ARRAY 65536 OF CHAR;
  357. filename: ARRAY 256 OF CHAR;
  358. BEGIN
  359. IF Trace THEN KernelLog.String("Handle Read File: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  360. (* RECEIVE *)
  361. c.in.SkipBytes(5);
  362. c.in.RawInt(fidToRead);
  363. GetFileName(fidToRead, filename);
  364. ReplaceSlash(filename);
  365. IF Trace THEN KernelLog.String(" -- File to read: "); KernelLog.String(filename); KernelLog.Ln(); END;
  366. c.in.RawLInt(offset);
  367. c.in.RawInt(maxCount);
  368. f := Files.Old(filename);
  369. IF (f # NIL) THEN
  370. Files.OpenReader(r, f, offset);
  371. r.Bytes(buffer, 0, maxCount, len);
  372. c.netbios := 32 + 27 + SHORT(len);
  373. WriteSMBHeader(c);
  374. c.out.Net8(12); (* word count *)
  375. c.out.Net8(255); (* andx *)
  376. c.out.Net8(0); (* reserved *)
  377. c.out.Net16(0); (* andx offset *)
  378. c.out.RawInt(-1); (* remaining: reserved, must be -1 *)
  379. c.out.RawInt(0); (* dataCompactionMode *)
  380. c.out.RawInt(0); (* reserved *)
  381. c.out.RawInt(SHORT(len)); (* low order length bytes *)
  382. c.out.RawInt(59);
  383. c.out.RawLInt(0); (* no write-large-capability -> datalengthhigh is 0 *)
  384. c.out.RawInt(0);
  385. c.out.RawLInt(0); (* 6 bytes reserved *)
  386. c.out.RawInt(SHORT(len)); (* ByteCount *)
  387. (* write data *)
  388. c.out.Bytes(buffer, 0, len);
  389. c.out.Update();
  390. ELSE (* FID invalid *)
  391. IF Trace THEN KernelLog.String(" -- FID invalid!"); KernelLog.Ln(); END;
  392. c.error := TRUE;
  393. c.errorcode := 393217;
  394. (* SEND *)
  395. c.netbios := 32 + 3;
  396. WriteSMBHeader(c);
  397. c.out.Net8(0); (* word count *)
  398. c.out.RawInt(0); (* bytecount *)
  399. c.out.Update();
  400. END;
  401. END HandleRead;
  402. PROCEDURE HandleWrite(c: Connection);
  403. VAR
  404. fidToWrite, count : INTEGER;
  405. offset, len: LONGINT; res: WORD;
  406. buffer: ARRAY 65536 OF CHAR;
  407. filename: ARRAY 256 OF CHAR;
  408. f: Files.File;
  409. w: Files.Writer;
  410. BEGIN
  411. IF Trace THEN KernelLog.String("Handle Write File: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  412. (* RECEIVE *)
  413. c.in.SkipBytes(1);
  414. c.in.RawInt(fidToWrite);
  415. GetFileName(fidToWrite, filename);
  416. ReplaceSlash(filename);
  417. IF Trace THEN KernelLog.String(" -- File to write: "); KernelLog.String(filename); KernelLog.Ln(); END;
  418. c.in.RawInt(count);
  419. c.in.RawLInt(offset);
  420. c.in.SkipBytes(7);
  421. IF count = 0 THEN
  422. IF Trace THEN KernelLog.String(" -- Count was zero. "); KernelLog.Ln(); END;
  423. IF offset # 0 THEN
  424. Files.Delete(filename, res);
  425. f := Files.New(filename);
  426. Files.Register(f);
  427. END;
  428. c.netbios := 32 + 5;
  429. WriteSMBHeader(c);
  430. c.out.Net8(1); (* word count *)
  431. c.out.RawInt(0); (* count *)
  432. c.out.Net16(0); (* byte count *)
  433. c.out.Update();
  434. RETURN;
  435. END;
  436. f := Files.Old(filename);
  437. IF (f # NIL) THEN
  438. c.in.Bytes(buffer, 0, count, len);
  439. Files.OpenWriter(w, f, offset);
  440. w.Bytes(buffer, 0, len);
  441. w.Update();
  442. (* SEND *)
  443. c.netbios := 32 + 5;
  444. WriteSMBHeader(c);
  445. c.out.Net8(1); (* word count *)
  446. c.out.RawInt(count); (* count *)
  447. c.out.Net16(0); (* byte count *)
  448. c.out.Update();
  449. ELSE (* FID invalid *)
  450. IF Trace THEN KernelLog.String(" -- FID invalid!"); KernelLog.Ln(); END;
  451. c.error := TRUE;
  452. c.errorcode := 393217;
  453. (* SEND *)
  454. c.netbios := 32 + 3;
  455. WriteSMBHeader(c);
  456. c.out.Net8(0); (* word count *)
  457. c.out.RawInt(0); (* bytecount *)
  458. c.out.Update();
  459. END;
  460. END HandleWrite;
  461. PROCEDURE HandleWriteAndX(c: Connection);
  462. VAR
  463. fidToWrite, byteCount, dataOffset: INTEGER;
  464. offset, len: LONGINT;
  465. f: Files.File;
  466. w: Files.Writer;
  467. buffer: ARRAY 65536 OF CHAR;
  468. filename: ARRAY 256 OF CHAR;
  469. BEGIN
  470. IF Trace THEN KernelLog.String("Handle Write File AndX: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  471. (* RECEIVE *)
  472. c.in.SkipBytes(5);
  473. c.in.RawInt(fidToWrite);
  474. GetFileName(fidToWrite, filename);
  475. ReplaceSlash(filename);
  476. IF Trace THEN KernelLog.String(" -- File to write: "); KernelLog.String(filename); KernelLog.Ln(); END;
  477. c.in.RawLInt(offset);
  478. c.in.SkipBytes(12);
  479. c.in.RawInt(dataOffset);
  480. c.in.RawInt(byteCount);
  481. IF (dataOffset = 0) OR (byteCount = 0) THEN
  482. f := NIL;
  483. len := 0;
  484. ELSE
  485. c.in.SkipBytes(dataOffset - 59);
  486. f := Files.Old(filename);
  487. END;
  488. IF (f # NIL) THEN
  489. Files.OpenWriter(w, f, offset);
  490. c.in.Bytes(buffer, 0, byteCount, len);
  491. w.Bytes(buffer, 0, len);
  492. w.Update();
  493. (* SEND *)
  494. c.netbios := 32 + 15;
  495. WriteSMBHeader(c);
  496. c.out.Net8(6); (* word count *)
  497. c.out.Net8(255); (* andx *)
  498. c.out.Net8(0); (* reserved *)
  499. c.out.Net16(0); (* andx offset *)
  500. c.out.RawInt(SHORT(len)); (* len written *)
  501. c.out.RawInt(-1); (* remaining *)
  502. c.out.RawInt(0); (* count high *)
  503. c.out.RawInt(0); (* reserved *)
  504. c.out.RawInt(0); (* byte count *)
  505. c.out.Update();
  506. ELSE (* FID invalid *)
  507. IF Trace THEN KernelLog.String(" -- FID invalid!"); KernelLog.Ln(); END;
  508. c.error := TRUE;
  509. c.errorcode := 393217;
  510. (* SEND *)
  511. c.netbios := 32 + 3;
  512. WriteSMBHeader(c);
  513. c.out.Net8(0); (* word count *)
  514. c.out.RawInt(0); (* bytecount *)
  515. c.out.Update();
  516. END;
  517. END HandleWriteAndX;
  518. PROCEDURE HandleQueryInformation(c: Connection);
  519. VAR
  520. filename: ARRAY 256 OF CHAR;
  521. i: INTEGER;
  522. f: Files.File;
  523. t,d: LONGINT;
  524. dTime: Dates.DateTime;
  525. BEGIN
  526. IF Trace THEN KernelLog.String("Handle Query Information: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  527. (* RECEIVE *)
  528. c.in.SkipBytes(4);
  529. c.in.RawString(filename);
  530. ReplaceSlash(filename);
  531. GetSharename(c);
  532. Strings.Concat(c.sharename, filename, filename);
  533. IF Trace THEN KernelLog.String(" -- Filename: "); KernelLog.String(filename); KernelLog.Ln(); END;
  534. f := Files.Old(filename);
  535. IF (f # NIL) OR (filename = c.sharename) THEN
  536. (* SEND *)
  537. c.netbios := 32 + 23;
  538. WriteSMBHeader(c);
  539. c.out.Net8(10); (* word count *)
  540. IF (filename = c.sharename) OR (Files.Directory IN f.flags) THEN (* is Directory *)
  541. c.out.RawInt(10H);
  542. ELSE
  543. c.out.RawInt(0H);
  544. END;
  545. IF (f # NIL) THEN
  546. f.GetDate(t,d);
  547. dTime := Dates.OberonToDateTime(d,t);
  548. GetUnixTimeStamp(dTime, t);
  549. c.out.RawLInt(t); (* last write *)
  550. c.out.RawLInt(f.Length()); (* file size *)
  551. ELSE
  552. c.out.RawLInt(0); (* last write *)
  553. c.out.RawLInt(0); (* file size *)
  554. END;
  555. FOR i := 1 TO 5 DO
  556. c.out.RawInt(0);
  557. END;
  558. c.out.RawInt(0);
  559. c.out.Update();
  560. ELSE
  561. IF Trace THEN KernelLog.String(" -- File not found!"); KernelLog.Ln(); END;
  562. c.error := TRUE;
  563. c.errorcode := 131073;
  564. (* SEND *)
  565. c.netbios := 32 + 3;
  566. WriteSMBHeader(c);
  567. c.out.Net8(0); (* word count *)
  568. c.out.RawInt(0); (* bytecount *)
  569. c.out.Update();
  570. END;
  571. END HandleQueryInformation;
  572. PROCEDURE HandleOpenOld(c: Connection);
  573. VAR
  574. filename: ARRAY 256 OF CHAR;
  575. f: Files.File;
  576. d,t : LONGINT;
  577. dTime: Dates.DateTime;
  578. BEGIN
  579. IF Trace THEN KernelLog.String("Handle Open (old) File: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  580. (* RECEIVE *)
  581. c.in.SkipBytes(8);
  582. c.in.RawString(filename);
  583. ReplaceSlash(filename);
  584. GetSharename(c);
  585. Strings.Concat(c.sharename, filename, filename);
  586. IF Trace THEN KernelLog.String(" -- Filename: "); KernelLog.String(filename); KernelLog.Ln(); END;
  587. f := Files.Old(filename);
  588. IF (f # NIL) THEN
  589. COPY(filename, c.filename);
  590. (* SEND *)
  591. c.netbios := 32 + 17;
  592. WriteSMBHeader(c);
  593. c.out.Net8(7); (* word count *)
  594. c.fid := GetFID();
  595. c.out.RawInt(c.fid); (* FID *)
  596. IF (Files.Directory IN f.flags) THEN
  597. c.out.RawInt(10H);
  598. ELSE
  599. c.out.RawInt(0H);
  600. END;
  601. f.GetDate(t,d);
  602. dTime := Dates.OberonToDateTime(d,t);
  603. GetUnixTimeStamp(dTime, t);
  604. c.out.RawLInt(t); (* last write *)
  605. c.out.RawLInt(f.Length()); (* datasize *)
  606. c.out.RawInt(0); (* granted access *)
  607. c.out.RawInt(0); (* bytecount *)
  608. c.out.Update();
  609. ELSE
  610. IF Trace THEN KernelLog.String(" -- File not found!"); KernelLog.Ln(); END;
  611. c.error := TRUE;
  612. c.errorcode := 131073;
  613. (* SEND *)
  614. c.netbios := 32 + 3;
  615. WriteSMBHeader(c);
  616. c.out.Net8(0); (* word count *)
  617. c.out.RawInt(0); (* bytecount *)
  618. c.out.Update();
  619. END;
  620. END HandleOpenOld;
  621. PROCEDURE HandleNegotiate(VAR c: Connection);
  622. VAR
  623. variable: LONGINT;
  624. name: ARRAY 64 OF CHAR;
  625. support: BOOLEAN;
  626. size: LONGINT;
  627. dialectIndex: INTEGER;
  628. t: ARRAY 2 OF LONGINT;
  629. BEGIN
  630. support := FALSE;
  631. size := c.msgSize;
  632. dialectIndex := 0;
  633. IF Trace THEN KernelLog.String("Handle Negotiation: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  634. (* RECEIVE *)
  635. c.in.SkipBytes(3);
  636. WHILE (size - 35 > 0) &( ~support) DO
  637. variable := c.in.Net8();
  638. c.in.RawString(name);
  639. IF (variable = 2) & (name = "NT LM 0.12") THEN
  640. support := TRUE;
  641. IF Trace THEN
  642. KernelLog.String(" -- NTLM 0.12 OK");
  643. KernelLog.Ln();
  644. END;
  645. ELSE
  646. INC(dialectIndex);
  647. END;
  648. size := size - 2 - Strings.Length(name);
  649. END;
  650. IF ~support THEN
  651. c.error := TRUE;
  652. END;
  653. (* SEND *)
  654. c.netbios := 32 + 37 + 10 + SHORT(Strings.Length(PrimaryDomain) + Strings.Length(Server));
  655. WriteSMBHeader(c);
  656. c.out.Net8(17); (* word count *)
  657. c.out.RawInt(dialectIndex);
  658. c.out.Net8(1); (* security mode *)
  659. c.out.RawInt(1); (* max mpx count *)
  660. c.out.RawInt(1); (* max vc *)
  661. c.out.RawLInt(32767); (* max buffer size *)
  662. c.out.RawLInt(32767); (* max raw buffer *)
  663. c.out.RawLInt(0); (* sessionkey *)
  664. c.out.RawLInt(0); (* capabilities *)
  665. GetSMBTimeStamp(Dates.Now(), t);
  666. c.out.RawLInt(t[0]); (* system time *)
  667. c.out.RawLInt(t[1]); (* system time*)
  668. c.out.Char(CHR(0)); (* time zone *)
  669. c.out.Char(CHR(0)); (* time zone *)
  670. c.out.Net8(8); (* key length *)
  671. c.out.RawInt(SHORT(Strings.Length(PrimaryDomain) + Strings.Length(Server)));
  672. c.out.String("serverpw");
  673. c.out.RawString(PrimaryDomain);
  674. c.out.RawString(Server);
  675. c.out.Update();
  676. END HandleNegotiate;
  677. PROCEDURE HandleSessionSetup(c: Connection);
  678. VAR
  679. ansiPwLen: INTEGER;
  680. ansiPass: ARRAY 256 OF CHAR;
  681. ucPwLen: INTEGER;
  682. uniPass: ARRAY 256 OF CHAR;
  683. username: ARRAY 256 OF CHAR;
  684. i: LONGINT;
  685. BEGIN
  686. IF Trace THEN KernelLog.String("Handle Session setup: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  687. (* RECEIVE *)
  688. c.in.SkipBytes(15);
  689. c.in.RawInt(ansiPwLen);
  690. c.in.RawInt(ucPwLen);
  691. c.in.SkipBytes(10);
  692. IF ansiPwLen > 0 THEN
  693. c.in.Bytes(ansiPass, 0, ansiPwLen, i);
  694. END;
  695. IF ucPwLen > 0 THEN
  696. c.in.Bytes(uniPass, 0, ucPwLen, i);
  697. END;
  698. c.in.RawString(username);
  699. IF Trace THEN KernelLog.String(" -- Username: "); KernelLog.String(username); KernelLog.Ln(); END;
  700. (* NO USERNAME *)
  701. IF username = "" THEN
  702. c.error := TRUE;
  703. c.errorcode := 262146;
  704. (* SEND *)
  705. c.netbios := 32 + 3;
  706. WriteSMBHeader(c);
  707. c.out.Net8(0); (* word count *)
  708. c.out.RawInt(0); (* bytecount *)
  709. c.out.Update();
  710. RETURN;
  711. END;
  712. (* SEND *)
  713. c.netbios := 32 + 12 + SHORT(Strings.Length(NativeOS) + Strings.Length(PrimaryDomain) + Strings.Length(LANManager));
  714. WriteSMBHeader(c);
  715. c.out.Net8(3); (* word count *)
  716. c.out.Char(CHR(255)); (* and x *)
  717. c.out.Net8(0); (* reserved *)
  718. c.out.Net16(0); (* andx offset *)
  719. c.out.RawInt(1); (* logged in as guest *)
  720. c.out.RawInt(3 + SHORT(Strings.Length(NativeOS) + Strings.Length(PrimaryDomain) + Strings.Length(LANManager))); (* max vc *)
  721. c.out.RawString(NativeOS);
  722. c.out.RawString(LANManager);
  723. c.out.RawString(PrimaryDomain);
  724. c.out.Update();
  725. END HandleSessionSetup;
  726. PROCEDURE HandleTreeConnect(c: Connection);
  727. VAR
  728. i,offset: LONGINT;
  729. pwLen: INTEGER;
  730. byteCount: INTEGER;
  731. password: ARRAY 256 OF CHAR;
  732. path: ARRAY 256 OF CHAR;
  733. service: ARRAY 256 OF CHAR;
  734. string : Strings.String;
  735. share : Share;
  736. BEGIN
  737. IF Trace THEN KernelLog.String("Handle Tree Connect: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  738. (* RECEIVE *)
  739. c.in.SkipBytes(7);
  740. c.in.RawInt(pwLen);
  741. c.in.RawInt(byteCount);
  742. IF pwLen > 0 THEN
  743. c.in.Bytes(password, 0, pwLen, i);
  744. END;
  745. c.in.RawString(path);
  746. c.in.RawString(service);
  747. IF Trace THEN
  748. KernelLog.String(" -- Service: "); KernelLog.String(service); KernelLog.Ln();
  749. KernelLog.String(" -- Path: "); KernelLog.String(path);
  750. END;
  751. IF Strings.EndsWith("IPC$", path) THEN
  752. IF Trace THEN KernelLog.String(" -- IPC"); KernelLog.Ln; END;
  753. service := "IPC";
  754. ELSE
  755. IF Trace THEN KernelLog.String(" - FILESYSTEM"); KernelLog.Ln; END;
  756. service := "A:";
  757. END;
  758. offset := Strings.Find(path, 3, CHR(5CH));
  759. string := Strings.Substring2(offset, path);
  760. IF (string # NIL) THEN COPY(string^, path); END;
  761. share := FindShare(path);
  762. IF (share # NIL) THEN
  763. COPY(share.path, c.sharename);
  764. KernelLog.String(" -- Sharename: "); KernelLog.String(c.sharename); KernelLog.Ln();
  765. ELSIF (service = "IPC") THEN
  766. KernelLog.String(" -- IPC Connected"); KernelLog.Ln();
  767. ELSE
  768. KernelLog.String(" NO SHARE FOUND"); KernelLog.Ln();
  769. c.error := TRUE;
  770. c.errorcode := 4390913;
  771. (* SEND *)
  772. c.netbios := 32 + 3;
  773. WriteSMBHeader(c);
  774. c.out.Net8(0); (* word count *)
  775. c.out.RawInt(0); (* bytecount *)
  776. c.out.Update();
  777. END;
  778. (* SEND *)
  779. c.netbios := 32 + 19 + SHORT(Strings.Length(FileSystem) + Strings.Length(service));
  780. WriteSMBHeader(c);
  781. c.out.Net8(7); (* word count *)
  782. c.out.Char(CHR(255)); (* and x *)
  783. c.out.Net8(0); (* reserved *)
  784. c.out.Net16(0); (* andx offset *)
  785. c.out.RawInt(0); (* optional support *)
  786. c.out.RawLInt(268435456); (* rights *)
  787. c.out.RawLInt(268435456); (* rights *)
  788. c.out.RawInt(2 + SHORT(Strings.Length(FileSystem) + Strings.Length(service)));
  789. c.out.RawString(service);
  790. c.out.RawString(FileSystem);
  791. c.out.Update();
  792. END HandleTreeConnect;
  793. PROCEDURE HandleTreeDisconnect(c: Connection);
  794. BEGIN
  795. IF Trace THEN KernelLog.String("Handle Tree Disonnect: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  796. (* SEND *)
  797. c.netbios := 32 + 3;
  798. WriteSMBHeader(c);
  799. c.out.Net8(0); (* word count *)
  800. c.out.RawInt(0); (* bytecount *)
  801. c.out.Update();
  802. c.client.Discard();
  803. RemoveConnections(c.tid);
  804. END HandleTreeDisconnect;
  805. PROCEDURE HandleOpen(c: Connection);
  806. VAR
  807. byteCount, openFunc: INTEGER;
  808. filename: ARRAY 256 OF CHAR;
  809. f: Files.File;
  810. t,d: LONGINT;
  811. dTime: Dates.DateTime;
  812. BEGIN
  813. IF Trace THEN KernelLog.String("Handle Open: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  814. (* RECEIVE *)
  815. c.in.SkipBytes(17);
  816. c.in.RawInt(openFunc);
  817. c.in.SkipBytes(12);
  818. c.in.RawInt(byteCount);
  819. c.in.RawString(filename);
  820. ReplaceSlash(filename);
  821. GetSharename(c);
  822. Strings.Concat(c.sharename, filename, filename);
  823. IF Trace THEN KernelLog.String(" -- Filename: "); KernelLog.String(filename); KernelLog.Ln(); END;
  824. f := Files.Old(filename);
  825. IF ((f # NIL) OR (filename = c.sharename)) & (0 IN SYSTEM.VAL(SET, openFunc)) THEN
  826. IF Trace THEN KernelLog.String(" -- opening file..."); KernelLog.Ln(); END;
  827. COPY(filename, c.filename);
  828. (* SEND *)
  829. c.netbios := 32 + 33;
  830. WriteSMBHeader(c);
  831. c.out.Net8(15); (* word count *)
  832. c.out.Char(CHR(255)); (* and x *)
  833. c.out.Net8(0); (* reserved *)
  834. c.out.Net16(0); (* andx offset *)
  835. c.fid := GetFID();
  836. c.out.RawInt(c.fid); (* FID *)
  837. IF ((f # NIL) & (Files.Directory IN f.flags)) OR (filename = c.sharename) THEN (* is Directory *)
  838. c.out.RawInt(10H);
  839. ELSE
  840. c.out.RawInt(0H);
  841. END;
  842. IF (f # NIL) THEN
  843. f.GetDate(t,d);
  844. dTime := Dates.OberonToDateTime(d,t);
  845. GetUnixTimeStamp(dTime, t);
  846. c.out.RawLInt(t); (* last write *)
  847. c.out.RawLInt(f.Length()); (* file size *)
  848. ELSE
  849. c.out.RawLInt(0); (* last write *)
  850. c.out.RawLInt(0); (* file size *)
  851. END;
  852. c.out.RawInt(0); (* granted access *)
  853. c.out.RawInt(0); (* filetype *)
  854. c.out.RawInt(0); (* ipc state *)
  855. c.out.RawInt(1); (* action *)
  856. c.out.RawLInt(0); (* serverfid*)
  857. c.out.RawInt(0); (* reserved *)
  858. c.out.RawInt(0); (* bytecount *)
  859. c.out.Update();
  860. ELSIF (f = NIL) & (4 IN SYSTEM.VAL(SET, openFunc)) THEN
  861. IF Trace THEN KernelLog.String(" -- creating file..."); KernelLog.Ln(); END;
  862. f := Files.New(filename);
  863. COPY(filename, c.filename);
  864. Files.Register(f);
  865. (* SEND *)
  866. c.netbios := 32 + 33;
  867. WriteSMBHeader(c);
  868. c.out.Net8(15); (* word count *)
  869. c.out.Char(CHR(255)); (* and x *)
  870. c.out.Net8(0); (* reserved *)
  871. c.out.Net16(0); (* andx offset *)
  872. c.fid := GetFID();
  873. c.out.RawInt(c.fid); (* FID *)
  874. c.out.RawInt(0H);
  875. GetUnixTimeStamp(Dates.Now(), t);
  876. c.out.RawLInt(t); (* last write *)
  877. c.out.RawLInt(f.Length()); (* filesize *)
  878. c.out.RawInt(0); (* granted access *)
  879. c.out.RawInt(0); (* filetype *)
  880. c.out.RawInt(0); (* ipc state *)
  881. c.out.RawInt(2); (* action *)
  882. c.out.RawLInt(0); (* serverfid*)
  883. c.out.RawInt(0); (* reserved *)
  884. c.out.RawInt(0); (* bytecount *)
  885. c.out.Update();
  886. ELSIF (f # NIL) & ~(0 IN SYSTEM.VAL(SET, openFunc)) THEN
  887. IF Trace THEN KernelLog.String(" -- Invalid open mode!."); KernelLog.Ln(); END;
  888. c.error := TRUE;
  889. c.errorcode := 786433;
  890. (* SEND *)
  891. c.netbios := 32 + 3;
  892. WriteSMBHeader(c);
  893. c.out.Net8(0); (* word count *)
  894. c.out.RawInt(0); (* bytecount *)
  895. c.out.Update();
  896. ELSIF Strings.StartsWith("/PIPE/", 0, filename) THEN
  897. IF Trace THEN KernelLog.String(" -- opening pipe..."); KernelLog.Ln(); END;
  898. COPY(filename, c.filename);
  899. (* SEND *)
  900. c.netbios := 32 + 33;
  901. WriteSMBHeader(c);
  902. c.out.Net8(15); (* word count *)
  903. c.out.Char(CHR(255)); (* and x *)
  904. c.out.Net8(0); (* reserved *)
  905. c.out.Net16(0); (* andx offset *)
  906. c.fid := GetFID();
  907. c.out.RawInt(c.fid); (* FID *)
  908. c.out.RawInt(0H);
  909. c.out.RawLInt(0); (* lastwrite *)
  910. c.out.RawLInt(0); (* filesize *)
  911. c.out.RawInt(0); (* granted access *)
  912. c.out.RawInt(0); (* filetype *)
  913. c.out.RawInt(0); (* ipc state *)
  914. c.out.RawInt(1); (* action *)
  915. c.out.RawLInt(0); (* serverfid*)
  916. c.out.RawInt(0); (* reserved *)
  917. c.out.RawInt(0); (* bytecount *)
  918. c.out.Update();
  919. ELSE
  920. IF Trace THEN KernelLog.String(" -- File not found!"); KernelLog.Ln(); END;
  921. c.error := TRUE;
  922. c.errorcode := 131073;
  923. (* SEND *)
  924. c.netbios := 32 + 3;
  925. WriteSMBHeader(c);
  926. c.out.Net8(0); (* word count *)
  927. c.out.RawInt(0); (* bytecount *)
  928. c.out.Update();
  929. END;
  930. END HandleOpen;
  931. PROCEDURE HandleClose(c: Connection);
  932. BEGIN
  933. IF Trace THEN KernelLog.String("Handle File close: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  934. (* SEND *)
  935. c.netbios := 32 + 3;
  936. WriteSMBHeader(c);
  937. c.out.Net8(0); (* word count *)
  938. c.out.RawInt(0); (* bytecount *)
  939. c.out.Update();
  940. END HandleClose;
  941. PROCEDURE HandleFindClose2(c: Connection);
  942. BEGIN
  943. IF Trace THEN KernelLog.String("Handle find close 2: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  944. (* SEND *)
  945. c.netbios := 32 + 3;
  946. WriteSMBHeader(c);
  947. c.out.Net8(0); (* word count *)
  948. c.out.RawInt(0); (* bytecount *)
  949. c.out.Update();
  950. END HandleFindClose2;
  951. PROCEDURE HandleFlush(c : Connection);
  952. BEGIN
  953. IF Trace THEN KernelLog.String("Handle Flush: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  954. (* SEND *)
  955. c.netbios := 32 + 3;
  956. WriteSMBHeader(c);
  957. c.out.Net8(0); (* word count *)
  958. c.out.RawInt(0); (* bytecount *)
  959. c.out.Update();
  960. END HandleFlush;
  961. PROCEDURE HandleRename(c : Connection);
  962. VAR
  963. oldName, newName,
  964. oldPath, newPath: ARRAY 256 OF CHAR;
  965. res: WORD;
  966. BEGIN
  967. IF Trace THEN KernelLog.String("Handle Rename: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  968. (* RECEIVE *)
  969. c.in.SkipBytes(6);
  970. c.in.RawString(oldName);
  971. ReplaceSlash(oldName);
  972. Files.SplitPath(oldName, oldPath, oldName);
  973. c.in.SkipBytes(1);
  974. c.in.RawString(newName);
  975. ReplaceSlash(newName);
  976. Files.SplitPath(newName, newPath, newName);
  977. IF Trace THEN
  978. KernelLog.String(" -- Old: "); KernelLog.String(oldName); KernelLog.Ln();
  979. KernelLog.String(" -- New: "); KernelLog.String(newName); KernelLog.Ln();
  980. END;
  981. IF oldPath = newPath THEN
  982. Files.Rename(oldName, newName, res);
  983. END;
  984. IF res # 0 THEN
  985. c.error := TRUE;
  986. c.errorcode := 327681;
  987. END;
  988. (* SEND *)
  989. c.netbios := 32 + 3;
  990. WriteSMBHeader(c);
  991. c.out.Net8(0); (* word count *)
  992. c.out.RawInt(0); (* bytecount *)
  993. c.out.Update();
  994. END HandleRename;
  995. PROCEDURE HandleDelete(c: Connection);
  996. VAR
  997. name, path: ARRAY 256 OF CHAR;
  998. res: WORD;
  999. BEGIN
  1000. IF Trace THEN KernelLog.String("Handle Delete: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  1001. (* RECEIVE *)
  1002. c.in.SkipBytes(6);
  1003. c.in.RawString(name);
  1004. ReplaceSlash(name);
  1005. Files.SplitPath(name, path, name);
  1006. IF Trace THEN KernelLog.String(" -- Filename: "); KernelLog.String(name); KernelLog.Ln(); END;
  1007. Files.Delete(name, res);
  1008. IF res # 0 THEN
  1009. c.error := TRUE;
  1010. c.errorcode := 327681;
  1011. END;
  1012. (* SEND *)
  1013. c.netbios := 32 + 3;
  1014. WriteSMBHeader(c);
  1015. c.out.Net8(0); (* word count *)
  1016. c.out.RawInt(0); (* bytecount *)
  1017. c.out.Update();
  1018. END HandleDelete;
  1019. PROCEDURE HandleQueryInfo2(c: Connection);
  1020. VAR
  1021. filename: ARRAY 256 OF CHAR;
  1022. fid: INTEGER;
  1023. f: Files.File;
  1024. t,d: LONGINT;
  1025. dTime: Dates.DateTime;
  1026. BEGIN
  1027. IF Trace THEN KernelLog.String("Handle Query Information 2: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  1028. (* RECEIVE *)
  1029. c.in.SkipBytes(1);
  1030. c.in.RawInt(fid);
  1031. GetFileName(fid, filename);
  1032. ReplaceSlash(filename);
  1033. IF Trace THEN KernelLog.String(" -- Filename: "); KernelLog.String(filename); KernelLog.Ln(); END;
  1034. f := Files.Old(filename);
  1035. IF (f # NIL) THEN
  1036. (* SEND *)
  1037. c.netbios := 32 + 25;
  1038. WriteSMBHeader(c);
  1039. c.out.Net8(11); (* word count *)
  1040. c.out.RawLInt(0); (* creation time *)
  1041. c.out.RawLInt(0); (* last access *)
  1042. f.GetDate(t,d);
  1043. dTime := Dates.OberonToDateTime(d,t);
  1044. GetDOSTimeStamp(dTime, t);
  1045. c.out.RawLInt(t); (* last write *)
  1046. c.out.RawLInt(f.Length()); (* file data size *)
  1047. c.out.RawLInt(f.Length()); (* file alloc *)
  1048. c.out.RawInt(0); (* attr *)
  1049. c.out.RawInt(0); (* byte count *)
  1050. c.out.Update();
  1051. ELSE
  1052. IF Trace THEN KernelLog.String(" -- File not found!"); KernelLog.Ln(); END;
  1053. c.error := TRUE;
  1054. c.errorcode := 131073;
  1055. (* SEND *)
  1056. c.netbios := 32 + 3;
  1057. WriteSMBHeader(c);
  1058. c.out.Net8(0); (* word count *)
  1059. c.out.RawInt(0); (* bytecount *)
  1060. c.out.Update();
  1061. END;
  1062. END HandleQueryInfo2;
  1063. PROCEDURE HandleSetInfo2(c: Connection);
  1064. BEGIN
  1065. IF Trace THEN KernelLog.String("Handle Set Information 2: "); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  1066. (* SEND *)
  1067. c.netbios := 32 + 3;
  1068. WriteSMBHeader(c);
  1069. c.out.Net8(0); (* word count *)
  1070. c.out.RawInt(0); (* bytecount *)
  1071. c.out.Update();
  1072. END HandleSetInfo2;
  1073. PROCEDURE HandleTrans2(c: Connection);
  1074. VAR
  1075. offset: INTEGER;
  1076. subcommand: INTEGER;
  1077. BEGIN
  1078. IF Trace THEN KernelLog.String("Handle Trans2 Request..."); KernelLog.Int(c.cmd, 0); KernelLog.Ln(); END;
  1079. (* RECEIVE *)
  1080. c.in.SkipBytes(21);
  1081. c.in.RawInt(offset);
  1082. offset := offset - 63;
  1083. c.in.SkipBytes(6);
  1084. c.in.RawInt(subcommand);
  1085. c.in.SkipBytes(offset);
  1086. IF Trace THEN KernelLog.String(" -- Subcommand: "); KernelLog.Int(subcommand, 0); KernelLog.Ln(); END;
  1087. Trans2Logic(subcommand, c);
  1088. END HandleTrans2;
  1089. PROCEDURE Trans2Logic(subcmd: INTEGER; c: Connection);
  1090. VAR
  1091. enum: Files.Enumerator;
  1092. eName, fullName, pathname, prefix, pattern, resumeFn, modPat: ARRAY 256 OF CHAR;
  1093. eFlags, flags : SET;
  1094. eTime, eDate, eSize : LONGINT;
  1095. success, eos: BOOLEAN;
  1096. i,j,z, searchCount, totalFileNameLen, lastlen, loi, sidnext: INTEGER;
  1097. f: Files.File;
  1098. tarray: ARRAY 2 OF LONGINT;
  1099. t,d: LONGINT;
  1100. dTime: Dates.DateTime;
  1101. BEGIN
  1102. IF (subcmd = 7) THEN
  1103. IF Trace THEN KernelLog.String(" -- QUERY FILE INFO"); KernelLog.Ln(); END;
  1104. c.error := TRUE;
  1105. c.errorcode := 327681;
  1106. (* SEND *)
  1107. c.netbios := 32 + 3;
  1108. WriteSMBHeader(c);
  1109. c.out.Net8(0); (* word count *)
  1110. c.out.RawInt(0); (* bytecount *)
  1111. c.out.Update();
  1112. RETURN;
  1113. ELSIF (subcmd = 3) THEN
  1114. IF Trace THEN KernelLog.String(" -- QUERY FS INFO"); KernelLog.Ln(); END;
  1115. (* SEND *)
  1116. c.netbios := 32 + 25 + 10 + SHORT(Strings.Length(FileSystem) + 1);
  1117. WriteSMBHeader(c);
  1118. c.out.Net8(10);
  1119. c.out.RawInt(0);
  1120. c.out.RawInt(12 + SHORT(Strings.Length(FileSystem) + 1));
  1121. c.out.Net16(0);
  1122. c.out.RawInt(0);
  1123. c.out.RawInt(55);
  1124. c.out.RawInt(0);
  1125. c.out.RawInt(12 + SHORT(Strings.Length(FileSystem) + 1));
  1126. c.out.RawInt(55);
  1127. c.out.RawInt(0);
  1128. c.out.Net8(0);
  1129. c.out.Net8(0);
  1130. c.out.RawInt(12 + SHORT(Strings.Length(FileSystem) + 1));
  1131. c.out.RawLInt(32);
  1132. c.out.RawLInt(64);
  1133. c.out.RawLInt(Strings.Length(FileSystem) + 1);
  1134. c.out.RawString(FileSystem);
  1135. c.out.Update();
  1136. ELSIF (subcmd = 5) THEN
  1137. IF Trace THEN KernelLog.String(" -- QUERY PATH INFO"); KernelLog.Ln(); END;
  1138. c.in.SkipBytes(6);
  1139. c.in.RawString(eName);
  1140. IF Trace THEN KernelLog.String(" -- Path name: "); KernelLog.String(eName); KernelLog.Ln(); END;
  1141. f := Files.Old(eName);
  1142. IF ((f = NIL) & (eName[0] # 0X)) THEN
  1143. (* NOT FOUND *)
  1144. c.error := TRUE;
  1145. c.errorcode := 131073;
  1146. (* SEND *)
  1147. c.netbios := 32 + 3;
  1148. WriteSMBHeader(c);
  1149. c.out.Net8(0); (* word count *)
  1150. c.out.RawInt(0); (* bytecount *)
  1151. c.out.Update();
  1152. RETURN;
  1153. END;
  1154. (* SEND *)
  1155. c.netbios := SHORT(32 + 89 + Strings.Length(eName));
  1156. WriteSMBHeader(c);
  1157. c.out.Net8(10); (* Word count *)
  1158. c.out.RawInt(2); (* total para count *)
  1159. c.out.RawInt(82); (* total data count *)
  1160. c.out.Net16(0); (* reserved *)
  1161. c.out.RawInt(2); (* parameter count *)
  1162. c.out.RawInt(55); (* para offset *)
  1163. c.out.RawInt(0); (* para displacement *)
  1164. c.out.RawInt(82); (* data count *)
  1165. c.out.RawInt(57); (* data offset *)
  1166. c.out.RawInt(0); (* data displacement *)
  1167. c.out.Net8(0); (* setup count *)
  1168. c.out.Net8(0); (* reserved *)
  1169. c.out.RawInt(84); (* byte count *)
  1170. (* query path info params *)
  1171. c.out.RawInt(0); (* ea error offset *)
  1172. (* query path info data*)
  1173. c.out.RawLInt(0); (* created *)
  1174. c.out.RawLInt(0); (* created *)
  1175. c.out.RawLInt(0); (* last access *)
  1176. c.out.RawLInt(0); (* last access *)
  1177. c.out.RawLInt(0); (* last write *)
  1178. c.out.RawLInt(0); (* last write *)
  1179. c.out.RawLInt(0); (* change *)
  1180. c.out.RawLInt(0); (* change *)
  1181. IF eName[0] = 0X THEN
  1182. c.out.RawInt(16); (* attr *)
  1183. ELSE
  1184. c.out.RawInt(0); (* attr *)
  1185. END;
  1186. c.out.RawLInt(0); (* alloc *)
  1187. c.out.RawLInt(0); (* alloc *)
  1188. c.out.RawLInt(0); (* eof *)
  1189. c.out.RawLInt(0); (* eof *)
  1190. c.out.RawLInt(1); (* link count *)
  1191. c.out.Net8(0); (* delete pending *)
  1192. IF eName[0] = 0X THEN
  1193. c.out.Net8(1); (* is dir *)
  1194. ELSE
  1195. c.out.Net8(0); (* is dir *)
  1196. END;
  1197. c.out.RawLInt(0); (* ea list *)
  1198. c.out.RawLInt(Strings.Length(eName)); (* filename len*)
  1199. c.out.RawString(eName); (* file name*)
  1200. c.out.Update();
  1201. ELSIF (subcmd = 1) THEN
  1202. IF Trace THEN KernelLog.String(" -- FIND FIRST 2"); KernelLog.Ln(); END;
  1203. c.in.SkipBytes(2);
  1204. c.in.RawInt(searchCount);
  1205. c.in.SkipBytes(2);
  1206. c.in.RawInt(loi);
  1207. c.in.SkipBytes(4);
  1208. c.in.RawString(pattern);
  1209. IF Trace THEN KernelLog.String(" -- Search Count: "); KernelLog.Int(searchCount, 0); KernelLog.Ln(); END;
  1210. RemoveSlash(pattern);
  1211. ReplaceSlash(pattern);
  1212. RemoveQuotes(pattern);
  1213. GetSharename(c);
  1214. IF Trace THEN
  1215. KernelLog.String(" -- Pattern: "); KernelLog.String(pattern); KernelLog.Ln();
  1216. KernelLog.String(" -- Level of Interest: "); KernelLog.Int(loi, 0); KernelLog.Ln();
  1217. KernelLog.String(" -- Sharename: "); KernelLog.String(c.sharename); KernelLog.Ln();
  1218. END;
  1219. COPY(pattern, c.pattern);
  1220. Strings.Concat(c.sharename, pattern, modPat);
  1221. IF Trace THEN KernelLog.String(" -- Modprefix: "); KernelLog.String(modPat); KernelLog.Ln(); END;
  1222. NEW(enum);
  1223. enum.Open(modPat, {});
  1224. IF searchCount > 100 THEN
  1225. searchCount := 100;
  1226. END;
  1227. i := 0;
  1228. totalFileNameLen := 0;
  1229. WHILE (enum.HasMoreEntries()) & (i < searchCount) DO
  1230. success := enum.GetEntry(fullName, eFlags, eTime, eDate, eSize);
  1231. IF success THEN
  1232. Files.SplitName(fullName, prefix, eName);
  1233. Files.SplitPath(eName, pathname, eName);
  1234. totalFileNameLen := totalFileNameLen + SHORT(Strings.Length(eName));
  1235. lastlen := SHORT(Strings.Length(eName));
  1236. INC(i);
  1237. END;
  1238. END;
  1239. eos := ~enum.HasMoreEntries();
  1240. IF Trace THEN KernelLog.String(" -- Files found: "); KernelLog.Int(i, 0); KernelLog.Ln(); END;
  1241. (* NO FILES FOUND *)
  1242. IF i = 0 THEN
  1243. c.error := TRUE;
  1244. c.errorcode := 131073; (* 1179649; *)
  1245. (* SEND *)
  1246. c.netbios := 32 + 3;
  1247. WriteSMBHeader(c);
  1248. c.out.Net8(0); (* word count *)
  1249. c.out.RawInt(0); (* bytecount *)
  1250. c.out.Update();
  1251. RETURN;
  1252. END;
  1253. IF loi = 260 THEN
  1254. j := 96*i + totalFileNameLen;
  1255. lastlen := lastlen + 96;
  1256. ELSIF loi = 1 THEN
  1257. j := 28*i + totalFileNameLen;
  1258. lastlen := lastlen + 28;
  1259. ELSE
  1260. IF Trace THEN KernelLog.String(" -- LEVEL OF INTEREST NOT SUPPORTED "); KernelLog.Ln(); END;
  1261. RETURN;
  1262. END;
  1263. (* SEND *)
  1264. c.netbios := 32 + 23 + 10 + j;
  1265. WriteSMBHeader(c);
  1266. c.out.Net8(10);
  1267. c.out.RawInt(10); (* total parameter count *)
  1268. c.out.RawInt(j); (* total data count *)
  1269. c.out.Net16(0);
  1270. c.out.RawInt(10); (* parameter count *)
  1271. c.out.RawInt(55); (* parameter offset *)
  1272. c.out.RawInt(0);
  1273. c.out.RawInt(j); (* data count *)
  1274. c.out.RawInt(65); (* data offset *)
  1275. c.out.RawInt(0);
  1276. c.out.Net8(0);
  1277. c.out.Net8(0);
  1278. c.out.RawInt(10 + j); (* byte count *)
  1279. c.sid := GetSID();
  1280. c.out.RawInt(c.sid); (* search id *)
  1281. c.out.RawInt(i); (* search count *)
  1282. IF eos THEN
  1283. c.out.RawInt(1); (* end of search *)
  1284. ELSE
  1285. c.out.RawInt(0); (* end of search *)
  1286. END;
  1287. c.out.RawInt(0); (* ea error *)
  1288. c.out.RawInt(j - lastlen);(* lastnameoffset *)
  1289. enum.Reset();
  1290. WHILE (i > 0) DO
  1291. success := enum.GetEntry(fullName, eFlags, eTime, eDate, eSize);
  1292. IF success THEN
  1293. Files.SplitName(fullName, prefix, eName);
  1294. Files.SplitPath(eName, pathname, eName);
  1295. f := Files.Old(eName);
  1296. IF loi = 260 THEN
  1297. c.out.RawLInt(96 + Strings.Length(eName)); (* next entry offset *)
  1298. c.out.RawLInt(0); (* file index*)
  1299. c.out.RawLInt(0); (* created *)
  1300. c.out.RawLInt(0); (* created *)
  1301. c.out.RawLInt(0); (* last access *)
  1302. c.out.RawLInt(0); (* last access *)
  1303. IF (f # NIL) THEN
  1304. f.GetDate(t,d);
  1305. dTime := Dates.OberonToDateTime(d,t);
  1306. GetSMBTimeStamp(dTime, tarray);
  1307. c.out.RawLInt(tarray[0]); (* last write *)
  1308. c.out.RawLInt(tarray[1]); (* last write *)
  1309. ELSE
  1310. c.out.RawLInt(0); (* last write *)
  1311. c.out.RawLInt(0); (* last write *)
  1312. END;
  1313. c.out.RawLInt(0); (* change *)
  1314. c.out.RawLInt(0); (* change *)
  1315. IF (f # NIL) THEN
  1316. c.out.RawLInt(f.Length()); (* eof *)
  1317. c.out.RawLInt(0); (* eof *)
  1318. ELSE
  1319. c.out.RawLInt(0); (* eof *)
  1320. c.out.RawLInt(0); (* eof *)
  1321. END;
  1322. IF (f # NIL) THEN
  1323. c.out.RawLInt(f.Length()); (* alloc *)
  1324. ELSE
  1325. c.out.RawLInt(0); (* alloc *)
  1326. END;
  1327. c.out.RawLInt(0); (* alloc *)
  1328. flags := {};
  1329. IF (Files.Directory IN eFlags) THEN INCL(flags, 4); END;
  1330. IF (Files.ReadOnly IN eFlags) THEN INCL(flags, 0) END;
  1331. c.out.RawLInt(SYSTEM.VAL(LONGINT, flags)); (* file attr *)
  1332. c.out.RawLInt(1 + Strings.Length(eName)); (* filename len *)
  1333. c.out.RawLInt(0); (* ea list *)
  1334. c.out.RawSInt(0); (* short fn len *)
  1335. c.out.RawSInt(0); (* reserved *)
  1336. FOR z := 1 TO 24 DO
  1337. c.out.Net8(0);
  1338. END; (* short filename *)
  1339. c.out.RawString(eName); (* file name*)
  1340. c.out.RawSInt(0); (* padding *)
  1341. ELSIF loi = 1 THEN
  1342. c.out.RawLInt(0); (* resume key *)
  1343. c.out.RawLInt(0); (* created *)
  1344. c.out.RawLInt(0); (* last access *)
  1345. IF (f # NIL) THEN
  1346. f.GetDate(t,d);
  1347. dTime := Dates.OberonToDateTime(d,t);
  1348. GetUnixTimeStamp(dTime, t);
  1349. c.out.RawLInt(t); (* last write *)
  1350. c.out.RawLInt(f.Length()); (* data size *)
  1351. c.out.RawLInt(f.Length()); (* alloc size *)
  1352. ELSE
  1353. c.out.RawLInt(0); (* last write *)
  1354. c.out.RawLInt(0);
  1355. c.out.RawLInt(0);
  1356. END;
  1357. flags := {};
  1358. IF (Files.Directory IN eFlags) THEN INCL(flags, 4); END;
  1359. IF (Files.ReadOnly IN eFlags) THEN INCL(flags, 0) END;
  1360. c.out.RawInt(SYSTEM.VAL(INTEGER, flags)); (* file attri *)
  1361. c.out.RawSInt(SHORT(SHORT(Strings.Length(eName)))); (* filename len *)
  1362. c.out.RawString(eName); (* file name*)
  1363. END;
  1364. END;
  1365. DEC(i);
  1366. END;
  1367. c.out.Update();
  1368. enum.Close();
  1369. ELSIF (subcmd = 2) THEN
  1370. IF Trace THEN KernelLog.String(" -- FIND Next 2"); KernelLog.Ln(); END;
  1371. c.in.RawInt(sidnext);
  1372. c.in.RawInt(searchCount);
  1373. c.in.RawInt(loi);
  1374. c.in.SkipBytes(6);
  1375. c.in.RawString(resumeFn);
  1376. GetPattern(sidnext, pattern);
  1377. ReplaceSlash(pattern);
  1378. GetSharename(c);
  1379. IF Trace THEN
  1380. KernelLog.String(" _- Search Count: "); KernelLog.Int(searchCount, 0); KernelLog.Ln();
  1381. KernelLog.String(" _- Resume Filename: "); KernelLog.String(resumeFn); KernelLog.Ln();
  1382. KernelLog.String(" -- Pattern: "); KernelLog.String(pattern); KernelLog.Ln();
  1383. KernelLog.String(" -- Level of Interest: "); KernelLog.Int(loi, 0); KernelLog.Ln();
  1384. KernelLog.String(" -- sharename: "); KernelLog.String(c.sharename); KernelLog.Ln();
  1385. END;
  1386. Strings.Concat(c.sharename, pattern, modPat);
  1387. IF Trace THEN KernelLog.String(" -- Modprefix: "); KernelLog.String(modPat); KernelLog.Ln(); END;
  1388. NEW(enum);
  1389. enum.Open(modPat, {});
  1390. IF searchCount > 100 THEN
  1391. searchCount := 100;
  1392. END;
  1393. i := 0;
  1394. totalFileNameLen := 0;
  1395. WHILE (eName # resumeFn) & (enum.HasMoreEntries()) DO
  1396. success := enum.GetEntry(fullName, eFlags, eTime, eDate, eSize);
  1397. IF success THEN
  1398. Files.SplitName(fullName, prefix, eName);
  1399. Files.SplitPath(eName, pathname, eName);
  1400. END;
  1401. END;
  1402. WHILE (enum.HasMoreEntries()) & (i < searchCount) DO
  1403. success := enum.GetEntry(fullName, eFlags, eTime, eDate, eSize);
  1404. IF success THEN
  1405. Files.SplitName(fullName, prefix, eName);
  1406. Files.SplitPath(eName, pathname, eName);
  1407. totalFileNameLen := totalFileNameLen + SHORT(Strings.Length(eName));
  1408. lastlen := SHORT(Strings.Length(eName));
  1409. INC(i);
  1410. END;
  1411. END;
  1412. eos := ~enum.HasMoreEntries();
  1413. IF Trace THEN KernelLog.String(" -- Files found: "); KernelLog.Int(i, 0); KernelLog.Ln(); END;
  1414. IF loi = 260 THEN
  1415. j := 96*i + totalFileNameLen;
  1416. lastlen := lastlen + 96;
  1417. ELSIF loi = 1 THEN
  1418. j := 28*i + totalFileNameLen;
  1419. lastlen := lastlen + 28;
  1420. ELSE
  1421. IF Trace THEN KernelLog.String(" -- LEVEL OF INTEREST NOT SUPPORTED "); KernelLog.Ln(); END;
  1422. RETURN;
  1423. END;
  1424. (* SEND *)
  1425. c.netbios := 32 + 23 + 8 + j;
  1426. WriteSMBHeader(c);
  1427. c.out.Net8(8);
  1428. c.out.RawInt(8); (* total parameter count *)
  1429. c.out.RawInt(j); (* total data count *)
  1430. c.out.Net16(0);
  1431. c.out.RawInt(8); (* parameter count *)
  1432. c.out.RawInt(55); (* parameter offset *)
  1433. c.out.RawInt(0);
  1434. c.out.RawInt(j); (* data count *)
  1435. c.out.RawInt(63); (* data offset *)
  1436. c.out.RawInt(0);
  1437. c.out.Net8(0);
  1438. c.out.Net8(0);
  1439. c.out.RawInt(10 + j); (* byte count *)
  1440. c.out.RawInt(i); (* search count *)
  1441. IF eos THEN
  1442. c.out.RawInt(1); (* end of search *)
  1443. ELSE
  1444. c.out.RawInt(0); (* end of search *)
  1445. END;
  1446. c.out.RawInt(0); (* ea error *)
  1447. c.out.RawInt(j - lastlen);(* lastnameoffset *)
  1448. enum.Reset();
  1449. WHILE (eName # resumeFn) & (enum.HasMoreEntries()) DO
  1450. success := enum.GetEntry(fullName, eFlags, eTime, eDate, eSize);
  1451. IF success THEN
  1452. Files.SplitName(fullName, prefix, eName);
  1453. Files.SplitPath(eName, pathname, eName);
  1454. END;
  1455. END;
  1456. WHILE (i > 0) DO
  1457. success := enum.GetEntry(fullName, eFlags, eTime, eDate, eSize);
  1458. IF success THEN
  1459. Files.SplitName(fullName, prefix, eName);
  1460. Files.SplitPath(eName, pathname, eName);
  1461. f := Files.Old(eName);
  1462. IF loi = 260 THEN
  1463. c.out.RawLInt(96 + Strings.Length(eName)); (* next entry offset *)
  1464. c.out.RawLInt(0); (* file index*)
  1465. c.out.RawLInt(0); (* created *)
  1466. c.out.RawLInt(0); (* created *)
  1467. c.out.RawLInt(0); (* last access *)
  1468. c.out.RawLInt(0); (* last access *)
  1469. IF (f # NIL) THEN
  1470. f.GetDate(t,d);
  1471. dTime := Dates.OberonToDateTime(d,t);
  1472. GetSMBTimeStamp(dTime, tarray);
  1473. c.out.RawLInt(tarray[0]); (* last write *)
  1474. c.out.RawLInt(tarray[1]); (* last write *)
  1475. ELSE
  1476. c.out.RawLInt(0); (* last write *)
  1477. c.out.RawLInt(0); (* last write *)
  1478. END;
  1479. c.out.RawLInt(0); (* change *)
  1480. c.out.RawLInt(0); (* change *)
  1481. IF (f # NIL) THEN
  1482. c.out.RawLInt(f.Length()); (* eof *)
  1483. c.out.RawLInt(0); (* eof *)
  1484. c.out.RawLInt(f.Length()); (* alloc *)
  1485. c.out.RawLInt(0); (* alloc *)
  1486. ELSE
  1487. c.out.RawLInt(0); (* eof *)
  1488. c.out.RawLInt(0); (* eof *)
  1489. c.out.RawLInt(0); (* alloc *)
  1490. c.out.RawLInt(0); (* alloc *)
  1491. END;
  1492. flags := {};
  1493. IF (Files.Directory IN eFlags) THEN INCL(flags, 4); END;
  1494. IF (Files.ReadOnly IN eFlags) THEN INCL(flags, 0) END;
  1495. c.out.RawLInt(SYSTEM.VAL(LONGINT, flags)); (* file attr *)
  1496. c.out.RawLInt(1 + Strings.Length(eName)); (* filename len *)
  1497. c.out.RawLInt(0); (* ea list *)
  1498. c.out.RawSInt(0); (* short fn len *)
  1499. c.out.RawSInt(0); (* reserved *)
  1500. FOR z := 1 TO 24 DO
  1501. c.out.Net8(0);
  1502. END; (* short filename *)
  1503. c.out.RawString(eName); (* file name*)
  1504. c.out.RawSInt(0); (* padding *)
  1505. ELSIF loi = 1 THEN
  1506. c.out.RawLInt(0); (* resume key *)
  1507. c.out.RawLInt(0); (* created *)
  1508. c.out.RawLInt(0); (* last access *)
  1509. IF (f # NIL) THEN
  1510. f.GetDate(t,d);
  1511. dTime := Dates.OberonToDateTime(d,t);
  1512. GetUnixTimeStamp(dTime, t);
  1513. c.out.RawLInt(t); (* last write *)
  1514. c.out.RawLInt(f.Length()); (* data size *)
  1515. ELSE
  1516. c.out.RawLInt(0); (* last write *)
  1517. c.out.RawLInt(0);
  1518. END;
  1519. IF (f # NIL) THEN
  1520. c.out.RawLInt(f.Length()); (* alloc size *)
  1521. ELSE
  1522. c.out.RawLInt(0);
  1523. END;
  1524. flags := {};
  1525. IF (Files.Directory IN eFlags) THEN INCL(flags, 4); END;
  1526. IF (Files.ReadOnly IN eFlags) THEN INCL(flags, 0) END;
  1527. c.out.RawInt(SYSTEM.VAL(INTEGER, flags)); (* file attri *)
  1528. c.out.RawSInt(SHORT(SHORT(Strings.Length(eName)))); (* filename len *)
  1529. c.out.RawString(eName); (* file name*)
  1530. END;
  1531. END;
  1532. DEC(i);
  1533. END;
  1534. c.out.Update();
  1535. enum.Close();
  1536. END;
  1537. END Trans2Logic;
  1538. PROCEDURE WriteSMBHeader(c: Connection);
  1539. BEGIN
  1540. c.in.Reset();
  1541. c.out.Reset();
  1542. c.out.Net16(0); (* message type *)
  1543. c.out.Net16(c.netbios); (* Netbios length *)
  1544. c.out.Char(CHR(255));
  1545. c.out.String("SMB");
  1546. c.out.Net8(c.cmd); (* Command *)
  1547. IF ~c.error THEN
  1548. c.out.Net32(0); (* status code *)
  1549. ELSE
  1550. c.out.RawLInt(c.errorcode);
  1551. END;
  1552. c.out.Net8(90H); (* FLAGS *)
  1553. c.out.RawInt(1); (* FLAGS 2 *)
  1554. c.out.Net32(0);
  1555. c.out.Net32(0); (* EXTRA *)
  1556. c.out.Net32(0);
  1557. IF (c.cmd = ORD(75X)) THEN
  1558. c.tid := GetTID();
  1559. END;
  1560. c.out.RawInt(c.tid); (* TID *)
  1561. c.out.RawInt(c.pid); (* PID *)
  1562. IF (c.cmd = ORD(73X)) THEN
  1563. c.uid := GetUID();
  1564. END;
  1565. c.out.RawInt(c.uid); (* UID *)
  1566. c.out.RawInt(c.mid); (* MID *)
  1567. END WriteSMBHeader;
  1568. PROCEDURE CheckSMBHeader(VAR c: Connection): BOOLEAN;
  1569. VAR
  1570. variable: LONGINT;
  1571. BEGIN
  1572. c.in.SkipBytes(2);
  1573. c.msgSize := c.in.Net16(); (* NetBios length *)
  1574. variable := c.in.Net32(); (* 0xFF SMB *)
  1575. IF variable # -11317950 THEN
  1576. c.error := TRUE; (* not correct *)
  1577. RETURN TRUE;
  1578. END;
  1579. c.cmd := c.in.Net8();
  1580. variable := c.in.Net32(); (* NT Status *)
  1581. IF variable # 0 THEN
  1582. c.error := TRUE; (* not correct *)
  1583. RETURN TRUE;
  1584. END;
  1585. c.flags := c.in.Net8();
  1586. c.in.RawInt(c.flags2);
  1587. c.in.SkipBytes(12);
  1588. c.in.RawInt(c.tid);
  1589. c.in.RawInt(c.pid);
  1590. c.in.RawInt(c.uid);
  1591. c.in.RawInt(c.mid);
  1592. RETURN FALSE;
  1593. END CheckSMBHeader;
  1594. PROCEDURE ReplaceSlash(VAR name: ARRAY OF CHAR);
  1595. VAR
  1596. i: LONGINT;
  1597. BEGIN
  1598. i := 0;
  1599. WHILE (i < Strings.Length(name)) DO
  1600. IF name[i] = CHR(5CH) THEN
  1601. name[i] := CHR(2FH);
  1602. END;
  1603. INC(i)
  1604. END;
  1605. END ReplaceSlash;
  1606. PROCEDURE RemoveQuotes(VAR name: ARRAY OF CHAR);
  1607. VAR
  1608. i,j: LONGINT;
  1609. newName: ARRAY 256 OF CHAR;
  1610. BEGIN
  1611. i := 0;
  1612. j := 0;
  1613. WHILE (i < Strings.Length(name)) DO
  1614. IF name[i] # CHR(22H) THEN
  1615. newName[j] := name[i];
  1616. INC(i);
  1617. INC(j);
  1618. ELSE
  1619. INC(i);
  1620. END;
  1621. END;
  1622. COPY(newName, name);
  1623. END RemoveQuotes;
  1624. PROCEDURE RemoveSlash(VAR name: ARRAY OF CHAR);
  1625. VAR
  1626. i: LONGINT;
  1627. BEGIN
  1628. i := 1;
  1629. WHILE (i <= Strings.Length(name)) DO
  1630. name[i-1] := name[i];
  1631. INC(i)
  1632. END;
  1633. END RemoveSlash;
  1634. PROCEDURE NewAgent(c: TCP.Connection; s: TCPServices.Service): TCPServices.Agent;
  1635. VAR
  1636. a: Agent;
  1637. BEGIN
  1638. NEW(a, c, s);
  1639. RETURN a;
  1640. END NewAgent;
  1641. PROCEDURE StartServer*(context: Commands.Context);
  1642. VAR
  1643. res: WORD;
  1644. BEGIN {EXCLUSIVE}
  1645. IF service = NIL THEN
  1646. lastUID := 777;
  1647. lastTID := 555;
  1648. lastFID := 333;
  1649. lastSID := 111;
  1650. NEW(firstConn);
  1651. NEW(service, SMBPort, NewAgent, res);
  1652. context.out.String("Start SambaServer...");
  1653. IF res = TCPServices.Ok THEN
  1654. context.out.String("started!");
  1655. context.out.Ln();
  1656. ELSE
  1657. context.out.Ln();
  1658. context.out.String("Could not start SambaServer. Res: ");
  1659. context.out.Int(res, 0);
  1660. context.out.Ln();
  1661. service := NIL;
  1662. END;
  1663. ELSE
  1664. context.out.String("SambaServer already running...");
  1665. context.out.Ln();
  1666. END;
  1667. END StartServer;
  1668. PROCEDURE StopServer*(context: Commands.Context);
  1669. BEGIN {EXCLUSIVE}
  1670. IF service # NIL THEN
  1671. service.Stop();
  1672. service := NIL;
  1673. context.out.String("SambaServer stopped!");
  1674. context.out.Ln();
  1675. ELSE
  1676. context.out.String("SambaServer was already stopped!");
  1677. context.out.Ln();
  1678. END;
  1679. END StopServer;
  1680. PROCEDURE FindShare(CONST unc : ARRAY OF CHAR) : Share;
  1681. VAR share : Share;
  1682. BEGIN {EXCLUSIVE}
  1683. share := shares;
  1684. WHILE (share # NIL) & (share.unc # unc) DO share := share.next; END;
  1685. RETURN share;
  1686. END FindShare;
  1687. PROCEDURE AddShare*(context : Commands.Context); (** name sharepath ~ *)
  1688. VAR share : Share; prefix : Files.Prefix; path : Files.FileName;
  1689. BEGIN
  1690. NEW(share);
  1691. context.arg.SkipWhitespace; context.arg.String(share.unc);
  1692. context.arg.SkipWhitespace; context.arg.String(share.path);
  1693. Files.SplitName(share.path, prefix, path);
  1694. IF (prefix # "") THEN
  1695. IF FindShare(share.unc) = NIL THEN
  1696. BEGIN {EXCLUSIVE}
  1697. share.next := shares;
  1698. shares := share;
  1699. END;
  1700. context.out.String("Added share "); context.out.String(share.unc);
  1701. context.out.String(" ("); context.out.String(share.path);
  1702. context.out.String(")"); context.out.Ln;
  1703. ELSE
  1704. context.error.String("UNC "); context.error.String(share.unc);
  1705. context.error.String(" is already used."); context.error.Ln;
  1706. END;
  1707. ELSE
  1708. context.error.String("Prefix required"); context.error.Ln;
  1709. END;
  1710. END AddShare;
  1711. PROCEDURE ListShares*(context : Commands.Context);
  1712. VAR share : Share;
  1713. BEGIN {EXCLUSIVE}
  1714. context.out.String("SambaServer share list: "); context.out.Ln;
  1715. IF (shares # NIL) THEN
  1716. share := shares;
  1717. WHILE (share # NIL) DO
  1718. context.out.String(share.unc); context.out.String(" -> ");
  1719. context.out.String(share.path); context.out.Ln;
  1720. share := share.next;
  1721. END;
  1722. ELSE
  1723. context.out.String("No shares"); context.out.Ln;
  1724. END;
  1725. END ListShares;
  1726. PROCEDURE GetSMBTimeStamp(dtNow:Dates.DateTime; VAR t: ARRAY OF LONGINT);
  1727. VAR
  1728. dtOld : Dates.DateTime;
  1729. diffDay, diffHour, diffMinute, diffSecond: LONGINT;
  1730. tsNow : HUGEINT;
  1731. BEGIN
  1732. dtOld.year := 1601;
  1733. dtOld.month := 1;
  1734. dtOld.day := 1;
  1735. dtOld.hour := 0;
  1736. dtOld.minute := 0;
  1737. dtOld.second := 0;
  1738. Dates.TimeDifference(dtOld, dtNow, diffDay, diffHour, diffMinute, diffSecond);
  1739. tsNow := diffDay * 86400 + diffHour * 3600 + diffMinute * 60 + diffSecond;
  1740. tsNow := tsNow * 10000000;
  1741. t[0] := SHORT(tsNow);
  1742. t[1] := SHORT(tsNow DIV 100000000H);
  1743. END GetSMBTimeStamp;
  1744. PROCEDURE GetUnixTimeStamp(dtNow: Dates.DateTime; VAR t: LONGINT);
  1745. VAR
  1746. dtOld : Dates.DateTime;
  1747. diffDay, diffHour, diffMinute, diffSecond: LONGINT;
  1748. BEGIN
  1749. dtOld.year := 1970;
  1750. dtOld.month := 1;
  1751. dtOld.day := 1;
  1752. dtOld.hour := 0;
  1753. dtOld.minute := 0;
  1754. dtOld.second := 0;
  1755. Dates.TimeDifference(dtOld, dtNow, diffDay, diffHour, diffMinute, diffSecond);
  1756. t := diffDay * 86400 + diffHour * 3600 + diffMinute * 60 + diffSecond;
  1757. END GetUnixTimeStamp;
  1758. PROCEDURE GetDOSTimeStamp(dtNow: Dates.DateTime; VAR t: LONGINT);
  1759. VAR
  1760. hour, minute, second, year, month, day: LONGINT;
  1761. BEGIN
  1762. hour := ASH(dtNow.hour, 27);
  1763. minute := ASH(dtNow.minute, 21);
  1764. second := ASH(dtNow.second DIV 2, 16);
  1765. year := ASH(dtNow.year - 1980, 9);
  1766. month := ASH(dtNow.month, 5);
  1767. day := dtNow.day;
  1768. t := hour + minute + second + year + month + day;
  1769. END GetDOSTimeStamp;
  1770. PROCEDURE Cleanup;
  1771. BEGIN {EXCLUSIVE}
  1772. IF service # NIL THEN
  1773. service.Stop();
  1774. service := NIL;
  1775. END;
  1776. END Cleanup;
  1777. BEGIN
  1778. shares := NIL;
  1779. Modules.InstallTermHandler(Cleanup);
  1780. END SambaServer.
  1781. SambaServer.StartServer ~
  1782. SambaServer.StopServer ~
  1783. System.Free SambaServer ~
  1784. SambaServer.ListShares ~
  1785. SambaServer.AddShare \AOS AOS: ~
  1786. SambaServer.AddShare \FAT FAT:Test/ ~
  1787. SambaServer.AddShare \Test ../Legal/ ~