27IOMANX_RETURN_VALUE_IMPL(EIO);
30static iop_device_ops_t smbman_ops = {
33 IOMANX_RETURN_VALUE(EIO),
39 IOMANX_RETURN_VALUE(EIO),
47 IOMANX_RETURN_VALUE(EIO),
50 IOMANX_RETURN_VALUE(EIO),
51 IOMANX_RETURN_VALUE(EIO),
52 IOMANX_RETURN_VALUE(EIO),
55 IOMANX_RETURN_VALUE(EIO),
56 IOMANX_RETURN_VALUE(EIO),
57 IOMANX_RETURN_VALUE(EIO),
61static iop_device_t smbdev = {
63 IOP_DT_FS | IOP_DT_FSEXT,
69#define SMB_NAME_MAX 256
78 char name[SMB_NAME_MAX];
81#define MAX_FDHANDLES 32
82FHANDLE smbman_fdhandles[MAX_FDHANDLES];
84#define SMB_SEARCH_BUF_MAX 4096
85#define SMB_PATH_MAX 1024
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];
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;
102static smbLogOn_in_t glogon_info;
103static smbOpenShare_in_t gopenshare_info;
105static int smb_LogOn(smbLogOn_in_t *logon);
106static int smb_OpenShare(smbOpenShare_in_t *openshare);
112static unsigned int timer_intr_handler(
void *args)
114 iSignalSema(keepalive_mutex);
115 iSetAlarm(&keepalive_sysclock, timer_intr_handler, NULL);
117 return (
unsigned int)args;
121static void keepalive_deinit(
void)
126 if (keepalive_inited) {
127 CpuSuspendIntr(&oldstate);
128 CancelAlarm(timer_intr_handler, NULL);
129 CpuResumeIntr(oldstate);
130 keepalive_inited = 0;
135static void keepalive_init(
void)
138 if ((!keepalive_inited) && (!keepalive_locked)) {
140 SetAlarm(&keepalive_sysclock, timer_intr_handler, NULL);
141 keepalive_inited = 1;
146static void keepalive_lock(
void)
148 keepalive_locked = 1;
152static void keepalive_unlock(
void)
154 keepalive_locked = 0;
158static void smb_io_lock(
void)
162 WaitSema(smbman_io_sema);
166static void smb_io_unlock(
void)
168 SignalSema(smbman_io_sema);
174static void keepalive_thread(
void *args)
176 int opened_share = 0;
184 WaitSema(keepalive_mutex);
187 WaitSema(smbman_io_sema);
190 r = smb_Echo(
"PS2 KEEPALIVE ECHO", 18);
198 r = smb_LogOn((smbLogOn_in_t *)&glogon_info);
201 smb_OpenShare((smbOpenShare_in_t *)&gopenshare_info);
208 SignalSema(smbman_io_sema);
213int smb_init(iop_device_t *dev)
220 smbman_io_sema = CreateMutex(IOP_MUTEX_UNLOCKED);
223 keepalive_mutex = CreateMutex(IOP_MUTEX_LOCKED);
226 USec2SysClock(3000 * 1000, &keepalive_sysclock);
231 thread.thread = (
void *)keepalive_thread;
232 thread.stacksize = 0x600;
233 thread.priority = 0x64;
235 keepalive_tid = CreateThread(&thread);
236 StartThread(keepalive_tid, NULL);
247 if (AddDrv((iop_device_t *)&smbdev))
250 for (i = 0; i < MAX_FDHANDLES; i++) {
253 fh = (
FHANDLE *)&smbman_fdhandles[i];
265int smb_deinit(iop_device_t *dev)
270 DeleteThread(keepalive_tid);
272 DeleteSema(smbman_io_sema);
274 DeleteSema(keepalive_mutex);
275 keepalive_mutex = -1;
281static FHANDLE *smbman_getfilefreeslot(
void)
285 for (i = 0; i < MAX_FDHANDLES; i++) {
288 fh = (
FHANDLE *)&smbman_fdhandles[i];
297static char *prepare_path(
const char *path,
char *full_path,
int max_path)
303 strncpy(full_path, smb_curdir, max_path - 3);
304 strcat(full_path,
"\\");
308 while ((*p ==
'\\') || (*p ==
'/'))
312 p2 = &path[strlen(path)];
313 while ((*p2 ==
'\\') || (*p2 ==
'/'))
317 for (i = strlen(full_path); (p <= p2) && (max_path - i - 2 > 0); p++, i++) {
318 full_path[i] = (*p ==
'/') ?
'\\' : *p;
323 full_path[i + 1] =
'\0';
329int smb_open(iop_file_t *f,
const char *filename,
int flags,
int mode)
340 if ((UID == -1) || (TID == -1))
343 char *path = prepare_path(filename, smb_curpath, SMB_PATH_MAX);
347 fh = smbman_getfilefreeslot();
349 r = smb_OpenAndX(UID, TID, path, &filesize, flags);
355 fh->filesize = filesize;
357 if (fh->mode & O_TRUNC)
359 else if (fh->mode & O_APPEND)
360 fh->position = filesize;
361 strncpy(fh->name, path, SMB_NAME_MAX);
373int smb_close(iop_file_t *f)
378 if ((UID == -1) || (TID == -1) || (fh->smb_fid == -1))
384 if (fh->mode != O_DIROPEN) {
385 r = smb_Close(UID, TID, fh->smb_fid);
390 memset(fh, 0,
sizeof(
FHANDLE));
402void smb_closeAll(
void)
406 for (i = 0; i < MAX_FDHANDLES; i++) {
409 fh = (
FHANDLE *)&smbman_fdhandles[i];
410 if (fh->smb_fid != -1)
411 smb_Close(UID, TID, fh->smb_fid);
416int smb_lseek(iop_file_t *f,
int pos,
int where)
418 return (
int)smb_lseek64(f, pos, where);
422int smb_read(iop_file_t *f,
void *buf,
int size)
427 if ((UID == -1) || (TID == -1) || (fh->smb_fid == -1))
430 if ((fh->position + size) > fh->filesize)
431 size = fh->filesize - fh->position;
435 r = smb_ReadFile(UID, TID, fh->smb_fid, fh->position, buf, size);
446int smb_write(iop_file_t *f,
void *buf,
int size)
451 if ((UID == -1) || (TID == -1) || (fh->smb_fid == -1))
454 if ((!(fh->mode & O_RDWR)) && (!(fh->mode & O_WRONLY)))
459 r = smb_WriteFile(UID, TID, fh->smb_fid, fh->position, buf, size);
462 if (fh->position > fh->filesize)
463 fh->filesize += fh->position - fh->filesize;
472int smb_remove(iop_file_t *f,
const char *filename)
481 if ((UID == -1) || (TID == -1))
484 char *path = prepare_path(filename, smb_curpath, SMB_PATH_MAX);
488 DPRINTF(
"smb_remove: filename=%s\n", filename);
490 r = smb_Delete(UID, TID, path);
498int smb_mkdir(iop_file_t *f,
const char *dirname,
int mode)
508 if ((UID == -1) || (TID == -1))
511 char *path = prepare_path(dirname, smb_curpath, SMB_PATH_MAX);
515 r = smb_ManageDirectory(UID, TID, path, SMB_COM_CREATE_DIRECTORY);
523int smb_rmdir(iop_file_t *f,
const char *dirname)
533 if ((UID == -1) || (TID == -1))
536 char *path = prepare_path(dirname, smb_curpath, SMB_PATH_MAX);
540 r = smb_QueryPathInformation(UID, TID, &info, path);
544 if (!(info.FileAttributes & EXT_ATTR_DIRECTORY)) {
549 r = smb_ManageDirectory(UID, TID, path, SMB_COM_DELETE_DIRECTORY);
558static void FileTimeToDate(u64 FileTime, u8 *datetime)
560 u8 daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
564 u8 leapdays, months, hours, minutes, seconds;
566 time = FileTime / 10000000;
568 years = (u16)(time / ((u64)60 * 60 * 24 * 365));
569 time -= years * ((u64)60 * 60 * 24 * 365);
571 leapdays = (years / 4) - (years / 100) + (years / 400);
574 days = (u16)(time / (60 * 60 * 24));
575 time -= (
unsigned int)days * (60 * 60 * 24);
578 if ((years % 4) == 0 && ((years % 100) != 0 || (years % 400) == 0))
582 for (i = 0; i < 12; i++) {
583 if (days > daysPerMonth[i]) {
584 days -= daysPerMonth[i];
594 hours = (u8)(time / (60 * 60));
595 time -= (u16)hours * (60 * 60);
597 minutes = (u8)(time / 60);
598 time -= minutes * 60;
600 seconds = (u8)(time);
603 datetime[1] = seconds;
604 datetime[2] = minutes;
606 datetime[4] = days + 1;
607 datetime[5] = months + 1;
608 datetime[6] = (u8)(years & 0xFF);
609 datetime[7] = (u8)((years >> 8) & 0xFF);
614 FileTimeToDate(info->Created, stat->ctime);
615 FileTimeToDate(info->LastAccess, stat->atime);
616 FileTimeToDate(info->Change, stat->mtime);
618 stat->size = (int)(info->EndOfFile & 0xffffffff);
619 stat->hisize = (int)((info->EndOfFile >> 32) & 0xffffffff);
621 stat->mode = (info->FileAttributes & EXT_ATTR_DIRECTORY) ? FIO_S_IFDIR : FIO_S_IFREG;
625int smb_dopen(iop_file_t *f,
const char *dirname)
634 if ((UID == -1) || (TID == -1))
637 char *path = prepare_path(dirname, smb_curpath, SMB_PATH_MAX);
642 r = smb_QueryPathInformation(UID, TID, &info, path);
647 if (!(info.FileAttributes & EXT_ATTR_DIRECTORY)) {
652 fh = smbman_getfilefreeslot();
656 fh->mode = O_DIROPEN;
660 strncpy(fh->name, path, 255);
661 if (fh->name[strlen(fh->name) - 1] !=
'\\')
662 strcat(fh->name,
"\\");
663 strcat(fh->name,
"*");
676int smb_dclose(iop_file_t *f)
682int smb_dread(iop_file_t *f, iox_dirent_t *dirent)
687 if ((UID == -1) || (TID == -1))
692 memset((
void *)dirent, 0,
sizeof(iox_dirent_t));
696 if (fh->smb_fid == -1) {
697 r = smb_FindFirstNext2(UID, TID, fh->name, TRANS2_FIND_FIRST2, info);
701 fh->smb_fid = info->SID;
704 info->SID = fh->smb_fid;
705 r = smb_FindFirstNext2(UID, TID, NULL, TRANS2_FIND_NEXT2, info);
713 smb_statFiller(&info->fileInfo, &dirent->stat);
714 strncpy(dirent->name, info->FileName, SMB_NAME_MAX);
724int smb_getstat(iop_file_t *f,
const char *filename, iox_stat_t *stat)
734 if ((UID == -1) || (TID == -1))
737 char *path = prepare_path(filename, smb_curpath, SMB_PATH_MAX);
741 memset((
void *)stat, 0,
sizeof(iox_stat_t));
743 r = smb_QueryPathInformation(UID, TID, &info, path);
748 smb_statFiller(&info, stat);
757int smb_rename(iop_file_t *f,
const char *oldname,
const char *newname)
763 if ((!oldname) || (!newname))
766 if ((UID == -1) || (TID == -1))
769 char *oldpath = prepare_path(oldname, smb_curpath, SMB_PATH_MAX);
770 char *newpath = prepare_path(newname, smb_secpath, SMB_PATH_MAX);
774 DPRINTF(
"smb_rename: oldname=%s newname=%s\n", oldname, newname);
776 r = smb_Rename(UID, TID, oldpath, newpath);
784int smb_chdir(iop_file_t *f,
const char *dirname)
794 if ((UID == -1) || (TID == -1))
797 char *path = prepare_path(dirname, smb_curpath, SMB_PATH_MAX);
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--) {
809 }
else if (path[strlen(path) - 1] ==
'.') {
812 r = smb_QueryPathInformation(UID, TID, &info, path);
817 if (!(info.FileAttributes & EXT_ATTR_DIRECTORY)) {
822 strncpy(smb_curdir, path,
sizeof(smb_curdir) - 1);
832s64 smb_lseek64(iop_file_t *f, s64 pos,
int where)
841 r = fh->position + pos;
842 if (r > fh->filesize) {
849 if (fh->filesize < pos) {
871void DMA_sendEE(
void *buf,
int size,
void *EE_addr)
873 SifDmaTransfer_t dmat;
876 dmat.dest = (
void *)EE_addr;
878 dmat.src = (
void *)buf;
883 CpuSuspendIntr(&oldstate);
884 id = sceSifSetDma(&dmat, 1);
885 CpuResumeIntr(oldstate);
887 while (sceSifDmaStat(
id) >= 0)
892static void smb_GetPasswordHashes(smbGetPasswordHashes_in_t *in, smbGetPasswordHashes_out_t *out)
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);
899static int smb_LogOff(
void);
901static int smb_LogOn(smbLogOn_in_t *logon)
910 r = smb_Connect(logon->serverIP, logon->serverPort);
912 return -SMB_DEVCTL_LOGON_ERR_CONN;
914 r = smb_NegotiateProtocol(&capabilities);
916 return -SMB_DEVCTL_LOGON_ERR_PROT;
918 r = smb_SessionSetupAndX(logon->User, logon->Password, logon->PasswordType, capabilities);
920 return -SMB_DEVCTL_LOGON_ERR_LOGON;
924 memcpy((
void *)&glogon_info, (
void *)logon,
sizeof(smbLogOn_in_t));
932static int smb_LogOff(
void)
941 smb_TreeDisconnect(UID, TID);
945 r = smb_LogOffAndX(UID);
959static int smb_GetShareList(smbGetShareList_in_t *getsharelist)
961 int i, r, sharecount, shareindex;
968 smb_TreeDisconnect(UID, TID);
973 sprintf(tree_str,
"\\\\%s\\IPC$", specs->ServerIP);
974 r = smb_TreeConnectAndX(UID, tree_str, NULL, 0);
984 r = smb_NetShareEnum(UID, TID, (ShareEntry_t *)&ShareList, 0, 0);
992 for (i = 0; i < sharecount; i++) {
994 r = smb_NetShareEnum(UID, TID, (ShareEntry_t *)&ShareList, i, 1);
999 if ((strcmp(ShareList.ShareName,
"IPC$")) && (shareindex < getsharelist->maxent)) {
1000 DMA_sendEE((
void *)&ShareList,
sizeof(ShareList), (
void *)(getsharelist->EE_addr + (shareindex *
sizeof(ShareEntry_t))));
1006 r = smb_TreeDisconnect(UID, TID);
1017static int smb_OpenShare(smbOpenShare_in_t *openshare)
1026 smb_TreeDisconnect(UID, TID);
1030 sprintf(tree_str,
"\\\\%s\\%s", specs->ServerIP, openshare->ShareName);
1031 r = smb_TreeConnectAndX(UID, tree_str, openshare->Password, openshare->PasswordType);
1037 memcpy((
void *)&gopenshare_info, (
void *)openshare,
sizeof(smbOpenShare_in_t));
1043static int smb_CloseShare(
void)
1052 r = smb_TreeDisconnect(UID, TID);
1062static int smb_EchoServer(smbEcho_in_t *echo)
1064 return smb_Echo(echo->echo, echo->len);
1068static int smb_QueryDiskInfo(smbQueryDiskInfo_out_t *querydiskinfo)
1070 if ((UID == -1) || (TID == -1))
1073 return smb_QueryInformationDisk(UID, TID, querydiskinfo);
1077int smb_devctl(iop_file_t *f,
const char *devname,
int cmd,
void *arg,
unsigned int arglen,
void *bufp,
unsigned int buflen)
1090 case SMB_DEVCTL_GETPASSWORDHASHES:
1091 smb_GetPasswordHashes((smbGetPasswordHashes_in_t *)arg, (smbGetPasswordHashes_out_t *)bufp);
1095 case SMB_DEVCTL_LOGON:
1096 r = smb_LogOn((smbLogOn_in_t *)arg);
1099 case SMB_DEVCTL_LOGOFF:
1103 case SMB_DEVCTL_GETSHARELIST:
1104 r = smb_GetShareList((smbGetShareList_in_t *)arg);
1107 case SMB_DEVCTL_OPENSHARE:
1108 r = smb_OpenShare((smbOpenShare_in_t *)arg);
1111 case SMB_DEVCTL_CLOSESHARE:
1112 r = smb_CloseShare();
1115 case SMB_DEVCTL_ECHO:
1116 r = smb_EchoServer((smbEcho_in_t *)arg);
1119 case SMB_DEVCTL_QUERYDISKINFO:
1120 r = smb_QueryDiskInfo((smbQueryDiskInfo_out_t *)bufp);