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