PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
smb_fio.c
1/*
2 Copyright 2009-2010, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4*/
5
6#include "types.h"
7#include "defs.h"
8#include "irx.h"
9#include "intrman.h"
10#include "iomanX.h"
11#include "io_common.h"
12#include "sifman.h"
13#include "stdio.h"
14#include "sysclib.h"
15#include "thbase.h"
16#include "thsemap.h"
17#include "errno.h"
18#include "ps2smb.h"
19
20#include "smb_fio.h"
21#include "smb.h"
22#include "auth.h"
23#include "debug.h"
24
25int smbman_io_sema;
26
27// driver ops func tab
28static iop_device_ops_t smbman_ops = {
29 &smb_init,
30 &smb_deinit,
31 (void *)&smb_dummy,
32 &smb_open,
33 &smb_close,
34 &smb_read,
35 &smb_write,
36 &smb_lseek,
37 (void *)&smb_dummy,
38 &smb_remove,
39 &smb_mkdir,
40 &smb_rmdir,
41 &smb_dopen,
42 &smb_dclose,
43 &smb_dread,
44 &smb_getstat,
45 (void *)&smb_dummy,
46 &smb_rename,
47 &smb_chdir,
48 (void *)&smb_dummy,
49 (void *)&smb_dummy,
50 (void *)&smb_dummy,
51 &smb_lseek64,
52 &smb_devctl,
53 (void *)&smb_dummy,
54 (void *)&smb_dummy,
55 (void *)&smb_dummy};
56
57// driver descriptor
58static iop_device_t smbdev = {
59 "smb",
60 IOP_DT_FS | IOP_DT_FSEXT,
61 1,
62 "SMB",
63 &smbman_ops,
64};
65
66#define SMB_NAME_MAX 256
67
68typedef struct
69{
70 iop_file_t *f;
71 int smb_fid;
72 s64 filesize;
73 s64 position;
74 u32 mode;
75 char name[SMB_NAME_MAX];
76} FHANDLE;
77
78#define MAX_FDHANDLES 32
79FHANDLE smbman_fdhandles[MAX_FDHANDLES];
80
81#define SMB_SEARCH_BUF_MAX 4096
82#define SMB_PATH_MAX 1024
83
84static ShareEntry_t ShareList;
85static u8 SearchBuf[SMB_SEARCH_BUF_MAX];
86static char smb_curdir[SMB_PATH_MAX];
87static char smb_curpath[SMB_PATH_MAX];
88static char smb_secpath[SMB_PATH_MAX];
89
90static int keepalive_mutex = -1;
91static int keepalive_inited = 0;
92static int keepalive_locked = 1;
93static int keepalive_tid;
94static iop_sys_clock_t keepalive_sysclock;
95
96static int UID = -1;
97static int TID = -1;
98
99static smbLogOn_in_t glogon_info;
100static smbOpenShare_in_t gopenshare_info;
101
102static int smb_LogOn(smbLogOn_in_t *logon);
103static int smb_OpenShare(smbOpenShare_in_t *openshare);
104
105//-------------------------------------------------------------------------
106// Timer Interrupt handler for Echoing the server every 3 seconds, when
107// not already doing IO, and counting after an IO operation has finished
108//
109static unsigned int timer_intr_handler(void *args)
110{
111 iSignalSema(keepalive_mutex);
112 iSetAlarm(&keepalive_sysclock, timer_intr_handler, NULL);
113
114 return (unsigned int)args;
115}
116
117//-------------------------------------------------------------------------
118static void keepalive_deinit(void)
119{
120 int oldstate;
121
122 // Cancel the alarm
123 if (keepalive_inited) {
124 CpuSuspendIntr(&oldstate);
125 CancelAlarm(timer_intr_handler, NULL);
126 CpuResumeIntr(oldstate);
127 keepalive_inited = 0;
128 }
129}
130
131//-------------------------------------------------------------------------
132static void keepalive_init(void)
133{
134 // set up the alarm
135 if ((!keepalive_inited) && (!keepalive_locked)) {
136 keepalive_deinit();
137 SetAlarm(&keepalive_sysclock, timer_intr_handler, NULL);
138 keepalive_inited = 1;
139 }
140}
141
142//-------------------------------------------------------------------------
143static void keepalive_lock(void)
144{
145 keepalive_locked = 1;
146}
147
148//-------------------------------------------------------------------------
149static void keepalive_unlock(void)
150{
151 keepalive_locked = 0;
152}
153
154//-------------------------------------------------------------------------
155static void smb_io_lock(void)
156{
157 keepalive_deinit();
158
159 WaitSema(smbman_io_sema);
160}
161
162//-------------------------------------------------------------------------
163static void smb_io_unlock(void)
164{
165 SignalSema(smbman_io_sema);
166
167 keepalive_init();
168}
169
170//-------------------------------------------------------------------------
171static void keepalive_thread(void *args)
172{
173 int opened_share = 0;
174
175 (void)args;
176
177 while (1) {
178 int r;
179
180 // wait for keepalive mutex
181 WaitSema(keepalive_mutex);
182
183 // ensure no IO is already processing
184 WaitSema(smbman_io_sema);
185
186 // echo the SMB server
187 r = smb_Echo("PS2 KEEPALIVE ECHO", 18);
188 if (r < 0) {
189 keepalive_lock();
190
191 if (TID != -1)
192 opened_share = 1;
193
194 if (UID != -1) {
195 r = smb_LogOn((smbLogOn_in_t *)&glogon_info);
196 if (r == 0) {
197 if (opened_share)
198 smb_OpenShare((smbOpenShare_in_t *)&gopenshare_info);
199 }
200 }
201
202 keepalive_unlock();
203 }
204
205 SignalSema(smbman_io_sema);
206 }
207}
208
209//--------------------------------------------------------------
210int smb_dummy(void)
211{
212 return -EIO;
213}
214
215//--------------------------------------------------------------
216int smb_init(iop_device_t *dev)
217{
219
220 (void)dev;
221
222 // create a mutex for IO ops
223 smbman_io_sema = CreateMutex(IOP_MUTEX_UNLOCKED);
224
225 // create a mutex for keep alive
226 keepalive_mutex = CreateMutex(IOP_MUTEX_LOCKED);
227
228 // set the keepalive timer (3 seconds)
229 USec2SysClock(3000 * 1000, &keepalive_sysclock);
230
231 // starting the keepalive thead
232 thread.attr = TH_C;
233 thread.option = 0;
234 thread.thread = (void *)keepalive_thread;
235 thread.stacksize = 0x600;
236 thread.priority = 0x64;
237
238 keepalive_tid = CreateThread(&thread);
239 StartThread(keepalive_tid, NULL);
240
241 return 0;
242}
243
244//--------------------------------------------------------------
245int smb_initdev(void)
246{
247 int i;
248
249 DelDrv(smbdev.name);
250 if (AddDrv((iop_device_t *)&smbdev))
251 return 1;
252
253 for (i = 0; i < MAX_FDHANDLES; i++) {
254 FHANDLE *fh;
255
256 fh = (FHANDLE *)&smbman_fdhandles[i];
257 fh->f = NULL;
258 fh->smb_fid = -1;
259 fh->filesize = 0;
260 fh->position = 0;
261 fh->mode = 0;
262 }
263
264 return 0;
265}
266
267//--------------------------------------------------------------
268int smb_deinit(iop_device_t *dev)
269{
270 (void)dev;
271
272 keepalive_deinit();
273 DeleteThread(keepalive_tid);
274
275 DeleteSema(smbman_io_sema);
276
277 DeleteSema(keepalive_mutex);
278 keepalive_mutex = -1;
279
280 return 0;
281}
282
283//--------------------------------------------------------------
284static FHANDLE *smbman_getfilefreeslot(void)
285{
286 int i;
287
288 for (i = 0; i < MAX_FDHANDLES; i++) {
289 FHANDLE *fh;
290
291 fh = (FHANDLE *)&smbman_fdhandles[i];
292 if (fh->f == NULL)
293 return fh;
294 }
295
296 return 0;
297}
298
299//--------------------------------------------------------------
300static char *prepare_path(const char *path, char *full_path, int max_path)
301{
302 const char *p, *p2;
303 int i;
304
305 // Reserve space for 2 backslashes and a NULL.
306 strncpy(full_path, smb_curdir, max_path - 3);
307 strcat(full_path, "\\");
308
309 // Skip all leading slashes and backslashes.
310 p = path;
311 while ((*p == '\\') || (*p == '/'))
312 p++;
313
314 // Locate the end of the path, ignoring any trailing slashes and backslashes.
315 p2 = &path[strlen(path)];
316 while ((*p2 == '\\') || (*p2 == '/'))
317 p2--;
318
319 // Copy path. Reserve space for a backslash and a NULL
320 for (i = strlen(full_path); (p <= p2) && (max_path - i - 2 > 0); p++, i++) { // Convert all slashes along the path to backslashes.
321 full_path[i] = (*p == '/') ? '\\' : *p;
322 }
323
324 // Append a backslash and null-terminate.
325 full_path[i] = '\\';
326 full_path[i + 1] = '\0';
327
328 return full_path;
329}
330
331//--------------------------------------------------------------
332int smb_open(iop_file_t *f, const char *filename, int flags, int mode)
333{
334 int r = 0;
335 FHANDLE *fh;
336 s64 filesize;
337
338 (void)mode;
339
340 if (!filename)
341 return -ENOENT;
342
343 if ((UID == -1) || (TID == -1))
344 return -ENOTCONN;
345
346 char *path = prepare_path(filename, smb_curpath, SMB_PATH_MAX);
347
348 smb_io_lock();
349
350 fh = smbman_getfilefreeslot();
351 if (fh) {
352 r = smb_OpenAndX(UID, TID, path, &filesize, flags);
353 if (r >= 0) {
354 f->privdata = fh;
355 fh->f = f;
356 fh->smb_fid = r;
357 fh->mode = flags;
358 fh->filesize = filesize;
359 fh->position = 0;
360 if (fh->mode & O_TRUNC)
361 fh->filesize = 0;
362 else if (fh->mode & O_APPEND)
363 fh->position = filesize;
364 strncpy(fh->name, path, SMB_NAME_MAX);
365 r = 0;
366 }
367 } else
368 r = -EMFILE;
369
370 smb_io_unlock();
371
372 return r;
373}
374
375//--------------------------------------------------------------
376int smb_close(iop_file_t *f)
377{
378 FHANDLE *fh = (FHANDLE *)f->privdata;
379 int r = 0;
380
381 if ((UID == -1) || (TID == -1) || (fh->smb_fid == -1))
382 return -EBADF;
383
384 smb_io_lock();
385
386 if (fh) {
387 if (fh->mode != O_DIROPEN) {
388 r = smb_Close(UID, TID, fh->smb_fid);
389 if (r != 0) {
390 goto io_unlock;
391 }
392 }
393 memset(fh, 0, sizeof(FHANDLE));
394 fh->smb_fid = -1;
395 r = 0;
396 }
397
398io_unlock:
399 smb_io_unlock();
400
401 return r;
402}
403
404//--------------------------------------------------------------
405void smb_closeAll(void)
406{
407 int i;
408
409 for (i = 0; i < MAX_FDHANDLES; i++) {
410 FHANDLE *fh;
411
412 fh = (FHANDLE *)&smbman_fdhandles[i];
413 if (fh->smb_fid != -1)
414 smb_Close(UID, TID, fh->smb_fid);
415 }
416}
417
418//--------------------------------------------------------------
419int smb_lseek(iop_file_t *f, int pos, int where)
420{
421 return (int)smb_lseek64(f, pos, where);
422}
423
424//--------------------------------------------------------------
425int smb_read(iop_file_t *f, void *buf, int size)
426{
427 FHANDLE *fh = (FHANDLE *)f->privdata;
428 int r;
429
430 if ((UID == -1) || (TID == -1) || (fh->smb_fid == -1))
431 return -EBADF;
432
433 if ((fh->position + size) > fh->filesize)
434 size = fh->filesize - fh->position;
435
436 smb_io_lock();
437
438 r = smb_ReadFile(UID, TID, fh->smb_fid, fh->position, buf, size);
439 if (r > 0) {
440 fh->position += r;
441 }
442
443 smb_io_unlock();
444
445 return r;
446}
447
448//--------------------------------------------------------------
449int smb_write(iop_file_t *f, void *buf, int size)
450{
451 FHANDLE *fh = (FHANDLE *)f->privdata;
452 int r;
453
454 if ((UID == -1) || (TID == -1) || (fh->smb_fid == -1))
455 return -EBADF;
456
457 if ((!(fh->mode & O_RDWR)) && (!(fh->mode & O_WRONLY)))
458 return -EACCES;
459
460 smb_io_lock();
461
462 r = smb_WriteFile(UID, TID, fh->smb_fid, fh->position, buf, size);
463 if (r > 0) {
464 fh->position += r;
465 if (fh->position > fh->filesize)
466 fh->filesize += fh->position - fh->filesize;
467 }
468
469 smb_io_unlock();
470
471 return r;
472}
473
474//--------------------------------------------------------------
475int smb_remove(iop_file_t *f, const char *filename)
476{
477 int r;
478
479 (void)f;
480
481 if (!filename)
482 return -ENOENT;
483
484 if ((UID == -1) || (TID == -1))
485 return -ENOTCONN;
486
487 char *path = prepare_path(filename, smb_curpath, SMB_PATH_MAX);
488
489 smb_io_lock();
490
491 DPRINTF("smb_remove: filename=%s\n", filename);
492
493 r = smb_Delete(UID, TID, path);
494
495 smb_io_unlock();
496
497 return r;
498}
499
500//--------------------------------------------------------------
501int smb_mkdir(iop_file_t *f, const char *dirname, int mode)
502{
503 int r;
504
505 (void)f;
506 (void)mode;
507
508 if (!dirname)
509 return -ENOENT;
510
511 if ((UID == -1) || (TID == -1))
512 return -ENOTCONN;
513
514 char *path = prepare_path(dirname, smb_curpath, SMB_PATH_MAX);
515
516 smb_io_lock();
517
518 r = smb_ManageDirectory(UID, TID, path, SMB_COM_CREATE_DIRECTORY);
519
520 smb_io_unlock();
521
522 return r;
523}
524
525//--------------------------------------------------------------
526int smb_rmdir(iop_file_t *f, const char *dirname)
527{
528 int r;
530
531 (void)f;
532
533 if (!dirname)
534 return -ENOENT;
535
536 if ((UID == -1) || (TID == -1))
537 return -ENOTCONN;
538
539 char *path = prepare_path(dirname, smb_curpath, SMB_PATH_MAX);
540
541 smb_io_lock();
542
543 r = smb_QueryPathInformation(UID, TID, &info, path);
544 if (r < 0) {
545 goto io_unlock;
546 }
547 if (!(info.FileAttributes & EXT_ATTR_DIRECTORY)) {
548 r = -ENOTDIR;
549 goto io_unlock;
550 }
551
552 r = smb_ManageDirectory(UID, TID, path, SMB_COM_DELETE_DIRECTORY);
553
554io_unlock:
555 smb_io_unlock();
556
557 return r;
558}
559
560//--------------------------------------------------------------
561static void FileTimeToDate(u64 FileTime, u8 *datetime)
562{
563 u8 daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
564 int i;
565 u64 time;
566 u16 years, days;
567 u8 leapdays, months, hours, minutes, seconds;
568
569 time = FileTime / 10000000; // convert to seconds from 100-nanosecond intervals
570
571 years = (u16)(time / ((u64)60 * 60 * 24 * 365)); // hurray for interger division
572 time -= years * ((u64)60 * 60 * 24 * 365); // truncate off the years
573
574 leapdays = (years / 4) - (years / 100) + (years / 400);
575 years += 1601; // add base year from FILETIME struct;
576
577 days = (u16)(time / (60 * 60 * 24));
578 time -= (unsigned int)days * (60 * 60 * 24);
579 days -= leapdays;
580
581 if ((years % 4) == 0 && ((years % 100) != 0 || (years % 400) == 0))
582 daysPerMonth[1]++;
583
584 months = 0;
585 for (i = 0; i < 12; i++) {
586 if (days > daysPerMonth[i]) {
587 days -= daysPerMonth[i];
588 months++;
589 } else
590 break;
591 }
592
593 if (months >= 12) {
594 months -= 12;
595 years++;
596 }
597 hours = (u8)(time / (60 * 60));
598 time -= (u16)hours * (60 * 60);
599
600 minutes = (u8)(time / 60);
601 time -= minutes * 60;
602
603 seconds = (u8)(time);
604
605 datetime[0] = 0;
606 datetime[1] = seconds;
607 datetime[2] = minutes;
608 datetime[3] = hours;
609 datetime[4] = days + 1;
610 datetime[5] = months + 1;
611 datetime[6] = (u8)(years & 0xFF);
612 datetime[7] = (u8)((years >> 8) & 0xFF);
613}
614
615static void smb_statFiller(const PathInformation_t *info, iox_stat_t *stat)
616{
617 FileTimeToDate(info->Created, stat->ctime);
618 FileTimeToDate(info->LastAccess, stat->atime);
619 FileTimeToDate(info->Change, stat->mtime);
620
621 stat->size = (int)(info->EndOfFile & 0xffffffff);
622 stat->hisize = (int)((info->EndOfFile >> 32) & 0xffffffff);
623
624 stat->mode = (info->FileAttributes & EXT_ATTR_DIRECTORY) ? FIO_S_IFDIR : FIO_S_IFREG;
625}
626
627//--------------------------------------------------------------
628int smb_dopen(iop_file_t *f, const char *dirname)
629{
630 int r = 0;
632 FHANDLE *fh;
633
634 if (!dirname)
635 return -ENOENT;
636
637 if ((UID == -1) || (TID == -1))
638 return -ENOTCONN;
639
640 char *path = prepare_path(dirname, smb_curpath, SMB_PATH_MAX);
641
642 smb_io_lock();
643
644 // test if the dir exists
645 r = smb_QueryPathInformation(UID, TID, &info, path);
646 if (r < 0) {
647 goto io_unlock;
648 }
649
650 if (!(info.FileAttributes & EXT_ATTR_DIRECTORY)) {
651 r = -ENOTDIR;
652 goto io_unlock;
653 }
654
655 fh = smbman_getfilefreeslot();
656 if (fh) {
657 f->privdata = fh;
658 fh->f = f;
659 fh->mode = O_DIROPEN;
660 fh->filesize = 0;
661 fh->position = 0;
662
663 strncpy(fh->name, path, 255);
664 if (fh->name[strlen(fh->name) - 1] != '\\')
665 strcat(fh->name, "\\");
666 strcat(fh->name, "*");
667
668 r = 0;
669 } else
670 r = -EMFILE;
671
672io_unlock:
673 smb_io_unlock();
674
675 return r;
676}
677
678//--------------------------------------------------------------
679int smb_dclose(iop_file_t *f)
680{
681 return smb_close(f);
682}
683
684//--------------------------------------------------------------
685int smb_dread(iop_file_t *f, iox_dirent_t *dirent)
686{
687 FHANDLE *fh = (FHANDLE *)f->privdata;
688 int r;
689
690 if ((UID == -1) || (TID == -1))
691 return -ENOTCONN;
692
693 smb_io_lock();
694
695 memset((void *)dirent, 0, sizeof(iox_dirent_t));
696
697 SearchInfo_t *info = (SearchInfo_t *)SearchBuf;
698
699 if (fh->smb_fid == -1) {
700 r = smb_FindFirstNext2(UID, TID, fh->name, TRANS2_FIND_FIRST2, info);
701 if (r < 0) {
702 goto io_unlock;
703 }
704 fh->smb_fid = info->SID;
705 r = 1;
706 } else {
707 info->SID = fh->smb_fid;
708 r = smb_FindFirstNext2(UID, TID, NULL, TRANS2_FIND_NEXT2, info);
709 if (r < 0) {
710 goto io_unlock;
711 }
712 r = 1;
713 }
714
715 if (r == 1) {
716 smb_statFiller(&info->fileInfo, &dirent->stat);
717 strncpy(dirent->name, info->FileName, SMB_NAME_MAX);
718 }
719
720io_unlock:
721 smb_io_unlock();
722
723 return r;
724}
725
726//--------------------------------------------------------------
727int smb_getstat(iop_file_t *f, const char *filename, iox_stat_t *stat)
728{
729 int r;
731
732 (void)f;
733
734 if (!filename)
735 return -ENOENT;
736
737 if ((UID == -1) || (TID == -1))
738 return -ENOTCONN;
739
740 char *path = prepare_path(filename, smb_curpath, SMB_PATH_MAX);
741
742 smb_io_lock();
743
744 memset((void *)stat, 0, sizeof(iox_stat_t));
745
746 r = smb_QueryPathInformation(UID, TID, &info, path);
747 if (r < 0) {
748 goto io_unlock;
749 }
750
751 smb_statFiller(&info, stat);
752
753io_unlock:
754 smb_io_unlock();
755
756 return r;
757}
758
759//--------------------------------------------------------------
760int smb_rename(iop_file_t *f, const char *oldname, const char *newname)
761{
762 int r;
763
764 (void)f;
765
766 if ((!oldname) || (!newname))
767 return -ENOENT;
768
769 if ((UID == -1) || (TID == -1))
770 return -ENOTCONN;
771
772 char *oldpath = prepare_path(oldname, smb_curpath, SMB_PATH_MAX);
773 char *newpath = prepare_path(newname, smb_secpath, SMB_PATH_MAX);
774
775 smb_io_lock();
776
777 DPRINTF("smb_rename: oldname=%s newname=%s\n", oldname, newname);
778
779 r = smb_Rename(UID, TID, oldpath, newpath);
780
781 smb_io_unlock();
782
783 return r;
784}
785
786//--------------------------------------------------------------
787int smb_chdir(iop_file_t *f, const char *dirname)
788{
789 int r = 0, i;
791
792 (void)f;
793
794 if (!dirname)
795 return -ENOENT;
796
797 if ((UID == -1) || (TID == -1))
798 return -ENOTCONN;
799
800 char *path = prepare_path(dirname, smb_curpath, SMB_PATH_MAX);
801
802 smb_io_lock();
803
804 if ((path[strlen(path) - 2] == '.') && (path[strlen(path) - 1] == '.')) {
805 char *p = (char *)smb_curdir;
806 for (i = strlen(p) - 1; i >= 0; i--) {
807 if (p[i] == '\\') {
808 p[i] = 0;
809 break;
810 }
811 }
812 } else if (path[strlen(path) - 1] == '.') {
813 smb_curdir[0] = 0;
814 } else {
815 r = smb_QueryPathInformation(UID, TID, &info, path);
816 if (r < 0) {
817 goto io_unlock;
818 }
819
820 if (!(info.FileAttributes & EXT_ATTR_DIRECTORY)) {
821 r = -ENOTDIR;
822 goto io_unlock;
823 }
824
825 strncpy(smb_curdir, path, sizeof(smb_curdir) - 1);
826 }
827
828io_unlock:
829 smb_io_unlock();
830
831 return r;
832}
833
834//--------------------------------------------------------------
835s64 smb_lseek64(iop_file_t *f, s64 pos, int where)
836{
837 s64 r;
838 FHANDLE *fh = (FHANDLE *)f->privdata;
839
840 smb_io_lock();
841
842 switch (where) {
843 case SEEK_CUR:
844 r = fh->position + pos;
845 if (r > fh->filesize) {
846 r = -EINVAL;
847 goto io_unlock;
848 }
849 break;
850 case SEEK_SET:
851 r = pos;
852 if (fh->filesize < pos) {
853 r = -EINVAL;
854 goto io_unlock;
855 }
856 break;
857 case SEEK_END:
858 r = fh->filesize;
859 break;
860 default:
861 r = -EINVAL;
862 goto io_unlock;
863 }
864
865 fh->position = r;
866
867io_unlock:
868 smb_io_unlock();
869
870 return r;
871}
872
873//--------------------------------------------------------------
874void DMA_sendEE(void *buf, int size, void *EE_addr)
875{
876 SifDmaTransfer_t dmat;
877 int oldstate, id;
878
879 dmat.dest = (void *)EE_addr;
880 dmat.size = size;
881 dmat.src = (void *)buf;
882 dmat.attr = 0;
883
884 id = 0;
885 while (!id) {
886 CpuSuspendIntr(&oldstate);
887 id = sceSifSetDma(&dmat, 1);
888 CpuResumeIntr(oldstate);
889 }
890 while (sceSifDmaStat(id) >= 0)
891 ;
892}
893
894//--------------------------------------------------------------
895static void smb_GetPasswordHashes(smbGetPasswordHashes_in_t *in, smbGetPasswordHashes_out_t *out)
896{
897 LM_Password_Hash((const unsigned char *)in->password, (unsigned char *)out->LMhash);
898 NTLM_Password_Hash((const unsigned char *)in->password, (unsigned char *)out->NTLMhash);
899}
900
901//--------------------------------------------------------------
902static int smb_LogOff(void);
903
904static int smb_LogOn(smbLogOn_in_t *logon)
905{
906 u32 capabilities;
907 int r;
908
909 if (UID != -1) {
910 smb_LogOff();
911 }
912
913 r = smb_Connect(logon->serverIP, logon->serverPort);
914 if (r < 0)
915 return -SMB_DEVCTL_LOGON_ERR_CONN;
916
917 r = smb_NegotiateProtocol(&capabilities);
918 if (r < 0)
919 return -SMB_DEVCTL_LOGON_ERR_PROT;
920
921 r = smb_SessionSetupAndX(logon->User, logon->Password, logon->PasswordType, capabilities);
922 if (r < 0)
923 return -SMB_DEVCTL_LOGON_ERR_LOGON;
924
925 UID = r;
926
927 memcpy((void *)&glogon_info, (void *)logon, sizeof(smbLogOn_in_t));
928
929 keepalive_unlock();
930
931 return 0;
932}
933
934//--------------------------------------------------------------
935static int smb_LogOff(void)
936{
937 int r;
938
939 if (UID == -1)
940 return -ENOTCONN;
941
942 if (TID != -1) {
943 smb_closeAll();
944 smb_TreeDisconnect(UID, TID);
945 TID = -1;
946 }
947
948 r = smb_LogOffAndX(UID);
949 if (r < 0)
950 return r;
951
952 UID = -1;
953
954 keepalive_lock();
955
956 smb_Disconnect();
957
958 return 0;
959}
960
961//--------------------------------------------------------------
962static int smb_GetShareList(smbGetShareList_in_t *getsharelist)
963{
964 int i, r, sharecount, shareindex;
965 char tree_str[64];
966 server_specs_t *specs;
967
968 specs = (server_specs_t *)getServerSpecs();
969
970 if (TID != -1) {
971 smb_TreeDisconnect(UID, TID);
972 TID = -1;
973 }
974
975 // Tree Connect on IPC slot
976 sprintf(tree_str, "\\\\%s\\IPC$", specs->ServerIP);
977 r = smb_TreeConnectAndX(UID, tree_str, NULL, 0);
978 if (r < 0)
979 return r;
980
981 TID = r;
982
983 if (UID == -1)
984 return -ENOTCONN;
985
986 // does a 1st enum to count shares (+IPC)
987 r = smb_NetShareEnum(UID, TID, (ShareEntry_t *)&ShareList, 0, 0);
988 if (r < 0)
989 return r;
990
991 sharecount = r;
992 shareindex = 0;
993
994 // now we list the following shares if any
995 for (i = 0; i < sharecount; i++) {
996
997 r = smb_NetShareEnum(UID, TID, (ShareEntry_t *)&ShareList, i, 1);
998 if (r < 0)
999 return r;
1000
1001 // if the entry is not IPC, we send it on EE, and increment shareindex
1002 if ((strcmp(ShareList.ShareName, "IPC$")) && (shareindex < getsharelist->maxent)) {
1003 DMA_sendEE((void *)&ShareList, sizeof(ShareList), (void *)(getsharelist->EE_addr + (shareindex * sizeof(ShareEntry_t))));
1004 shareindex++;
1005 }
1006 }
1007
1008 // disconnect the tree
1009 r = smb_TreeDisconnect(UID, TID);
1010 if (r < 0)
1011 return r;
1012
1013 TID = -1;
1014
1015 // return the number of shares
1016 return shareindex;
1017}
1018
1019//--------------------------------------------------------------
1020static int smb_OpenShare(smbOpenShare_in_t *openshare)
1021{
1022 int r;
1023 char tree_str[274];
1024 server_specs_t *specs;
1025
1026 specs = (server_specs_t *)getServerSpecs();
1027
1028 if (TID != -1) {
1029 smb_TreeDisconnect(UID, TID);
1030 TID = -1;
1031 }
1032
1033 sprintf(tree_str, "\\\\%s\\%s", specs->ServerIP, openshare->ShareName);
1034 r = smb_TreeConnectAndX(UID, tree_str, openshare->Password, openshare->PasswordType);
1035 if (r < 0)
1036 return r;
1037
1038 TID = r;
1039
1040 memcpy((void *)&gopenshare_info, (void *)openshare, sizeof(smbOpenShare_in_t));
1041
1042 return 0;
1043}
1044
1045//--------------------------------------------------------------
1046static int smb_CloseShare(void)
1047{
1048 int r;
1049
1050 if (TID == -1)
1051 return -ENOTCONN;
1052
1053 smb_closeAll();
1054
1055 r = smb_TreeDisconnect(UID, TID);
1056 if (r < 0)
1057 return r;
1058
1059 TID = -1;
1060
1061 return 0;
1062}
1063
1064//--------------------------------------------------------------
1065static int smb_EchoServer(smbEcho_in_t *echo)
1066{
1067 return smb_Echo(echo->echo, echo->len);
1068}
1069
1070//--------------------------------------------------------------
1071static int smb_QueryDiskInfo(smbQueryDiskInfo_out_t *querydiskinfo)
1072{
1073 if ((UID == -1) || (TID == -1))
1074 return -ENOTCONN;
1075
1076 return smb_QueryInformationDisk(UID, TID, querydiskinfo);
1077}
1078
1079//--------------------------------------------------------------
1080int smb_devctl(iop_file_t *f, const char *devname, int cmd, void *arg, unsigned int arglen, void *bufp, unsigned int buflen)
1081{
1082 int r = 0;
1083
1084 (void)f;
1085 (void)devname;
1086 (void)arglen;
1087 (void)buflen;
1088
1089 smb_io_lock();
1090
1091 switch (cmd) {
1092
1093 case SMB_DEVCTL_GETPASSWORDHASHES:
1094 smb_GetPasswordHashes((smbGetPasswordHashes_in_t *)arg, (smbGetPasswordHashes_out_t *)bufp);
1095 r = 0;
1096 break;
1097
1098 case SMB_DEVCTL_LOGON:
1099 r = smb_LogOn((smbLogOn_in_t *)arg);
1100 break;
1101
1102 case SMB_DEVCTL_LOGOFF:
1103 r = smb_LogOff();
1104 break;
1105
1106 case SMB_DEVCTL_GETSHARELIST:
1107 r = smb_GetShareList((smbGetShareList_in_t *)arg);
1108 break;
1109
1110 case SMB_DEVCTL_OPENSHARE:
1111 r = smb_OpenShare((smbOpenShare_in_t *)arg);
1112 break;
1113
1114 case SMB_DEVCTL_CLOSESHARE:
1115 r = smb_CloseShare();
1116 break;
1117
1118 case SMB_DEVCTL_ECHO:
1119 r = smb_EchoServer((smbEcho_in_t *)arg);
1120 break;
1121
1122 case SMB_DEVCTL_QUERYDISKINFO:
1123 r = smb_QueryDiskInfo((smbQueryDiskInfo_out_t *)bufp);
1124 break;
1125
1126 default:
1127 r = -EINVAL;
1128 }
1129
1130 smb_io_unlock();
1131
1132 return r;
1133}
#define ENOENT
Definition errno.h:23
#define EINVAL
Definition errno.h:63
#define EMFILE
Definition errno.h:67
#define EIO
Definition errno.h:29
#define ENOTDIR
Definition errno.h:59
#define EACCES
Definition errno.h:45
#define EBADF
Definition errno.h:37
#define ENOTCONN
Definition errno.h:247
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
void * privdata
Definition ioman.h:61
#define IOP_DT_FSEXT
Definition iomanX.h:66
#define FIO_S_IFDIR
Definition iox_stat.h:45
#define FIO_S_IFREG
Definition iox_stat.h:43
Definition ps2smb.h:80