A 32bit* process injecting a 64bit dll in to a 64bit process is possible. Injecting a 32bit dll in to a 64bit process should also be possible from my limited tests.
But it would be more of a cool proof of concept than anything else imo because you have to be very careful with what you do in your dll unless you want to bring the target process down in a flaming ball of crashing fire
*) Technically all processes are 64bit.. Some just also run 32bit code.
As for return values.. Like Cypher said it should be easy to find out most of them but I guess some could be confusing if you don't know assembly, and I'm bored atm so I typed them out for you. This is for managed dlls btw, native ones have different error codes. (Which now that I think back is kind of stupid)
Local code:
1 : process handle is null
2 : memory allocation failure
3 : loadlibrary("mscoree.dll") (local process)
4-14 : WriteProcessMemory
15 : CreateRemoteThread(loadlibrary)
16 : loadlibray("mscoree.dll") (remote process)
17 : WriteProcessMemory
18 : CreateRemoteThread(assembler code)
Remote code:
19 : CLRCreateInstance()
20 : MetaHost->GetRuntime()
21 : RuntimeInfo->IsStarted() // typo in the comment
22 : RuntimeInfo->GetInterface() // typo in the comment
23 : RuntimeHost->Start()
24 : RuntimeHost->ExecuteInDefaultAppDomain()
Success code is whatever you return from your managed func, so I recommend not using 1-24.
Sometimes you get random return codes but I haven't debugged why, and I think it only happens with native dlls.