* fixed dangerous code (out of bounds memory writing in renderman)
[open-ps2-loader.git] / labs / smblab / smblab.c
blob0dd40a90ced44b47dafecf686e2af9bf5cfa67d8
2 #include <tamtypes.h>
3 #include <kernel.h>
4 #include <sifrpc.h>
5 #include <loadfile.h>
6 #include <fileio.h>
7 #include <fileXio_rpc.h>
8 #include <malloc.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <sbv_patches.h>
12 #include <iopcontrol.h>
13 #include <iopheap.h>
14 #include <debug.h>
15 #include <sys/time.h>
16 #include <time.h>
17 #include <ps2smb.h>
19 #define DPRINTF(args...) printf(args); scr_printf(args);
21 #define IP_ADDR "192.168.0.10"
22 #define NETMASK "255.255.255.0"
23 #define GATEWAY "192.168.0.1"
25 extern void poweroff_irx;
26 extern int size_poweroff_irx;
27 extern void ps2dev9_irx;
28 extern int size_ps2dev9_irx;
29 extern void smsutils_irx;
30 extern int size_smsutils_irx;
31 extern void smstcpip_irx;
32 extern int size_smstcpip_irx;
33 extern void smsmap_irx;
34 extern int size_smsmap_irx;
35 extern void smbman_irx;
36 extern int size_smbman_irx;
37 extern void udptty_irx;
38 extern int size_udptty_irx;
39 extern void ioptrap_irx;
40 extern int size_ioptrap_irx;
41 extern void ps2link_irx;
42 extern int size_ps2link_irx;
43 extern void iomanx_irx;
44 extern int size_iomanx_irx;
45 extern void filexio_irx;
46 extern int size_filexio_irx;
48 // for IP config
49 #define IPCONFIG_MAX_LEN 64
50 static char g_ipconfig[IPCONFIG_MAX_LEN] __attribute__((aligned(64)));
51 static int g_ipconfig_len;
53 static ShareEntry_t sharelist[128] __attribute__((aligned(64))); // Keep this aligned for DMA!
55 typedef struct {
56 u8 unused;
57 u8 sec;
58 u8 min;
59 u8 hour;
60 u8 day;
61 u8 month;
62 u16 year;
63 } ps2time_t;
65 #define isYearLeap(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
67 //--------------------------------------------------------------
68 // I wanted this to be done on IOP, but unfortunately, the compiler
69 // can't handle div ops on 64 bit numbers.
71 static ps2time_t *smbtime2ps2time(s64 smbtime, ps2time_t *ps2time)
73 const int mdtab[2][12] = {
74 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
75 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } // leap year
77 register u32 dayclock, dayno;
78 s64 UnixSystemTime;
79 register int year = 1970; // year of the Epoch
81 memset((void *)ps2time, 0, sizeof(ps2time_t));
83 // we add 5x10^6 to the number before scaling it to seconds and subtracting
84 // the constant (seconds between 01/01/1601 and the Epoch: 01/01/1970),
85 // so that we round in the same way windows does.
86 UnixSystemTime = (s64)(((smbtime + 5000000) / 10000000) - 11644473600);
88 dayclock = UnixSystemTime % 86400;
89 dayno = UnixSystemTime / 86400;
91 ps2time->sec = dayclock % 60;
92 ps2time->min = (dayclock % 3600) / 60;
93 ps2time->hour = dayclock / 3600;
94 while (dayno >= (isYearLeap(year) ? 366 : 365)) {
95 dayno -= (isYearLeap(year) ? 366 : 365);
96 year++;
98 ps2time->year = year;
99 ps2time->month = 0;
100 while (dayno >= mdtab[isYearLeap(year)][ps2time->month]) {
101 dayno -= mdtab[isYearLeap(year)][ps2time->month];
102 ps2time->month++;
104 ps2time->day = dayno + 1;
105 ps2time->month++;
107 return (ps2time_t *)ps2time;
110 //--------------------------------------------------------------
111 void set_ipconfig(void)
113 memset(g_ipconfig, 0, IPCONFIG_MAX_LEN);
114 g_ipconfig_len = 0;
116 strncpy(&g_ipconfig[g_ipconfig_len], IP_ADDR, 15);
117 g_ipconfig_len += strlen(IP_ADDR) + 1;
118 strncpy(&g_ipconfig[g_ipconfig_len], NETMASK, 15);
119 g_ipconfig_len += strlen(NETMASK) + 1;
120 strncpy(&g_ipconfig[g_ipconfig_len], GATEWAY, 15);
121 g_ipconfig_len += strlen(GATEWAY) + 1;
124 //--------------------------------------------------------------
125 int main(int argc, char *argv[2])
127 int i, ret, id;
129 init_scr();
130 scr_clear();
131 DPRINTF("smblab\n");
133 SifInitRpc(0);
135 DPRINTF("IOP Reset... ");
137 while(!SifIopReset("rom0:UDNL rom0:EELOADCNF",0));
138 while(!SifIopSync());;
139 fioExit();
140 SifExitIopHeap();
141 SifLoadFileExit();
142 SifExitRpc();
143 SifExitCmd();
145 SifInitRpc(0);
146 FlushCache(0);
147 FlushCache(2);
149 SifLoadFileInit();
150 SifInitIopHeap();
152 sbv_patch_enable_lmb();
153 sbv_patch_disable_prefix_check();
155 SifLoadModule("rom0:SIO2MAN", 0, 0);
156 SifLoadModule("rom0:MCMAN", 0, 0);
157 SifLoadModule("rom0:MCSERV", 0, 0);
159 DPRINTF("OK\n");
161 set_ipconfig();
163 DPRINTF("loading iomanX... ");
164 id = SifExecModuleBuffer(&iomanx_irx, size_iomanx_irx, 0, NULL, &ret);
165 DPRINTF("ret=%d\n", ret);
167 DPRINTF("loading fileXio... ");
168 id = SifExecModuleBuffer(&filexio_irx, size_filexio_irx, 0, NULL, &ret);
169 DPRINTF("ret=%d\n", ret);
171 DPRINTF("loading poweroff... ");
172 id = SifExecModuleBuffer(&poweroff_irx, size_poweroff_irx, 0, NULL, &ret);
173 DPRINTF("ret=%d\n", ret);
175 DPRINTF("loading ps2dev9... ");
176 id = SifExecModuleBuffer(&ps2dev9_irx, size_ps2dev9_irx, 0, NULL, &ret);
177 DPRINTF("ret=%d\n", ret);
179 DPRINTF("loading smsutils... ");
180 id = SifExecModuleBuffer(&smsutils_irx, size_smsutils_irx, 0, NULL, &ret);
181 DPRINTF("ret=%d\n", ret);
183 DPRINTF("loading smstcpip... ");
184 id = SifExecModuleBuffer(&smstcpip_irx, size_smstcpip_irx, 0, NULL, &ret);
185 DPRINTF("ret=%d\n", ret);
187 DPRINTF("loading smsmap... ");
188 id = SifExecModuleBuffer(&smsmap_irx, size_smsmap_irx, g_ipconfig_len, g_ipconfig, &ret);
189 DPRINTF("ret=%d\n", ret);
191 DPRINTF("loading udptty... ");
192 id = SifExecModuleBuffer(&udptty_irx, size_udptty_irx, 0, NULL, &ret);
193 DPRINTF("ret=%d\n", ret);
195 DPRINTF("loading ioptrap... ");
196 id = SifExecModuleBuffer(&ioptrap_irx, size_ioptrap_irx, 0, NULL, &ret);
197 DPRINTF("ret=%d\n", ret);
199 DPRINTF("loading ps2link... ");
200 id = SifExecModuleBuffer(&ps2link_irx, size_ps2link_irx, 0, NULL, &ret);
201 DPRINTF("ret=%d\n", ret);
203 DPRINTF("loading smbman... ");
204 id = SifExecModuleBuffer(&smbman_irx, size_smbman_irx, 0, NULL, &ret);
205 DPRINTF("ret=%d\n", ret);
207 DPRINTF("modules load OK\n");
209 fileXioInit();
212 // ----------------------------------------------------------------
213 // how to get password hashes:
214 // ----------------------------------------------------------------
216 smbGetPasswordHashes_in_t passwd;
217 smbGetPasswordHashes_out_t passwdhashes;
219 strcpy(passwd.password, "mypassw");
221 DPRINTF("GETPASSWORDHASHES... ");
222 ret = fileXioDevctl("smb:", SMB_DEVCTL_GETPASSWORDHASHES, (void *)&passwd, sizeof(passwd), (void *)&passwdhashes, sizeof(passwdhashes));
223 if (ret == 0) {
224 DPRINTF("OK\n");
225 DPRINTF("LMhash = 0x");
226 for (i=0; i<16; i++)
227 DPRINTF("%02X", passwdhashes.LMhash[i]);
228 DPRINTF("\n");
229 DPRINTF("NTLMhash = 0x");
230 for (i=0; i<16; i++)
231 DPRINTF("%02X", passwdhashes.NTLMhash[i]);
232 DPRINTF("\n");
234 else
235 DPRINTF("Error %d\n", ret);
237 // we now have 32 bytes of hash (16 bytes LM hash + 16 bytes NTLM hash)
238 // ----------------------------------------------------------------
241 // ----------------------------------------------------------------
242 // how to LOGON to SMB server:
243 // ----------------------------------------------------------------
245 smbLogOn_in_t logon;
247 strcpy(logon.serverIP, "192.168.0.2");
248 logon.serverPort = 445;
249 strcpy(logon.User, "GUEST");
250 //strcpy(logon.User, "jimmikaelkael");
251 // we could reuse the generated hash
252 //memcpy((void *)logon.Password, (void *)&passwdhashes, sizeof(passwdhashes));
253 //logon.PasswordType = HASHED_PASSWORD;
254 // or log sending the plaintext password
255 //strcpy(logon.Password, "mypassw");
256 //logon.PasswordType = PLAINTEXT_PASSWORD;
257 // or simply tell we're not sending password
258 //logon.PasswordType = NO_PASSWORD;
260 DPRINTF("LOGON... ");
261 ret = fileXioDevctl("smb:", SMB_DEVCTL_LOGON, (void *)&logon, sizeof(logon), NULL, 0);
262 if (ret == 0) {
263 DPRINTF("OK ");
265 else {
266 DPRINTF("Error %d ", ret);
270 // ----------------------------------------------------------------
271 // how to send an Echo to SMB server to test if it's alive:
272 // ----------------------------------------------------------------
273 smbEcho_in_t echo;
275 strcpy(echo.echo, "ALIVE ECHO TEST");
276 echo.len = strlen("ALIVE ECHO TEST");
278 DPRINTF(" ECHO... ");
279 ret = fileXioDevctl("smb:", SMB_DEVCTL_ECHO, (void *)&echo, sizeof(echo), NULL, 0);
280 if (ret == 0) {
281 DPRINTF("OK\n");
283 else {
284 DPRINTF("Error %d\n", ret);
288 // ----------------------------------------------------------------
289 // how to get the available share list:
290 // ----------------------------------------------------------------
292 smbGetShareList_in_t getsharelist;
294 getsharelist.EE_addr = (void *)&sharelist[0];
295 getsharelist.maxent = 128;
297 DPRINTF("GETSHARELIST... ");
298 ret = fileXioDevctl("smb:", SMB_DEVCTL_GETSHARELIST, (void *)&getsharelist, sizeof(getsharelist), NULL, 0);
299 if (ret >= 0) {
300 DPRINTF("OK count = %d\n", ret);
301 for (i=0; i<ret; i++) {
302 DPRINTF("\t\t - %s: %s\n", sharelist[i].ShareName, sharelist[i].ShareComment);
305 else {
306 DPRINTF("Error %d\n", ret);
310 // ----------------------------------------------------------------
311 // how to open a share:
312 // ----------------------------------------------------------------
314 smbOpenShare_in_t openshare;
316 strcpy(openshare.ShareName, "PS2SMB");
317 // we could reuse the generated hash
318 //memcpy((void *)logon.Password, (void *)&passwdhashes, sizeof(passwdhashes));
319 //logon.PasswordType = HASHED_PASSWORD;
320 // or log sending the plaintext password
321 //strcpy(logon.Password, "mypassw");
322 //logon.PasswordType = PLAINTEXT_PASSWORD;
323 // or simply tell we're not sending password
324 //logon.PasswordType = NO_PASSWORD;
326 DPRINTF("OPENSHARE... ");
327 ret = fileXioDevctl("smb:", SMB_DEVCTL_OPENSHARE, (void *)&openshare, sizeof(openshare), NULL, 0);
328 if (ret == 0) {
329 DPRINTF("OK\n");
331 else {
332 DPRINTF("Error %d\n", ret);
336 // ----------------------------------------------------------------
337 // how to query disk informations: (you must be connected to a share)
338 // ----------------------------------------------------------------
339 smbQueryDiskInfo_out_t querydiskinfo;
341 DPRINTF("QUERYDISKINFO... ");
342 ret = fileXioDevctl("smb:", SMB_DEVCTL_QUERYDISKINFO, NULL, 0, (void *)&querydiskinfo, sizeof(querydiskinfo));
343 if (ret == 0) {
344 DPRINTF("OK\n");
345 DPRINTF("Total Units = %d, BlocksPerUnit = %d\n", querydiskinfo.TotalUnits, querydiskinfo.BlocksPerUnit);
346 DPRINTF("BlockSize = %d, FreeUnits = %d\n", querydiskinfo.BlockSize, querydiskinfo.FreeUnits);
348 else {
349 DPRINTF("Error %d\n", ret);
353 // ----------------------------------------------------------------
354 // getstat test:
355 // ----------------------------------------------------------------
357 DPRINTF("IO getstat... ");
359 iox_stat_t stats;
360 ret = fileXioGetStat("smb:\\", &stats);
361 if (ret == 0) {
362 DPRINTF("OK\n");
364 s64 smb_ctime, smb_atime, smb_mtime;
365 ps2time_t ctime, atime, mtime;
367 memcpy((void *)&smb_ctime, stats.ctime, 8);
368 memcpy((void *)&smb_atime, stats.atime, 8);
369 memcpy((void *)&smb_mtime, stats.mtime, 8);
371 smbtime2ps2time(smb_ctime, (ps2time_t *)&ctime);
372 smbtime2ps2time(smb_atime, (ps2time_t *)&atime);
373 smbtime2ps2time(smb_mtime, (ps2time_t *)&mtime);
375 s64 hisize = stats.hisize;
376 hisize = hisize << 32;
377 s64 size = hisize | stats.size;
379 DPRINTF("size = %ld, mode = %04x\n", size, stats.mode);
381 DPRINTF("ctime = %04d.%02d.%02d %02d:%02d:%02d.%02d\n",
382 ctime.year, ctime.month, ctime.day,
383 ctime.hour, ctime.min, ctime.sec, ctime.unused);
384 DPRINTF("atime = %04d.%02d.%02d %02d:%02d:%02d.%02d\n",
385 atime.year, atime.month, atime.day,
386 atime.hour, atime.min, atime.sec, atime.unused);
387 DPRINTF("mtime = %04d.%02d.%02d %02d:%02d:%02d.%02d\n",
388 mtime.year, mtime.month, mtime.day,
389 mtime.hour, mtime.min, mtime.sec, mtime.unused);
391 else {
392 DPRINTF("Error %d\n", ret);
396 // ----------------------------------------------------------------
397 // create directory test:
398 // ----------------------------------------------------------------
399 DPRINTF("IO mkdir... ");
400 ret = mkdir("smb:\\created");
401 if (ret == 0) {
402 DPRINTF("OK\n");
404 else {
405 DPRINTF("Error %d\n", ret);
409 // ----------------------------------------------------------------
410 // rename file test:
411 // ----------------------------------------------------------------
413 DPRINTF("IO rename... ");
414 ret = fileXioRename("smb:\\rename_me\\rename_me.txt", "smb:\\rename_me\\renamed.txt");
415 if (ret == 0) {
416 DPRINTF("OK\n");
418 else {
419 DPRINTF("Error %d\n", ret);
424 // ----------------------------------------------------------------
425 // rename directory test:
426 // ----------------------------------------------------------------
427 DPRINTF("IO rename... ");
428 ret = fileXioRename("smb:\\created", "smb:\\renamed");
429 if (ret == 0) {
430 DPRINTF("OK\n");
432 else {
433 DPRINTF("Error %d\n", ret);
437 // ----------------------------------------------------------------
438 // delete file test:
439 // ----------------------------------------------------------------
441 DPRINTF("IO remove... ");
442 ret = remove("smb:\\delete_me\\delete_me.txt");
443 if (ret == 0) {
444 DPRINTF("OK\n");
446 else {
447 DPRINTF("Error %d\n", ret);
452 // ----------------------------------------------------------------
453 // delete directory test:
454 // ----------------------------------------------------------------
455 DPRINTF("IO rmdir... ");
456 ret = rmdir("smb:\\renamed");
457 if (ret == 0) {
458 DPRINTF("OK\n");
460 else {
461 DPRINTF("Error %d\n", ret);
465 // ----------------------------------------------------------------
466 // open file test:
467 // ----------------------------------------------------------------
469 int fd = fileXioOpen("smb:\\BFTP.iso", O_RDONLY, 0666);
470 if (fd >= 0) {
471 // 64bit filesize test
472 s64 filesize = fileXioLseek64(fd, 0, SEEK_END);
473 u8 *p = (u8 *)&filesize;
474 DPRINTF("filesize = ");
475 for (i=0; i<8; i++) {
476 DPRINTF("%02X ", p[i]);
478 DPRINTF("\n");
480 // 64bit offset read test
481 fileXioLseek64(fd, filesize - 2041, SEEK_SET);
482 u8 buf[16];
483 fileXioRead(fd, buf, 16);
484 p = (u8 *)buf;
485 DPRINTF("read = ");
486 for (i=0; i<16; i++) {
487 DPRINTF("%02X", p[i]);
489 DPRINTF("\n");
491 // 64bit write test
492 //fileXioLseek64(fd, filesize - 16, SEEK_SET);
493 //fileXioWrite(fd, "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC", 16);
494 //fileXioLseek64(fd, filesize - 16, SEEK_SET);
495 //fileXioRead(fd, buf, 16);
496 //p = (u8 *)buf;
497 //DPRINTF("read = ");
498 //for (i=0; i<16; i++) {
499 // DPRINTF("%02X", p[i]);
501 //DPRINTF("\n");
503 fileXioClose(fd);
507 // ----------------------------------------------------------------
508 // create file test:
509 // ----------------------------------------------------------------
511 fd = open("smb:\\testfile", O_RDWR | O_CREAT | O_TRUNC);
512 if (fd >= 0) {
513 write(fd, "test", 4);
514 close(fd);
517 //while(1);
520 // ----------------------------------------------------------------
521 // chdir test
522 // ----------------------------------------------------------------
524 DPRINTF("IO chdir... ");
525 ret = fileXioChdir("smb:\\dossier");
526 if (ret == 0) {
527 DPRINTF("OK\n");
529 else {
530 DPRINTF("Error %d\n", ret);
534 // ----------------------------------------------------------------
535 // dopen/dread/dclose test
536 // ----------------------------------------------------------------
538 iox_dirent_t dirent;
540 DPRINTF("IO dopen... ");
541 fd = fileXioDopen("smb:\\");
542 if (fd >= 0) {
543 DPRINTF("OK\n\t ");
544 ret = 1;
545 while (ret == 1) {
546 ret = fileXioDread(fd, &dirent);
547 if (ret == 1)
548 DPRINTF("%s ", dirent.name);
550 fileXioDclose(fd);
551 DPRINTF("\n");
553 else {
554 DPRINTF("Error %d\n", ret);
558 // ----------------------------------------------------------------
559 // chdir test
560 // ----------------------------------------------------------------
562 DPRINTF("IO chdir... ");
563 ret = fileXioChdir("smb:\\dossier2");
564 if (ret == 0) {
565 DPRINTF("OK\n");
567 else {
568 DPRINTF("Error %d\n", ret);
572 // ----------------------------------------------------------------
573 // dopen/dread/dclose test
574 // ----------------------------------------------------------------
576 DPRINTF("IO dopen... ");
577 fd = fileXioDopen("smb:\\");
578 if (fd >= 0) {
579 DPRINTF("OK\n\t ");
580 ret = 1;
581 while (ret == 1) {
582 ret = fileXioDread(fd, &dirent);
583 if (ret == 1)
584 DPRINTF("%s ", dirent.name);
586 fileXioDclose(fd);
587 DPRINTF("\n");
589 else {
590 DPRINTF("Error %d\n", ret);
594 // ----------------------------------------------------------------
595 // chdir test
596 // ----------------------------------------------------------------
598 DPRINTF("IO chdir... ");
599 ret = fileXioChdir("smb:\\..");
600 if (ret == 0) {
601 DPRINTF("OK\n");
603 else {
604 DPRINTF("Error %d\n", ret);
608 // ----------------------------------------------------------------
609 // dopen/dread/dclose test
610 // ----------------------------------------------------------------
612 DPRINTF("IO dopen... ");
613 fd = fileXioDopen("smb:\\");
614 if (fd >= 0) {
615 DPRINTF("OK\n\t ");
616 ret = 1;
617 while (ret == 1) {
618 ret = fileXioDread(fd, &dirent);
619 if (ret == 1)
620 DPRINTF("%s ", dirent.name);
622 fileXioDclose(fd);
623 DPRINTF("\n");
625 else {
626 DPRINTF("Error %d\n", ret);
630 // ----------------------------------------------------------------
631 // how to close a share:
632 // ----------------------------------------------------------------
634 DPRINTF("CLOSESHARE... ");
635 ret = fileXioDevctl("smb:", SMB_DEVCTL_CLOSESHARE, NULL, 0, NULL, 0);
636 if (ret == 0) {
637 DPRINTF("OK\n");
639 else {
640 DPRINTF("Error %d\n", ret);
644 // ----------------------------------------------------------------
645 // how to LOGOFF from SMB server:
646 // ----------------------------------------------------------------
648 DPRINTF("LOGOFF... ");
649 ret = fileXioDevctl("smb:", SMB_DEVCTL_LOGOFF, NULL, 0, NULL, 0);
650 if (ret == 0) {
651 DPRINTF("OK\n");
653 else {
654 DPRINTF("Error %d\n", ret);
658 SleepThread();
659 return 0;